Commit 855a80da authored by shenyong's avatar shenyong

年费会员界面,启动引导页结构更改

parent 5e825e99
...@@ -27,13 +27,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -27,13 +27,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
window?.backgroundColor = .white window?.backgroundColor = .white
window?.overrideUserInterfaceStyle = .light window?.overrideUserInterfaceStyle = .light
let Ssoryboard = UIStoryboard(name: "LauchVC", bundle: nil)
if let current = Ssoryboard.instantiateViewController(identifier: "LauchVCID") as? LauchVC { let rootNav = BaseNavViewController(rootViewController: HomeViewController())
window?.rootViewController = rootNav
window?.rootViewController = current
window?.makeKeyAndVisible() window?.makeKeyAndVisible()
}
// let Ssoryboard = UIStoryboard(name: "LauchVC", bundle: nil)
//
// if let current = Ssoryboard.instantiateViewController(identifier: "LauchVCID") as? LauchVC {
//
// window?.rootViewController = current
// window?.makeKeyAndVisible()
// }
let battery = WidgetPublicModel.battery() let battery = WidgetPublicModel.battery()
let storage = WidgetPublicModel.UseDiskSpace() * 100 let storage = WidgetPublicModel.UseDiskSpace() * 100
widgetAppgourp.share.PushWidgetData(battery: Int(battery), storage: Int(storage)) widgetAppgourp.share.PushWidgetData(battery: Int(battery), storage: Int(storage))
...@@ -51,6 +57,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -51,6 +57,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// 相册基本资源加载 // 相册基本资源加载
PhotoManager.shared.config() PhotoManager.shared.config()
// 设置app动态按钮
setupDynamicShortcuts()
return true return true
} }
......
//
// AppDelegateEx.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import Foundation
import UIKit
extension AppDelegate{
func setupDynamicShortcuts() {
let shortcutItem = UIApplicationShortcutItem(
type: "com.app.phonemanager.iap.distance",
localizedTitle: "Unlock Exclusive Discounts",
localizedSubtitle: "Your special offer is awaiting—don't miss this limited-time second chance benefit!",
icon: UIApplicationShortcutIcon(systemImageName: "star.fill"),
userInfo: nil
)
UIApplication.shared.shortcutItems = [shortcutItem]
}
// 处理快捷方式点击
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
// 处理快捷方式点击事件
switch shortcutItem.type {
case "com.app.phonemanager.iap.distance":
// 执行相应操作
let vc = PayDistanceViewController()
vc.modalPresentationStyle = .fullScreen
GETCURRENTNAV()?.present(vc, animated: false)
completionHandler(true)
default:
completionHandler(false)
}
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame_1171276222@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame_1171276222@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -48,7 +48,8 @@ class IAPManager: NSObject { ...@@ -48,7 +48,8 @@ class IAPManager: NSObject {
private let alert = PMLoadingHUD.share private let alert = PMLoadingHUD.share
enum PayState { enum PayState {
case subscribe case weekSubscribe
case yearSubscribe
case nonConsumable case nonConsumable
} }
...@@ -56,9 +57,10 @@ class IAPManager: NSObject { ...@@ -56,9 +57,10 @@ class IAPManager: NSObject {
private struct ProductID { private struct ProductID {
static let weekMember = "com.app.phonemanager.week.member" static let weekMember = "com.app.phonemanager.week.member"
static let lifetimeMember = "com.app.phonemanager.lifetime.member" static let lifetimeMember = "com.app.phonemanager.lifetime.member"
static let yearMember = "com.app.phonemanager.year.member"
static var all: [String] { static var all: [String] {
return [weekMember, lifetimeMember] return [weekMember, lifetimeMember,yearMember]
} }
} }
...@@ -66,14 +68,16 @@ class IAPManager: NSObject { ...@@ -66,14 +68,16 @@ class IAPManager: NSObject {
private var weekProduct: SKProduct? private var weekProduct: SKProduct?
// 永久订阅 // 永久订阅
private var lifetimeProduct: SKProduct? private var lifetimeProduct: SKProduct?
// 年费订阅
private var yearProduct: SKProduct?
private var state: PayState = .subscribe private var state: PayState = .weekSubscribe
//购买操作的完成回调 //购买操作的完成回调
private var purchaseCompletion: ((Result<Bool, IAPError>) -> Void)? private var purchaseCompletion: ((Result<Bool, IAPError>) -> Void)?
//恢复购买的完成回调 //恢复购买的完成回调
private var restoreCompletion: ((Result<Bool, IAPError>) -> Void)? private var restoreCompletion: ((Result<Bool, IAPError>) -> Void)?
//获取商品信息的完成回调 //获取商品信息的完成回调
private var productRequestCompletion: (((SKProduct?,SKProduct?)?) -> Void)? private var productRequestCompletion: (((SKProduct?,SKProduct?,SKProduct?)?) -> Void)?
var isSubscribed = false { var isSubscribed = false {
didSet { didSet {
...@@ -98,15 +102,16 @@ class IAPManager: NSObject { ...@@ -98,15 +102,16 @@ class IAPManager: NSObject {
extension IAPManager { extension IAPManager {
// 获取订阅内购商品信息 // 获取订阅内购商品信息
func fetchProducts(completion: @escaping ((SKProduct?,SKProduct?)?) -> Void) { func fetchProducts(completion: @escaping ((SKProduct?,SKProduct?,SKProduct?)?) -> Void) {
// 先检查缓存 // 先检查缓存
if let cachedProducts = getCachedProducts() { if let cachedProducts = getCachedProducts() {
// 后台更新最新数据 // 后台更新最新数据
self.weekProduct = cachedProducts.filter{$0.productIdentifier == ProductID.weekMember}.first self.weekProduct = cachedProducts.filter{$0.productIdentifier == ProductID.weekMember}.first
self.lifetimeProduct = cachedProducts.filter{$0.productIdentifier == ProductID.lifetimeMember}.first self.lifetimeProduct = cachedProducts.filter{$0.productIdentifier == ProductID.lifetimeMember}.first
completion((self.weekProduct,self.lifetimeProduct)) self.yearProduct = cachedProducts.filter{$0.productIdentifier == ProductID.yearMember}.first
completion((self.weekProduct,self.lifetimeProduct,self.yearProduct))
refreshProducts() refreshProducts()
return
} }
productRequestCompletion = completion productRequestCompletion = completion
...@@ -157,9 +162,14 @@ extension IAPManager { ...@@ -157,9 +162,14 @@ extension IAPManager {
} }
} }
func purchase(_ state: PayState = .subscribe, completion: @escaping (Result<Bool, IAPError>) -> Void) { func purchase(_ state: PayState = .weekSubscribe, completion: @escaping (Result<Bool, IAPError>) -> Void) {
if state == .weekSubscribe,weekProduct == nil{
completion(.failure(.noProductsFound))
return
}
if state == .subscribe,weekProduct == nil{ if state == .yearSubscribe,yearProduct == nil{
completion(.failure(.noProductsFound)) completion(.failure(.noProductsFound))
return return
} }
...@@ -175,12 +185,23 @@ extension IAPManager { ...@@ -175,12 +185,23 @@ extension IAPManager {
self.state = state self.state = state
self.purchaseCompletion = completion self.purchaseCompletion = completion
let payment = SKPayment(product: state == .subscribe ? weekProduct! : lifetimeProduct!)
var payment:SKPayment = SKPayment()
switch state{
case .weekSubscribe:
payment = SKPayment(product: weekProduct!)
case .yearSubscribe:
payment = SKPayment(product: yearProduct!)
case .nonConsumable:
payment = SKPayment(product: lifetimeProduct!)
}
SKPaymentQueue.default().add(payment) SKPaymentQueue.default().add(payment)
alert.show("Processing the purchase request...", "") alert.show("Processing the purchase request...", "")
} }
func restore(_ state: PayState = .subscribe, completion: @escaping (Result<Bool, IAPError>) -> Void) { func restore(_ state: PayState = .weekSubscribe, completion: @escaping (Result<Bool, IAPError>) -> Void) {
self.state = state self.state = state
self.restoreCompletion = completion self.restoreCompletion = completion
SKPaymentQueue.default().restoreCompletedTransactions() SKPaymentQueue.default().restoreCompletedTransactions()
...@@ -384,15 +405,15 @@ extension IAPManager: SKProductsRequestDelegate { ...@@ -384,15 +405,15 @@ extension IAPManager: SKProductsRequestDelegate {
// 拿到请求下来的商品信息 // 拿到请求下来的商品信息
self.weekProduct = products.filter{$0.productIdentifier == ProductID.weekMember}.first self.weekProduct = products.filter{$0.productIdentifier == ProductID.weekMember}.first
self.lifetimeProduct = products.filter{$0.productIdentifier == ProductID.lifetimeMember}.first self.lifetimeProduct = products.filter{$0.productIdentifier == ProductID.lifetimeMember}.first
self.yearProduct = products.filter{$0.productIdentifier == ProductID.yearMember}.first
// 缓存 // 缓存
if let week = self.weekProduct,let life = self.lifetimeProduct{ if let week = self.weekProduct,let life = self.lifetimeProduct,let year = self.yearProduct{
cacheProducts([week,life]) cacheProducts([week,life,year])
} }
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
self?.productRequestCompletion?((weakSelf.weekProduct,weakSelf.lifetimeProduct)) self?.productRequestCompletion?((weakSelf.weekProduct,weakSelf.lifetimeProduct,weakSelf.yearProduct))
BackgroundTaskManager.share.endTask() BackgroundTaskManager.share.endTask()
} }
} }
......
...@@ -107,7 +107,7 @@ class HomeViewController:BaseViewController { ...@@ -107,7 +107,7 @@ class HomeViewController:BaseViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
loadLaunchView()
self.setupUI() self.setupUI()
// 调用下追踪权限 // 调用下追踪权限
...@@ -182,6 +182,18 @@ class HomeViewController:BaseViewController { ...@@ -182,6 +182,18 @@ class HomeViewController:BaseViewController {
} }
func loadLaunchView(){
let luanch = HomeLaunchView(frame: CGRect(x: 0, y: 0, width: ScreenW, height: ScreenH))
luanch.show()
if !UserDef.shard.isShowLanding{
let Ssoryboard = UIStoryboard(name: "PermissionVC", bundle: nil)
if let current = Ssoryboard.instantiateViewController(identifier: "PermissionVCID") as? PermissionVC {
self.navigationController?.pushViewController(current, animated: false)
}
}
}
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
...@@ -259,3 +271,12 @@ extension HomeViewController { ...@@ -259,3 +271,12 @@ extension HomeViewController {
} }
} }
} }
// 遵守转场代理协议
extension HomeViewController: UIViewControllerTransitioningDelegate {
// 返回自定义的消失动画对象
func animationController(forDismissed dismissedController: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return FadeOutTransition()
}
}
...@@ -233,11 +233,4 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView { ...@@ -233,11 +233,4 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
GETCURRENTNAV()?.pushViewController(vc, animated: true) GETCURRENTNAV()?.pushViewController(vc, animated: true)
} }
func GETCURRENTNAV() -> UINavigationController? {
let k = UIApplication.shared.windows.filter({$0.isKeyWindow}).first
let pre = k?.rootViewController?.presentedViewController
let rt = k?.rootViewController
return (pre as? UINavigationController) ?? ((rt as? UITabBarController)?.selectedViewController as? UINavigationController) ?? (rt as? UINavigationController)
}
} }
...@@ -81,21 +81,23 @@ class NewGuideViewController: UIViewController { ...@@ -81,21 +81,23 @@ class NewGuideViewController: UIViewController {
} }
func enterHome(){ func enterHome(){
let vc:HomeViewController = HomeViewController() // let vc:HomeViewController = HomeViewController()
//
let nav = BaseNavViewController(rootViewController: vc) // let nav = BaseNavViewController(rootViewController: vc)
//
cWindow?.rootViewController = nav // cWindow?.rootViewController = nav
//
let transition = CATransition() // let transition = CATransition()
transition.duration = 0.5 // transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) // transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
//
// 添加动画到 window 的 layer // // 添加动画到 window 的 layer
cWindow?.layer.add(transition, forKey: kCATransition) // cWindow?.layer.add(transition, forKey: kCATransition)
//
// // 显示 window
// cWindow?.makeKeyAndVisible()
// 显示 window self.navigationController?.popToRootViewController(animated: false)
cWindow?.makeKeyAndVisible()
UserDef.shard.isShowLanding = true UserDef.shard.isShowLanding = true
UserDef.shard.saveUserDefToSandBox() UserDef.shard.saveUserDefToSandBox()
......
//
// HomeLaunchView.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
import Lottie
class HomeLaunchView:UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.frame = frame
configUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configUI(){
backgroundColor = UIColor.colorWithHex(hexStr: "#0082FF")
let logoImage = UIImageView()
logoImage.image = UIImage.init(named: "icon_phone_manager")
addSubview(logoImage)
let nameImage = UIImageView()
nameImage.image = UIImage.init(named: "icon_phone_manager_name")
addSubview(nameImage)
addSubview(LaunchingLoop)
logoImage.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(kSafeAreaInsets.top+150)
}
nameImage.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(logoImage.snp.bottom).offset(12)
}
LaunchingLoop.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.height.equalTo(150)
make.bottom.equalToSuperview().offset(-60 * RScreenH())
}
}
func show(){
KEYWINDOW()?.addSubview(self)
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
self.alpha = 1
UIView.animate(withDuration: 0.3) {
self.alpha = 0
}completion: { _ in
self.removeFromSuperview()
}
})
}
private lazy var LaunchingLoop: LottieAnimationView = {
let animationView = LottieAnimationView(name: "launch_loaing")
animationView.loopMode = .loop
animationView.play()
return animationView
}()
}
...@@ -29,40 +29,33 @@ class LauchVC:UIViewController { ...@@ -29,40 +29,33 @@ class LauchVC:UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
// backView.addSubview(LaunchingView) view.addSubview(LaunchingLoop)
backView.addSubview(LaunchingLoop)
// LaunchingView.snp.makeConstraints { make in
// make.centerX.equalToSuperview()
// make.centerY.equalToSuperview().offset(-140 * RScreenH())
// make.width.equalToSuperview()
// make.height.equalTo(LaunchingView.snp.width)
// }
LaunchingLoop.snp.makeConstraints { make in LaunchingLoop.snp.makeConstraints { make in
make.centerX.equalToSuperview() make.centerX.equalToSuperview()
make.width.height.equalTo(150) make.width.height.equalTo(150)
make.bottom.equalToSuperview().offset(-60 * RScreenH()) make.bottom.equalToSuperview().offset(-60 * RScreenH())
} }
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: { DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
var vc:UIViewController? self.dismiss(animated: false)
if (UserDef.shard.isShowLanding) { // var vc:UIViewController?
vc = HomeViewController() // if (UserDef.shard.isShowLanding) {
}else { // vc = HomeViewController()
let Ssoryboard = UIStoryboard(name: "PermissionVC", bundle: nil) // }else {
if let current = Ssoryboard.instantiateViewController(identifier: "PermissionVCID") as? PermissionVC { // let Ssoryboard = UIStoryboard(name: "PermissionVC", bundle: nil)
vc = current // if let current = Ssoryboard.instantiateViewController(identifier: "PermissionVCID") as? PermissionVC {
} // vc = current
} // }
guard let vc else {return} // }
let nav = BaseNavViewController(rootViewController: vc) // guard let vc else {return}
cWindow?.rootViewController = nav // let nav = BaseNavViewController(rootViewController: vc)
let transition = CATransition() // cWindow?.rootViewController = nav
transition.duration = 0.5 // let transition = CATransition()
transition.subtype = CATransitionSubtype.fromRight // 从左侧推入 // transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) // transition.subtype = CATransitionSubtype.fromRight // 从左侧推入
cWindow?.layer.add(transition, forKey: kCATransition) // transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
cWindow?.makeKeyAndVisible() // cWindow?.layer.add(transition, forKey: kCATransition)
// cWindow?.makeKeyAndVisible()
}) })
} }
} }
//
// LaunchViewController.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
import Lottie
class LaunchViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.colorWithHex(hexStr: "#0082FF")
let logoImage = UIImageView()
logoImage.image = UIImage.init(named: "icon_phone_manager")
view.addSubview(logoImage)
let nameImage = UIImageView()
nameImage.image = UIImage.init(named: "icon_phone_manager_name")
view.addSubview(nameImage)
view.addSubview(LaunchingLoop)
logoImage.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(kSafeAreaInsets.top+150)
}
nameImage.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(logoImage.snp.bottom).offset(12)
}
LaunchingLoop.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.height.equalTo(150)
make.bottom.equalToSuperview().offset(-60 * RScreenH())
}
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
self.dismiss(animated: true)
})
}
private lazy var LaunchingLoop: LottieAnimationView = {
let animationView = LottieAnimationView(name: "launch_loaing")
animationView.loopMode = .loop
animationView.play()
return animationView
}()
}
...@@ -631,4 +631,17 @@ class HomePayView:UIView { ...@@ -631,4 +631,17 @@ class HomePayView:UIView {
addSubview(payDueView) addSubview(payDueView)
return payDueView return payDueView
}() }()
func setPayAnime(){
// 添加呼吸动画
let breathAnimation = CABasicAnimation(keyPath: "transform.scale")
breathAnimation.fromValue = 1.0
breathAnimation.toValue = 1.05
breathAnimation.duration = 0.8
breathAnimation.autoreverses = true
breathAnimation.repeatCount = Float.infinity
breathAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
payButton?.layer.add(breathAnimation, forKey: "breathingAnimation")
}
} }
...@@ -10,6 +10,7 @@ import StoreKit ...@@ -10,6 +10,7 @@ import StoreKit
import SVProgressHUD import SVProgressHUD
class HomePayViewController:UIViewController { class HomePayViewController:UIViewController {
private var homePayView:HomePayView? private var homePayView:HomePayView?
...@@ -121,7 +122,7 @@ extension HomePayViewController { ...@@ -121,7 +122,7 @@ extension HomePayViewController {
IAPManager.share.fetchProducts { [weak self] products in IAPManager.share.fetchProducts { [weak self] products in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
DispatchQueue.main.async { DispatchQueue.main.async {
if let (weekProduct, lifetimeProduct) = products { if let (weekProduct, lifetimeProduct,_) = products {
weakSelf.homePayView?.reloadSKPorduct(week: weekProduct, life: lifetimeProduct) weakSelf.homePayView?.reloadSKPorduct(week: weekProduct, life: lifetimeProduct)
} }
} }
...@@ -129,7 +130,7 @@ extension HomePayViewController { ...@@ -129,7 +130,7 @@ extension HomePayViewController {
} }
private func payTouch() -> Void { private func payTouch() -> Void {
IAPManager.share.purchase((homePayView?.type == 0) ? .subscribe : .nonConsumable) {[weak self] result in IAPManager.share.purchase((homePayView?.type == 0) ? .weekSubscribe : .nonConsumable) {[weak self] result in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
switch result { switch result {
case .success(let success): case .success(let success):
...@@ -182,4 +183,5 @@ extension HomePayViewController { ...@@ -182,4 +183,5 @@ extension HomePayViewController {
rt.present(nav, animated: true) rt.present(nav, animated: true)
} }
} }
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PayDistanceViewController" customModuleProvider="target">
<connections>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
</view>
</objects>
</document>
...@@ -83,3 +83,11 @@ public func Alert( _ title:String? , _ message:String) -> Void { ...@@ -83,3 +83,11 @@ public func Alert( _ title:String? , _ message:String) -> Void {
alert.addAction(UIAlertAction(title: "OK", style: .cancel)) alert.addAction(UIAlertAction(title: "OK", style: .cancel))
cWindow?.rootViewController?.present(alert, animated: true) cWindow?.rootViewController?.present(alert, animated: true)
} }
func GETCURRENTNAV() -> UINavigationController? {
let k = UIApplication.shared.windows.filter({$0.isKeyWindow}).first
let pre = k?.rootViewController?.presentedViewController
let rt = k?.rootViewController
return (pre as? UINavigationController) ?? ((rt as? UITabBarController)?.selectedViewController as? UINavigationController) ?? (rt as? UINavigationController)
}
//
// FadeOutTransition.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import Foundation
import UIKit
// 自定义转场动画(用于消失时的渐隐效果)
class FadeOutTransition: NSObject, UIViewControllerAnimatedTransitioning {
// 动画时长(可自定义)
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3 // 0.3秒渐隐
}
// 执行动画
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
// 获取即将消失的控制器(被弹出的控制器)
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to) else { return }
// 将目标控制器的视图添加到容器视图(确保转场后界面正确)
transitionContext.containerView.addSubview(toVC.view)
// 渐隐动画:将 fromVC 的视图透明度从 1 降到 0
UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
fromVC.view.alpha = 0
}) { (_) in
// 动画完成后,标记转场结束
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment