Swift微信语音通话最小化 Swift仿微信语音通话最小化时后的效果实例代码
醉梦弦音 人气:0想了解Swift仿微信语音通话最小化时后的效果实例代码的相关内容吗,醉梦弦音在本文为您仔细讲解Swift微信语音通话最小化的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:swift,微信语音通话最小化,下面大家一起来学习吧。
前言
最近碰到个需求,需要仿微信语音通话缩小化后,保持界面最上层有一个悬浮的小View可以一点击就把刚刚缩放掉的界面再放回来,其实本质就是创造了一个新的Window,在这个window上创建了一个rootController并展示他,缩小化时是把controller dismiss掉了,再次点击那个小View之后把这个controller再展示出来便可以了。同理微信小程序其实也是在一个新的Window中做了一套新的逻辑。随着现在手机性能的提升,多Window同时存在并不会造成严重卡顿,而衍生出来的一种新的开发方式。
实例代码
上代码,这个是根据网上找到的类似效果进行了部分修改的,作者叫冯琦帆
SuspendTool
import Foundation import UIKit enum SuspendType { case none case single case multi } class SuspendTool: NSObject { static let sharedInstance = SuspendTool() private var suspendWindows: [SuspendWindow] = [] // var semicircle: Semicircle? var origin: CGPoint = CGPoint.init(x: 10, y: 300) static func showSuspendWindow(rootViewController: UIViewController, coverImageName: String) { let tool = SuspendTool.sharedInstance let window = SuspendWindow.init(rootViewController: rootViewController, coverImageName: coverImageName, frame: CGRect.init(origin: tool.origin, size: CGSize.init(width: radious, height: radious))) window.show() tool.suspendWindows.append(window) } static func replaceSuspendWindow(rootViewController: UIViewController, coverImageName: String) { let tool = SuspendTool.sharedInstance tool.suspendWindows.removeAll() let window = SuspendWindow.init(rootViewController: rootViewController, coverImageName: coverImageName, frame: CGRect.init(origin: tool.origin, size: CGSize.init(width: radious, height: radious))) window.show() tool.suspendWindows.append(window) } static func remove(suspendWindow: SuspendWindow) { UIView.animate(withDuration: 0.25, animations: { suspendWindow.alpha = 0 }) { (complete) in if let index = SuspendTool.sharedInstance.suspendWindows.index(of: suspendWindow) { SuspendTool.sharedInstance.suspendWindows.remove(at: index) } } } static func setLatestOrigin(origin: CGPoint) { SuspendTool.sharedInstance.origin = origin } }
SuspendWindow
import UIKit let radious: CGFloat = 82 class SuspendWindow: UIWindow { fileprivate let coverImageName: String fileprivate let space: CGFloat = 15 var containsRootViewController: UIViewController? init(rootViewController: UIViewController ,coverImageName: String, frame: CGRect) { self.coverImageName = coverImageName super.init(frame: frame) // self.rootViewController = rootViewController self.containsRootViewController = rootViewController } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func show() { self.backgroundColor = UIColor.clear self.windowLevel = UIWindow.Level.alert - 1//UIWindowLevelAlert - 1 self.screen = UIScreen.main self.isHidden = false let bgView = UIView() bgView.isUserInteractionEnabled = true bgView.frame = self.bounds bgView.backgroundColor = UIColor.white bgView.layer.cornerRadius = radious / 2.0 bgView.layer.borderColor = UIColor.lightGray.cgColor bgView.layer.borderWidth = 5 bgView.layer.masksToBounds = true self.addSubview(bgView) bgView.addSubview(iconImageView) bgView.addSubview(timeLabel) let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(didPan(_:))) self.addGestureRecognizer(panGesture) let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(didTap(_:))) self.addGestureRecognizer(tapGesture) } @objc fileprivate func didTap(_ tapGesture: UITapGestureRecognizer) { SuspendTool.sharedInstance.origin = self.frame.origin self.containsRootViewController?.spread(from: self.self.frame.origin) SuspendTool.remove(suspendWindow: self) } @objc fileprivate func didPan(_ panGesture: UIPanGestureRecognizer) { let point = panGesture.translation(in: panGesture.view) var originX = self.frame.origin.x + point.x if originX < space { originX = space } else if originX > UIScreen.main.bounds.width - radious - space { originX = UIScreen.main.bounds.width - radious - space } var originY = self.frame.origin.y + point.y if originY < space { originY = space } else if originY > UIScreen.main.bounds.height - radious - space { originY = UIScreen.main.bounds.height - radious - space } self.frame = CGRect.init(x: originX, y: originY, width: self.bounds.width, height: self.bounds.height) if panGesture.state == UIGestureRecognizer.State.cancelled || panGesture.state == UIGestureRecognizer.State.ended || panGesture.state == UIGestureRecognizer.State.failed { self.adjustFrameAfterPan() } panGesture.setTranslation(CGPoint.zero, in: self) } fileprivate func adjustFrameAfterPan() { var originX: CGFloat = space if self.center.x < UIScreen.main.bounds.width / 2 { originX = space } else if self.center.x >= UIScreen.main.bounds.width / 2 { originX = UIScreen.main.bounds.width - radious - space } UIView.animate(withDuration: 0.25, animations: { self.frame = CGRect.init(x: originX, y: self.frame.origin.y, width: self.frame.size.width, height: self.frame.size.height) }) { (complete) in SuspendTool.setLatestOrigin(origin: self.frame.origin) } } lazy var timeLabel: UILabel = { let timeLabel = UILabel() timeLabel.frame = CGRect(x: 0, y: 55.5, width: 42, height: 13) timeLabel.center.x = self.bounds.size.width / 2 timeLabel.textAlignment = .center timeLabel.text = "0:00" timeLabel.textColor = UIColor.text timeLabel.font = UIFont.mediumFont(ofSize: 13) return timeLabel }() lazy var iconImageView: UIImageView = { let iconImageView = UIImageView.init(image: UIImage.init(named: coverImageName)) iconImageView.isUserInteractionEnabled = true iconImageView.frame = CGRect(x: 0, y: 12, width: 38, height: 38) iconImageView.center.x = self.bounds.size.width / 2 return iconImageView }() }
UIViewController+FF
import Foundation import UIKit extension UIViewController { func suspend(coverImageName: String, type: SuspendType) { if type == .none { self.navigationController?.popViewController(animated: true) return } self.view.layer.masksToBounds = true UIView.animate(withDuration: 0.25, animations: { self.view.layer.cornerRadius = radious / 2.0 self.view.frame = CGRect.init(origin: SuspendTool.sharedInstance.origin, size: CGSize.init(width: radious, height: radious)) self.view.layoutIfNeeded() }) { (complete) in self.navigationController?.popViewController(animated: false) if type == .single { SuspendTool.replaceSuspendWindow(rootViewController: self, coverImageName: coverImageName) } else { SuspendTool.showSuspendWindow(rootViewController: self, coverImageName: coverImageName) } } } func spread(from point: CGPoint) { if let isContain = self.navigationController?.viewControllers.contains(self), isContain { return } self.view.frame = CGRect.init(origin: point, size: CGSize.init(width: radious, height: radious)) //UIViewController.currentViewController() UIViewController.currentViewController().navigationController?.pushViewController(self, animated: false) UIView.animate(withDuration: 0.25, animations: { self.view.layer.cornerRadius = 0 self.view.frame = UIScreen.main.bounds self.view.layoutIfNeeded() }) } static func currentViewController() -> UIViewController { var rootViewController: UIViewController? = nil for window in UIApplication.shared.windows { if (window.rootViewController != nil) { rootViewController = window.rootViewController break } } var viewController = rootViewController while (true) { if viewController?.presentedViewController != nil { viewController = viewController!.presentedViewController } else if viewController!.isKind(of: UINavigationController.self) { viewController = (viewController as! UINavigationController).visibleViewController } else if viewController!.isKind(of: UITabBarController.self) { viewController = (viewController as! UITabBarController).selectedViewController } else { break } } return viewController! } }
总结
加载全部内容