增加换肤功能
This commit is contained in:
200
TUIKit/TUICallKit/TUICallKit-Swift/View/WindowManager.swift
Normal file
200
TUIKit/TUICallKit/TUICallKit-Swift/View/WindowManager.swift
Normal file
@@ -0,0 +1,200 @@
|
||||
//
|
||||
// WindowManger.swift
|
||||
// TUICallKit
|
||||
//
|
||||
// Created by vincepzhang on 2023/2/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class WindowManager: NSObject, FloatingWindowViewDelegate {
|
||||
|
||||
static let instance = WindowManager()
|
||||
|
||||
var isFloating = false
|
||||
var floatWindowBeganPoint: CGPoint = .zero
|
||||
|
||||
let mediaTypeObserver = Observer()
|
||||
|
||||
let callWindow: UIWindow = {
|
||||
let callWindow = UIWindow()
|
||||
callWindow.windowLevel = .alert - 1
|
||||
return callWindow
|
||||
}()
|
||||
|
||||
let floatWindow: UIWindow = {
|
||||
let floatWindow = UIWindow()
|
||||
floatWindow.windowLevel = .alert - 1
|
||||
floatWindow.layer.masksToBounds = true
|
||||
return floatWindow
|
||||
}()
|
||||
|
||||
var callKitViewController: CallKitViewController?
|
||||
|
||||
func getCallKitViewController() -> CallKitViewController {
|
||||
if let callKitViewController = callKitViewController {
|
||||
return callKitViewController
|
||||
} else {
|
||||
let newCallKitViewController = CallKitViewController()
|
||||
callKitViewController = newCallKitViewController
|
||||
return newCallKitViewController
|
||||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
registerObserveState()
|
||||
}
|
||||
|
||||
deinit {
|
||||
TUICallState.instance.mediaType.removeObserver(mediaTypeObserver)
|
||||
}
|
||||
|
||||
func showCallWindow(_ isIncomingCall: Bool = true) {
|
||||
if isIncomingCall && TUICallState.instance.selfUser.value.callRole.value == .called {
|
||||
showIncomingFloatView()
|
||||
} else {
|
||||
showCallView()
|
||||
}
|
||||
}
|
||||
|
||||
func closeCallWindow() {
|
||||
callKitViewController = nil
|
||||
callWindow.rootViewController = nil
|
||||
callWindow.isHidden = true
|
||||
}
|
||||
|
||||
func showIncomingFloatView() {
|
||||
let viewController = UIViewController()
|
||||
viewController.view.addSubview(IncomingFloatView(frame: CGRect.zero))
|
||||
callWindow.rootViewController = viewController
|
||||
callWindow.isHidden = false
|
||||
callWindow.backgroundColor = UIColor.clear
|
||||
callWindow.frame = CGRect(x: 8.scaleWidth(),
|
||||
y: StatusBar_Height + 10,
|
||||
width: Screen_Width - 16.scaleWidth(),
|
||||
height: 92.scaleWidth())
|
||||
callWindow.t_makeKeyAndVisible()
|
||||
}
|
||||
|
||||
func showCallView() {
|
||||
closeFloatWindow()
|
||||
callWindow.rootViewController = CallKitNavigationController(rootViewController: getCallKitViewController())
|
||||
callWindow.isHidden = false
|
||||
callWindow.frame = CGRect(x: 0, y: 0, width: Screen_Width, height: Screen_Height)
|
||||
callWindow.t_makeKeyAndVisible()
|
||||
}
|
||||
|
||||
func showFloatWindow() {
|
||||
closeCallWindow()
|
||||
let floatViewController = FloatWindowViewController()
|
||||
floatViewController.delegate = self
|
||||
floatWindow.rootViewController = floatViewController
|
||||
floatWindow.backgroundColor = UIColor.clear
|
||||
floatWindow.isHidden = false
|
||||
floatWindow.frame = getFloatWindowFrame()
|
||||
updateFloatWindowFrame()
|
||||
floatWindow.t_makeKeyAndVisible()
|
||||
isFloating = true
|
||||
}
|
||||
|
||||
func closeFloatWindow() {
|
||||
floatWindow.rootViewController = nil
|
||||
floatWindow.isHidden = true
|
||||
isFloating = false
|
||||
}
|
||||
|
||||
func getFloatWindowFrame() -> CGRect {
|
||||
if TUICallState.instance.scene.value == .group {
|
||||
return kMicroGroupViewRect
|
||||
}
|
||||
|
||||
if TUICallState.instance.mediaType.value == .audio {
|
||||
return kMicroAudioViewRect
|
||||
} else {
|
||||
return kMicroVideoViewRect
|
||||
}
|
||||
}
|
||||
|
||||
func updateFloatWindowFrame() {
|
||||
let originY = floatWindow.frame.origin.y
|
||||
|
||||
if TUICallState.instance.scene.value == .group {
|
||||
let dstX = floatWindow.frame.origin.x < (Screen_Width / 2.0) ? 0 : (Screen_Width - kMicroGroupViewWidth)
|
||||
floatWindow.frame = CGRect(x: dstX, y: originY, width: kMicroGroupViewWidth, height: kMicroGroupViewHeight)
|
||||
return
|
||||
}
|
||||
|
||||
if TUICallState.instance.mediaType.value == .audio {
|
||||
let dstX = floatWindow.frame.origin.x < (Screen_Width / 2.0) ? 0 : (Screen_Width - kMicroAudioViewWidth)
|
||||
floatWindow.frame = CGRect(x: dstX, y: originY, width: kMicroAudioViewWidth, height: kMicroAudioViewHeight)
|
||||
} else {
|
||||
let dstX = floatWindow.frame.origin.x < (Screen_Width / 2.0) ? 0 : (Screen_Width - kMicroVideoViewWidth)
|
||||
floatWindow.frame = CGRect(x: dstX, y: originY, width: kMicroVideoViewWidth, height: kMicroVideoViewHeight)
|
||||
}
|
||||
}
|
||||
|
||||
func registerObserveState() {
|
||||
TUICallState.instance.mediaType.addObserver(mediaTypeObserver, closure: { [weak self] newValue, _ in
|
||||
guard let self = self else { return }
|
||||
if self.isFloating {
|
||||
self.updateFloatWindowFrame()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// MARK: FloatingWindowViewDelegate
|
||||
func tapGestureAction(tapGesture: UITapGestureRecognizer) {
|
||||
showCallWindow(false)
|
||||
}
|
||||
|
||||
func panGestureAction(panGesture: UIPanGestureRecognizer) {
|
||||
switch panGesture.state {
|
||||
case .began:
|
||||
floatWindowBeganPoint = floatWindow.frame.origin
|
||||
break
|
||||
case.changed:
|
||||
let point = panGesture.translation(in: floatWindow)
|
||||
var dstX = floatWindowBeganPoint.x + point.x
|
||||
var dstY = floatWindowBeganPoint.y + point.y
|
||||
|
||||
if dstX < 0 {
|
||||
dstX = 0
|
||||
} else if dstX > (Screen_Width - floatWindow.frame.size.width) {
|
||||
dstX = Screen_Width - floatWindow.frame.size.width
|
||||
}
|
||||
|
||||
if dstY < 0 {
|
||||
dstY = 0
|
||||
} else if dstY > (Screen_Height - floatWindow.frame.size.height) {
|
||||
dstY = Screen_Height - floatWindow.frame.size.height
|
||||
|
||||
}
|
||||
|
||||
floatWindow.frame = CGRect(x: dstX,
|
||||
y: dstY,
|
||||
width: floatWindow.frame.size.width,
|
||||
height: floatWindow.frame.size.height)
|
||||
break
|
||||
case.cancelled:
|
||||
break
|
||||
case.ended:
|
||||
var dstX: CGFloat = 0
|
||||
let currentCenterX: CGFloat = floatWindow.frame.origin.x + floatWindow.frame.size.width / 2.0
|
||||
|
||||
if currentCenterX < Screen_Width / 2 {
|
||||
dstX = CGFloat(0)
|
||||
} else if currentCenterX > Screen_Width / 2 {
|
||||
dstX = CGFloat(Screen_Width - floatWindow.frame.size.width)
|
||||
}
|
||||
|
||||
floatWindow.frame = CGRect(x: dstX,
|
||||
y: floatWindow.frame.origin.y,
|
||||
width: floatWindow.frame.size.width,
|
||||
height: floatWindow.frame.size.height)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user