Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
P
PhoneManager
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Yang
PhoneManager
Commits
855a80da
Commit
855a80da
authored
May 19, 2025
by
shenyong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
年费会员界面,启动引导页结构更改
parent
5e825e99
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
707 additions
and
73 deletions
+707
-73
AppDelegate.swift
PhoneManager/AppDelegate.swift
+14
-6
AppDelegateEx.swift
PhoneManager/AppDelegateEx.swift
+40
-0
Contents.json
...ssets.xcassets/Pay/iap_distance_bg.imageset/Contents.json
+22
-0
Frame@2x.png
...Assets.xcassets/Pay/iap_distance_bg.imageset/Frame@2x.png
+0
-0
Frame@3x.png
...Assets.xcassets/Pay/iap_distance_bg.imageset/Frame@3x.png
+0
-0
Contents.json
...ts.xcassets/Pay/iap_distance_offer.imageset/Contents.json
+22
-0
Frame_1171276222@2x.png
...s/Pay/iap_distance_offer.imageset/Frame_1171276222@2x.png
+0
-0
Frame_1171276222@3x.png
...s/Pay/iap_distance_offer.imageset/Frame_1171276222@3x.png
+0
-0
IAPManager.swift
PhoneManager/Class/Manager/IAPManager/IAPManager.swift
+36
-15
HomeViewController.swift
...nager/Class/Page/Home/Controller/HomeViewController.swift
+22
-1
HomeVideoDetailCustomHeaderView.swift
...lass/Page/Home/View/HomeVideoDetailCustomHeaderView.swift
+0
-7
NewGuideViewController.swift
PhoneManager/Class/Page/Landing/NewGuideViewController.swift
+16
-14
HomeLaunchView.swift
PhoneManager/Class/Page/Lauch/HomeLaunchView.swift
+75
-0
LauchVC.swift
PhoneManager/Class/Page/Lauch/LauchVC.swift
+21
-28
LaunchViewController.swift
PhoneManager/Class/Page/Lauch/LaunchViewController.swift
+56
-0
HomePayView.swift
PhoneManager/Class/Page/Pay/View/HomePayView.swift
+13
-0
HomePayViewController.swift
...Class/Page/Pay/ViewController/HomePayViewController.swift
+4
-2
PayDistanceViewController.swift
...s/Page/Pay/ViewController/PayDistanceViewController.swift
+300
-0
PayDistanceViewController.xib
...ass/Page/Pay/ViewController/PayDistanceViewController.xib
+22
-0
Common.swift
PhoneManager/Class/Tool/Common/Common.swift
+8
-0
FadeOutTransition.swift
PhoneManager/Class/Tool/Common/FadeOutTransition.swift
+36
-0
No files found.
PhoneManager/AppDelegate.swift
View file @
855a80da
...
@@ -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
}
}
...
...
PhoneManager/AppDelegateEx.swift
0 → 100644
View file @
855a80da
//
// 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
)
}
}
}
PhoneManager/Assets.xcassets/Pay/iap_distance_bg.imageset/Contents.json
0 → 100644
View file @
855a80da
{
"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
}
}
PhoneManager/Assets.xcassets/Pay/iap_distance_bg.imageset/Frame@2x.png
0 → 100644
View file @
855a80da
58.9 KB
PhoneManager/Assets.xcassets/Pay/iap_distance_bg.imageset/Frame@3x.png
0 → 100644
View file @
855a80da
62 KB
PhoneManager/Assets.xcassets/Pay/iap_distance_offer.imageset/Contents.json
0 → 100644
View file @
855a80da
{
"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
}
}
PhoneManager/Assets.xcassets/Pay/iap_distance_offer.imageset/Frame_1171276222@2x.png
0 → 100644
View file @
855a80da
12.1 KB
PhoneManager/Assets.xcassets/Pay/iap_distance_offer.imageset/Frame_1171276222@3x.png
0 → 100644
View file @
855a80da
25.1 KB
PhoneManager/Class/Manager/IAPManager/IAPManager.swift
View file @
855a80da
...
@@ -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
=
.
s
ubscribe
private
var
state
:
PayState
=
.
weekS
ubscribe
//购买操作的完成回调
//购买操作的完成回调
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
,
week
Product
==
nil
{
if
state
==
.
yearSubscribe
,
year
Product
==
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
=
.
s
ubscribe
,
completion
:
@escaping
(
Result
<
Bool
,
IAPError
>
)
->
Void
)
{
func
restore
(
_
state
:
PayState
=
.
weekS
ubscribe
,
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
()
}
}
}
}
...
...
PhoneManager/Class/Page/Home/Controller/HomeViewController.swift
View file @
855a80da
...
@@ -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
()
}
}
PhoneManager/Class/Page/Home/View/HomeVideoDetailCustomHeaderView.swift
View file @
855a80da
...
@@ -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
)
}
}
}
PhoneManager/Class/Page/Landing/NewGuideViewController.swift
View file @
855a80da
...
@@ -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
()
...
...
PhoneManager/Class/Page/Lauch/HomeLaunchView.swift
0 → 100644
View file @
855a80da
//
// 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
}()
}
PhoneManager/Class/Page/Lauch/LauchVC.swift
View file @
855a80da
...
@@ -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()
})
})
}
}
}
}
PhoneManager/Class/Page/Lauch/LaunchViewController.swift
0 → 100644
View file @
855a80da
//
// 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
}()
}
PhoneManager/Class/Page/Pay/View/HomePayView.swift
View file @
855a80da
...
@@ -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"
)
}
}
}
PhoneManager/Class/Page/Pay/ViewController/HomePayViewController.swift
View file @
855a80da
...
@@ -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
)
?
.
s
ubscribe
:
.
nonConsumable
)
{[
weak
self
]
result
in
IAPManager
.
share
.
purchase
((
homePayView
?
.
type
==
0
)
?
.
weekS
ubscribe
:
.
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
)
}
}
}
}
PhoneManager/Class/Page/Pay/ViewController/PayDistanceViewController.swift
0 → 100644
View file @
855a80da
//
// PayDistanceViewController.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import
UIKit
import
StoreKit
import
SVProgressHUD
class
PayDistanceViewController
:
UIViewController
{
var
scrollView
:
UIScrollView
!
var
dropImage
:
UIImageView
!
var
yearDistacePrice
:
UILabel
!
var
payBtn
:
UIButton
!
var
year
:
SKProduct
?
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
reloadSKPorduct
()
configUI
()
reloadSKPorduct
()
}
func
configUI
(){
scrollView
=
UIScrollView
()
scrollView
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
ScreenW
,
height
:
ScreenH
)
scrollView
.
contentSize
=
CGSize
(
width
:
ScreenW
,
height
:
ScreenH
)
view
.
addSubview
(
scrollView
)
let
closeBtn
=
UIButton
()
closeBtn
.
setImage
(
UIImage
.
init
(
named
:
"home_pay_close"
),
for
:
.
normal
)
closeBtn
.
addTarget
(
self
,
action
:
#selector(
payClose
)
,
for
:
.
touchUpInside
)
scrollView
.
addSubview
(
closeBtn
)
let
offerImage
=
UIImageView
()
offerImage
.
image
=
UIImage
.
init
(
named
:
"iap_distance_offer"
)
scrollView
.
addSubview
(
offerImage
)
dropImage
=
UIImageView
()
dropImage
.
image
=
UIImage
.
init
(
named
:
"iap_distance_bg"
)
scrollView
.
addSubview
(
dropImage
)
let
distanceL
=
UILabel
()
distanceL
.
text
=
"70% Discount"
distanceL
.
font
=
UIFont
.
systemFont
(
ofSize
:
40
,
weight
:
.
semibold
)
distanceL
.
textColor
=
UIColor
.
colorWithHex
(
hexStr
:
"#111111"
)
scrollView
.
addSubview
(
distanceL
)
let
annual
=
UILabel
()
annual
.
text
=
"Annual visit"
annual
.
font
=
UIFont
.
systemFont
(
ofSize
:
18
,
weight
:
.
semibold
)
annual
.
textColor
=
UIColor
.
colorWithHex
(
hexStr
:
"#111111"
)
scrollView
.
addSubview
(
annual
)
yearDistacePrice
=
UILabel
()
yearDistacePrice
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
semibold
)
yearDistacePrice
.
textColor
=
UIColor
.
colorWithHex
(
hexStr
:
"#111111"
)
yearDistacePrice
.
text
=
"$39.99 $19.99 / Year"
scrollView
.
addSubview
(
yearDistacePrice
)
let
priceAtt
=
createRichPriceText
(
originalPrice
:
"$39.99"
,
discountedPrice
:
"$19.99 / Year"
)
yearDistacePrice
.
attributedText
=
priceAtt
let
cancelLabel
=
UILabel
()
cancelLabel
.
font
=
UIFont
.
systemFont
(
ofSize
:
12
,
weight
:
.
semibold
)
cancelLabel
.
textColor
=
UIColor
.
colorWithHex
(
hexStr
:
"#0082FF"
)
cancelLabel
.
text
=
"Cancel at any time"
scrollView
.
addSubview
(
cancelLabel
)
payBtn
=
UIButton
()
payBtn
.
setTitle
(
"Get discounts"
,
for
:
.
normal
)
payBtn
.
setTitleColor
(
.
white
,
for
:
.
normal
)
payBtn
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
18
,
weight
:
.
semibold
)
payBtn
.
layer
.
cornerRadius
=
30
payBtn
.
addTarget
(
self
,
action
:
#selector(
iapPayAction
)
,
for
:
.
touchUpInside
)
payBtn
.
backgroundColor
=
UIColor
.
colorWithHex
(
hexStr
:
"#0082FF"
)
scrollView
.
addSubview
(
payBtn
)
let
termsBtn
=
UIButton
()
termsBtn
.
setTitle
(
"Terms"
,
for
:
.
normal
)
termsBtn
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
10
,
weight
:
.
medium
)
termsBtn
.
setTitleColor
(
UIColor
.
colorWithHex
(
hexStr
:
"#999999"
),
for
:
.
normal
)
termsBtn
.
titleLabel
?
.
addUnderline
()
scrollView
.
addSubview
(
termsBtn
)
let
recoveryBtn
=
UIButton
()
recoveryBtn
.
setTitle
(
"Recovery"
,
for
:
.
normal
)
recoveryBtn
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
10
,
weight
:
.
medium
)
recoveryBtn
.
setTitleColor
(
UIColor
.
colorWithHex
(
hexStr
:
"#999999"
),
for
:
.
normal
)
recoveryBtn
.
frame
=
CGRect
(
x
:
scrollView
.
bounds
.
width
-
66
,
y
:
ScreenH
-
(
20
+
kSafeAreaInsets
.
bottom
),
width
:
50
,
height
:
20
)
recoveryBtn
.
titleLabel
?
.
addUnderline
()
scrollView
.
addSubview
(
recoveryBtn
)
let
appleLabel
=
UILabel
()
appleLabel
.
font
=
UIFont
.
systemFont
(
ofSize
:
10
,
weight
:
.
medium
)
appleLabel
.
textColor
=
UIColor
.
colorWithHex
(
hexStr
:
"#111111"
)
appleLabel
.
text
=
" Apple Security Guarantee"
scrollView
.
addSubview
(
appleLabel
)
closeBtn
.
snp
.
makeConstraints
{
make
in
make
.
left
.
equalTo
(
16
)
make
.
top
.
equalTo
(
kSafeAreaInsets
.
top
+
20
)
make
.
size
.
equalTo
(
30
)
}
offerImage
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
top
.
equalTo
(
kSafeAreaInsets
.
top
+
70
)
make
.
width
.
equalTo
(
111
)
make
.
height
.
equalTo
(
37
)
}
distanceL
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
top
.
equalTo
(
dropImage
.
snp
.
bottom
)
.
offset
(
46
)
}
appleLabel
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
height
.
equalTo
(
20
)
make
.
top
.
equalToSuperview
()
.
offset
(
ScreenH
-
(
20
+
kSafeAreaInsets
.
bottom
))
}
termsBtn
.
snp
.
makeConstraints
{
make
in
make
.
centerY
.
equalTo
(
appleLabel
)
make
.
left
.
equalTo
(
16
)
}
payBtn
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
width
.
equalTo
(
343
)
make
.
height
.
equalTo
(
57
)
make
.
bottom
.
equalTo
(
appleLabel
.
snp
.
top
)
.
offset
(
-
24
)
}
cancelLabel
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
bottom
.
equalTo
(
payBtn
.
snp
.
top
)
.
offset
(
-
22
)
make
.
height
.
equalTo
(
22
)
}
yearDistacePrice
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
bottom
.
equalTo
(
cancelLabel
.
snp
.
top
)
.
offset
(
0
)
make
.
height
.
equalTo
(
22
)
}
annual
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
bottom
.
equalTo
(
yearDistacePrice
.
snp
.
top
)
.
offset
(
-
8
)
make
.
height
.
equalTo
(
22
)
}
}
override
func
viewDidAppear
(
_
animated
:
Bool
)
{
super
.
viewDidAppear
(
animated
)
setAnim
()
}
func
setAnim
(){
dropImage
.
frame
=
CGRect
(
x
:
(
ScreenW
-
300
)
/
2
,
y
:
-
224
,
width
:
300
,
height
:
224
)
// 添加重力动画效果
UIView
.
animate
(
withDuration
:
1.5
,
delay
:
0.2
,
usingSpringWithDamping
:
0.5
,
// 弹性系数,越小弹性越大
initialSpringVelocity
:
0.8
,
// 初始速度
options
:
.
curveEaseIn
,
animations
:
{
// 设置最终位置
self
.
dropImage
.
frame
=
CGRect
(
x
:
(
ScreenW
-
300
)
/
2
,
y
:
kSafeAreaInsets
.
top
+
129
,
// 根据原来的约束位置计算
width
:
300
,
height
:
224
)
},
completion
:
nil
)
// 添加呼吸动画
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
)
payBtn
.
layer
.
add
(
breathAnimation
,
forKey
:
"breathingAnimation"
)
}
func
reloadSKPorduct
(){
if
IAPManager
.
share
.
isSubscribed
{
}
IAPManager
.
share
.
fetchProducts
{
[
weak
self
]
products
in
guard
let
weakSelf
=
self
else
{
return
}
DispatchQueue
.
main
.
async
{
if
let
(
weekProduct
,
lifetimeProduct
,
yearProduct
)
=
products
{
weakSelf
.
year
=
yearProduct
weakSelf
.
reloadSKUI
()
}
}
}
}
func
reloadSKUI
(){
guard
let
year
=
year
else
{
return
}
let
priceAtt
=
createRichPriceText
(
originalPrice
:
"$39.99"
,
discountedPrice
:
"
\(
year
.
localizedPrice
)
/ Year"
)
yearDistacePrice
.
attributedText
=
priceAtt
}
}
extension
PayDistanceViewController
{
@objc
func
payClose
(){
self
.
dismiss
(
animated
:
true
)
}
@objc
func
iapPayAction
(){
IAPManager
.
share
.
purchase
(
.
yearSubscribe
)
{[
weak
self
]
result
in
guard
let
weakSelf
=
self
else
{
return
}
switch
result
{
case
.
success
(
let
success
):
DispatchQueue
.
main
.
async
{
SVProgressHUD
.
showSuccess
(
withStatus
:
"purchase succeeds"
)
weakSelf
.
dismiss
(
animated
:
true
)
}
case
.
failure
(
let
failure
):
DispatchQueue
.
main
.
async
{
SVProgressHUD
.
showError
(
withStatus
:
failure
.
localizedDescription
)
}
}
}
}
func
createRichPriceText
(
originalPrice
:
String
,
discountedPrice
:
String
)
->
NSAttributedString
{
// 创建可变属性字符串
let
attributedString
=
NSMutableAttributedString
()
// 1. 设置原价部分(带删除线)
let
originalPriceAttributes
:
[
NSAttributedString
.
Key
:
Any
]
=
[
.
foregroundColor
:
UIColor
.
colorWithHex
(
hexStr
:
"#111111"
,
alpha
:
0.6
),
.
strikethroughStyle
:
NSUnderlineStyle
.
single
.
rawValue
,
.
font
:
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
semibold
)
]
let
originalPricePart
=
NSAttributedString
(
string
:
originalPrice
,
attributes
:
originalPriceAttributes
)
attributedString
.
append
(
originalPricePart
)
// 2. 添加空格分隔
attributedString
.
append
(
NSAttributedString
(
string
:
" "
))
// 3. 设置折扣价部分(无删除线)
let
discountedPriceAttributes
:
[
NSAttributedString
.
Key
:
Any
]
=
[
.
foregroundColor
:
UIColor
.
colorWithHex
(
hexStr
:
"#111111"
),
.
font
:
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
semibold
)
]
let
discountedPricePart
=
NSAttributedString
(
string
:
discountedPrice
,
attributes
:
discountedPriceAttributes
)
attributedString
.
append
(
discountedPricePart
)
return
attributedString
}
}
PhoneManager/Class/Page/Pay/ViewController/PayDistanceViewController.xib
0 → 100644
View file @
855a80da
<?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>
PhoneManager/Class/Tool/Common/Common.swift
View file @
855a80da
...
@@ -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
)
}
PhoneManager/Class/Tool/Common/FadeOutTransition.swift
0 → 100644
View file @
855a80da
//
// 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
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment