我报名参加金石计划1期应战——分割10万奖池,这是我的第2篇文章,点击查看活动详情
前言
我上一年的一篇文章具体的介绍了我编写的一套Swift弹窗组件库一个高雅的Swift弹窗组件-JFPopup。里边适配了一套ToastView,恰逢本年苹果iPhone14 Pro以上系列新出了一套灵动岛的交互风格,所以就意外想到能否把ToastView也适配进去灵动岛,所以此文就应运而生。我上篇文章现已很具体的介绍了JFPopup具体用法,这篇文章主要解说适配灵动岛的心路历程。
具体作用:
用法
尽管我上篇文章现已介绍了一遍,这里我仍是再写一下。另外灵动岛Toast默许适配iPhone14 Pro以上机型,无需另外操作,若不是灵动岛机型,则是默许居中,还支撑top及bottom。更多具体参数请看一个高雅的Swift弹窗组件-JFPopup
Toast:
//默许仅案牍
JFPopupView.popup.toast(hit: "默许toast,支撑灵动岛")
//带logo ,内置success or fail
JFPopupView.popup.toast(hit: "付出成功", icon: .success)
JFPopupView.popup.toast(hit: "付出失利", icon: .fail)
//自定义logo
JFPopupView.popup.toast(hit: "自定义", icon: .imageName(name: "face"))
Loading:
DispatchQueue.main.async {
JFPopupView.popup.loading()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
JFPopupView.popup.hideLoading()
JFPopupView.popup.toast(hit: "改写成功")
}
适配灵动岛具体过程
由于苹果官方现已说了要在下半年推出的ActivityKit才会加入适配灵动岛的Api。所以目前并没有官方的api可以给咱们适配。所以只能硬着头皮自己去思考适配方案了。
– 首要要知道灵动岛的区域巨细
咱们用最笨的方法,直接给模拟器截个图自己去算巨细。至少能复原99%的作用了。如图得知,灵动岛的区域大概是宽120dt,高34dp,那半圆圆角天然为17dt。居顶部大约10dp,以及在屏幕居中。有了这些信息,咱们天然就能模拟灵动岛的扩大缩小转场作用了。
– ToastView新增灵动岛动画
咱们在原先基础上新增灵动岛动画枚举
public enum JFToastPosition {
case center
case top
case bottom
case dynamicIsland //新增灵动岛方位动画
}
重新实现下present 及 dismiss协议的转场动画代码如下
打开:
let originSize = contianerView.jf.size
if config.toastPosition == .dynamicIsland {
contianerView.jf_size = CGSize(width: 120, height: 34)
contianerView.center = CGPoint(x: CGSize.jf.screenSize().width / 2, y: 27)
}
let updateV = {
contianerView.center = CGPoint(x: CGSize.jf.screenSize().width / 2, y: CGSize.jf.screenSize().height / 2)
if config.toastPosition == .top {
contianerView.jf_top = CGFloat.jf.navigationBarHeight() + 15
} else if config.toastPosition == .bottom {
contianerView.jf_bottom = CGSize.jf.screenHeight() - CGFloat.jf.safeAreaBottomHeight() - 15
} else if config.toastPosition == .dynamicIsland {
contianerView.jf_size = originSize
contianerView.center = CGPoint(x: CGSize.jf.screenSize().width / 2, y: originSize.height / 2 + 10)
}
contianerView.layoutIfNeeded()
}
guard config.withoutAnimation == false else {
updateV()
transitonContext?.completeTransition(true)
completion?(true)
return
}
if config.toastPosition == .dynamicIsland {
UIView.animate(withDuration: 0.25) {
updateV()
} completion: { finished in
transitonContext?.completeTransition(true)
completion?(finished)
}
return
}
消失:
UIView.animate(withDuration: 0.25, animations: {
if config.toastPosition == .dynamicIsland {
contianerView?.layer.cornerRadius = 17
contianerView?.jf_size = CGSize(width: 120, height: 34)
contianerView?.center = CGPoint(x: CGSize.jf.screenSize().width / 2, y: 27)
}
contianerView?.subviews.forEach({ v in
if config.toastPosition == .dynamicIsland {
v.isHidden = true
} else {
v.alpha = 0
}
})
contianerView?.alpha = 0
}) { (finished) in
transitonContext?.completeTransition(true)
completion?(finished)
}
末尾
以上便是我JFPopup内置组件JFToastView适配灵动岛动画的全过程,假如下半年苹果更新了Api我也会第一时间重新适配。