服务器之家

服务器之家 > 正文

Swift仿微信语音通话最小化时后的效果实例代码

时间:2021-12-23 15:18     来源/作者:醉梦弦音

前言

最近碰到个需求,需要仿微信语音通话缩小化后,保持界面最上层有一个悬浮的小View可以一点击就把刚刚缩放掉的界面再放回来,其实本质就是创造了一个新的Window,在这个window上创建了一个rootController并展示他,缩小化时是把controller dismiss掉了,再次点击那个小View之后把这个controller再展示出来便可以了。同理微信小程序其实也是在一个新的Window中做了一套新的逻辑。随着现在手机性能的提升,多Window同时存在并不会造成严重卡顿,而衍生出来的一种新的开发方式。

实例代码

上代码,这个是根据网上找到的类似效果进行了部分修改的,作者叫冯琦帆

SuspendTool

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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!
 }
 
}

总结

到此这篇关于Swift仿微信语音通话最小化时后效果的文章就介绍到这了,更多相关Swift微信语音通话最小化内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://juejin.cn/post/6935348223850577927

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
返回顶部