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

 更新时间:2021年03月04日 11:45:39   作者:醉梦弦音  
这篇文章主要介绍了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!
 }

}

总结

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

相关文章

  • 纯swift实现ipad版简单美团界面功能

    纯swift实现ipad版简单美团界面功能

    这篇文章主要为大家详细介绍了纯swift实现ipad版简单美团界面功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Swift开发中switch语句值绑定模式

    Swift开发中switch语句值绑定模式

    本文给大家分享Swift开发中switch语句值绑定模式,非常不错,具有参考借鉴价值,需要的的朋友参考下
    2016-12-12
  • swift4.0实现视频播放、屏幕旋转、倍速播放、手势调节及锁屏面板等功能实例

    swift4.0实现视频播放、屏幕旋转、倍速播放、手势调节及锁屏面板等功能实例

    这篇文章主要给大家介绍了关于swift4.0实现视频播放、屏幕旋转、倍速播放、手势调节及锁屏面板等功能的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • Swift的开发环境搭建以及基本语法详解

    Swift的开发环境搭建以及基本语法详解

    这篇文章主要介绍了Swift的开发环境搭建以及基本语法详解,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • Swift编程中数组的使用方法指南

    Swift编程中数组的使用方法指南

    这篇文章主要介绍了Swift编程中数组的使用方法指南,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • 苹果公司编程语言Swift语言简介

    苹果公司编程语言Swift语言简介

    这篇文章主要介绍了苹果公司编程语言Swift语言简介,Swift 是一门新的编程语言,兼容Objective-C代码,是用来代替Objective-C的苹果主力开发语言,需要的朋友可以参考下
    2014-07-07
  • Swift 3.0基础学习之类与结构体

    Swift 3.0基础学习之类与结构体

    最近在学swift 3.0,主要看的是苹果的官方文档,这里只是根据自己看官方文档的理解所做的一些记录,不是完整的翻译,希望也对你有所帮助。下面这篇文章主要介绍了Swift 3.0基础学习之类与结构体的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-03-03
  • 深入理解Swift中的访问控制关键字

    深入理解Swift中的访问控制关键字

    这篇文章主要给大家介绍了Swift中访问控制关键字的相关资料,文中介绍的非常详细,对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • 如何删掉编程中的 Switch 语句

    如何删掉编程中的 Switch 语句

    多重方法是一种有趣的方式,可以帮你摆脱令人讨厌的 switch,这篇文章主要介绍了如何删掉编程中的 Switch 语句,需要的朋友可以参考下
    2022-09-09
  • SwiftUI中TabView组件的常规使用

    SwiftUI中TabView组件的常规使用

    这篇文章主要给大家介绍了关于SwiftUI中TabView组件的常规使用,文中通过实例代码介绍的非常详细,对大家学习或者使用SwiftUI具有一定的参考学习价值,需要的朋友可以参考下
    2022-06-06

最新评论