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
6a947483
Commit
6a947483
authored
May 16, 2025
by
shenyong
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev_syong' into dev_main
parents
2907ba5e
02803439
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
363 additions
and
189 deletions
+363
-189
PhotoDuplicateManager.swift
.../Class/Manager/PMPhotoManager/PhotoDuplicateManager.swift
+17
-4
PhotoManager.swift
PhoneManager/Class/Manager/PMPhotoManager/PhotoManager.swift
+38
-1
PhotoSimilarManager.swift
...er/Class/Manager/PMPhotoManager/PhotoSimilarManager.swift
+5
-4
ScreenShotSimilarManager.swift
...ass/Manager/PMPhotoManager/ScreenShotSimilarManager.swift
+4
-4
VideoSimilarManager.swift
...er/Class/Manager/PMPhotoManager/VideoSimilarManager.swift
+64
-18
CompressController.swift
...r/Class/Page/Compress/Controller/CompressController.swift
+1
-1
HomeInfoViewController.swift
...r/Class/Page/Home/Controller/HomeInfoViewController.swift
+1
-3
HomePhotosDetailViewController.swift
...Page/Home/Controller/HomePhotosDetailViewController.swift
+1
-1
HomeVideoDetailController.swift
...lass/Page/Home/Controller/HomeVideoDetailController.swift
+1
-1
HomeCollectionViewHeader.swift
...nager/Class/Page/Home/View/HomeCollectionViewHeader.swift
+17
-20
HomeView.swift
PhoneManager/Class/Page/Home/View/HomeView.swift
+11
-11
VideocompressionHeadView.swift
...nager/Class/Page/Home/View/VideocompressionHeadView.swift
+10
-4
VideocompressionHeadView.xib
...Manager/Class/Page/Home/View/VideocompressionHeadView.xib
+1
-0
HomeViewModel.swift
PhoneManager/Class/Page/Home/ViewModel/HomeViewModel.swift
+5
-62
MaintaiDetailViewController.swift
...ss/Page/Keep/Controller/MaintaiDetailViewController.swift
+51
-10
MaintainViewListController.swift
...ass/Page/Keep/Controller/MaintainViewListController.swift
+42
-7
MaintaiDetailTableViewCell.swift
...ger/Class/Page/Keep/View/MaintaiDetailTableViewCell.swift
+10
-5
MaintaiDetialVideoCell.swift
...Manager/Class/Page/Keep/View/MaintaiDetialVideoCell.swift
+67
-32
MaintaiTipsAlertView.swift
PhoneManager/Class/Page/Keep/View/MaintaiTipsAlertView.swift
+3
-0
PhotoAndVideoMananger.swift
...l/Class/PhotoAndVideoMananger/PhotoAndVideoMananger.swift
+1
-1
NSString+Extension.swift
...nager/Class/Tool/Extension.swift/NSString+Extension.swift
+13
-0
No files found.
PhoneManager/Class/Manager/PMPhotoManager/PhotoDuplicateManager.swift
View file @
6a947483
...
...
@@ -49,7 +49,7 @@ class PhotoDuplicateManager: @unchecked Sendable {
print
(
"本地数据加载完成"
)
// 2. 通知已缓存的结果
let
cachedGroups
=
await
stateManager
.
getAllDuplicateGroups
()
let
cachedGroups
=
await
loadSimilarGroups
()
//
stateManager.getAllDuplicateGroups()
print
(
"通知已缓存的结果"
,
cachedGroups
.
count
)
await
MainActor
.
run
{
let
groups
=
cachedGroups
.
map
{
$0
.
assets
}
...
...
@@ -143,7 +143,7 @@ class PhotoDuplicateManager: @unchecked Sendable {
await
self
.
savePendingDuplicateGroups
()
}
let
allGroups
=
await
stateManager
.
getAllDuplicateGroups
()
let
allGroups
=
await
loadSimilarGroups
()
//
stateManager.getAllDuplicateGroups()
await
MainActor
.
run
{
print
(
"执行完毕"
)
completionHandler
?(
allGroups
.
map
{
$0
.
assets
})
...
...
@@ -209,17 +209,30 @@ extension PhotoDuplicateManager {
private
func
savePendingDuplicateGroups
()
async
{
await
stateManager
.
savePendingGroups
()
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAllDuplicate
Groups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
loadSimilar
Groups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
duplicateGroupsPath
))
}
}
private
func
loadSimilarGroups
()
async
->
[
SimilarGroupModel
]
{
let
groups
=
await
stateManager
.
getAllDuplicateGroups
()
// 验证资源有效性
return
groups
.
map
{
group
in
var
validAssets
=
group
.
assets
validAssets
.
removeAll
{
asset
in
let
fetchResult
=
PHAsset
.
fetchAssets
(
withLocalIdentifiers
:
[
asset
.
localIdentifier
],
options
:
nil
)
return
fetchResult
.
firstObject
==
nil
}
return
SimilarGroupModel
(
groupId
:
group
.
groupId
,
assets
:
validAssets
)
}
.
filter
{
!
$0
.
assets
.
isEmpty
}
}
// 移除本地文件资源
func
removeLocalFileWithIds
(
for
ids
:[
String
])
async
{
await
stateManager
.
deleteData
(
for
:
ids
)
// 保存到文件
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAllDuplicate
Groups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
loadSimilar
Groups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
duplicateGroupsPath
))
}
}
...
...
PhoneManager/Class/Manager/PMPhotoManager/PhotoManager.swift
View file @
6a947483
...
...
@@ -113,6 +113,11 @@ class PhotoManager{
private(set)
var
screenShotTotalSize
:
Int64
=
0
private(set)
var
videoTotalSize
:
Int64
=
0
private(set)
var
otherTotalSize
:
Int64
=
0
var
trash
=
TrashDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
var
keep
=
GroupDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
private
var
currentPage
:
Int
=
0
private
let
pageSize
:
Int
=
50
// 每次加载的数量
...
...
@@ -722,11 +727,12 @@ extension PhotoManager{
let
similarPhotos
=
filterGroups
(
similarModels
,
byExcludingIDs
:
deletes
)
let
similarVideos
=
filterGroups
(
similarVideoModels
,
byExcludingIDs
:
deletes
)
let
similarShots
=
filterGroups
(
similarScreenShotModels
,
byExcludingIDs
:
deletes
)
let
duplicates
=
filterGroups
(
duplicateModels
,
byExcludingIDs
:
deletes
)
similarModels
=
similarPhotos
similarVideoModels
=
similarVideos
similarScreenShotModels
=
similarShots
duplicateModels
=
duplicates
// 保存到本地
saveToLocal
(
type
:
"video"
,
models
:
self
.
videoModels
)
...
...
@@ -756,4 +762,35 @@ extension PhotoManager{
}
}
// 重写获取垃圾桶和保留刷新进行刷新
func
reloadTrashAndKeep
(){
trash
=
TrashDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
keep
=
GroupDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
filterResource
()
}
// 基本资源过滤保留和垃圾桶资源
func
filterResource
(){
let
filterArray
=
trash
+
keep
let
others
=
removeAssets
(
withIdentifiers
:
filterArray
,
from
:
otherModels
)
let
videos
=
removeAssets
(
withIdentifiers
:
filterArray
,
from
:
videoModels
)
let
screens
=
removeAssets
(
withIdentifiers
:
filterArray
,
from
:
screenShotModels
)
filterOtherModels
=
others
filterVideoModels
=
videos
filterScreenShotModels
=
screens
let
similarPhotos
=
filterGroups
(
similarModels
,
byExcludingIDs
:
filterArray
)
let
similarVideos
=
filterGroups
(
similarVideoModels
,
byExcludingIDs
:
filterArray
)
let
similarShots
=
filterGroups
(
similarScreenShotModels
,
byExcludingIDs
:
filterArray
)
filterSimilarModels
=
similarPhotos
filterSimilarVideoModels
=
similarVideos
filterSimilarScreenShotModels
=
similarShots
}
}
PhoneManager/Class/Manager/PMPhotoManager/PhotoSimilarManager.swift
View file @
6a947483
...
...
@@ -59,7 +59,7 @@ class PhotoSimilarManager: @unchecked Sendable {
}
// 3. 通知已缓存的结果
let
cachedGroups
=
await
stateManager
.
getAllSimilarGroups
()
let
cachedGroups
=
await
loadSimilarGroups
()
//await
stateManager.getAllSimilarGroups()
print
(
"通知已缓存的结果"
,
cachedGroups
.
count
)
await
MainActor
.
run
{
for
group
in
cachedGroups
{
...
...
@@ -176,7 +176,8 @@ class PhotoSimilarManager: @unchecked Sendable {
await
savePendingSimilarGroups
()
}
let
allGroups
=
await
stateManager
.
getAllSimilarGroups
()
// var allGroups = await stateManager.getAllSimilarGroups()
let
allGroups
=
await
loadSimilarGroups
()
await
MainActor
.
run
{
print
(
"执行完毕"
)
completionHandler
?(
allGroups
.
map
{
$0
.
assets
})
...
...
@@ -332,7 +333,7 @@ extension PhotoSimilarManager{
private
func
savePendingSimilarGroups
()
async
{
await
stateManager
.
savePendingGroups
()
// 保存到文件
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAll
SimilarGroups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
load
SimilarGroups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
similarGroupsPath
))
}
}
...
...
@@ -355,7 +356,7 @@ extension PhotoSimilarManager{
await
stateManager
.
deleteData
(
for
:
ids
)
// 保存到文件
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAll
SimilarGroups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
load
SimilarGroups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
similarGroupsPath
))
}
}
...
...
PhoneManager/Class/Manager/PMPhotoManager/ScreenShotSimilarManager.swift
View file @
6a947483
...
...
@@ -58,7 +58,7 @@ class ScreenshotSimilarJSONManager: @unchecked Sendable {
}
// 3. 通知已缓存的结果
let
cachedGroups
=
await
stateManager
.
getAllSimilarGroups
()
let
cachedGroups
=
await
loadSimilarGroups
()
//await
stateManager.getAllSimilarGroups()
print
(
"通知已缓存的结果"
,
cachedGroups
.
count
)
await
MainActor
.
run
{
for
group
in
cachedGroups
{
...
...
@@ -175,7 +175,7 @@ class ScreenshotSimilarJSONManager: @unchecked Sendable {
await
savePendingSimilarGroups
()
}
let
allGroups
=
await
stateManager
.
getAllSimilarGroups
()
let
allGroups
=
await
loadSimilarGroups
()
//await
stateManager.getAllSimilarGroups()
await
MainActor
.
run
{
print
(
"执行完毕"
)
completionHandler
?(
allGroups
.
map
{
$0
.
assets
})
...
...
@@ -365,7 +365,7 @@ extension ScreenshotSimilarJSONManager{
private
func
savePendingSimilarGroups
()
async
{
await
stateManager
.
savePendingGroups
()
// 保存到文件
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAll
SimilarGroups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
load
SimilarGroups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
similarGroupsPath
))
}
}
...
...
@@ -389,7 +389,7 @@ extension ScreenshotSimilarJSONManager{
await
stateManager
.
deleteData
(
for
:
ids
)
// 保存到文件
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAll
SimilarGroups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
load
SimilarGroups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
similarGroupsPath
))
}
}
...
...
PhoneManager/Class/Manager/PMPhotoManager/VideoSimilarManager.swift
View file @
6a947483
...
...
@@ -89,7 +89,7 @@ class VideoSimilarJSONManager: @unchecked Sendable {
}
// 3. 通知已缓存的结果
let
cachedGroups
=
await
stateManager
.
getAllSimilarGroups
()
let
cachedGroups
=
await
loadSimilarGroups
()
//await
stateManager.getAllSimilarGroups()
await
MainActor
.
run
{
for
group
in
cachedGroups
{
progressHandler
?(
group
.
assets
)
...
...
@@ -202,7 +202,7 @@ class VideoSimilarJSONManager: @unchecked Sendable {
await
savePendingSimilarGroups
()
}
let
allGroups
=
await
stateManager
.
getAllSimilarGroups
()
let
allGroups
=
await
loadSimilarGroups
()
//await
stateManager.getAllSimilarGroups()
await
MainActor
.
run
{
completionHandler
?(
allGroups
.
map
{
$0
.
assets
})
}
...
...
@@ -577,22 +577,55 @@ class VideoSimilarJSONManager: @unchecked Sendable {
return
zip
(
hash1
,
hash2
)
.
filter
{
$0
!=
$1
}
.
count
}
private
func
createAssetModels
(
from
assets
:
[
PHAsset
])
->
[
AssetModel
]
{
return
assets
.
map
{
asset
in
let
assetSize
:
Double
if
let
resource
=
PHAssetResource
.
assetResources
(
for
:
asset
)
.
first
,
let
size
=
resource
.
value
(
forKey
:
"fileSize"
)
as?
Int64
{
assetSize
=
Double
(
size
)
}
else
{
assetSize
=
0
// private func createAssetModels(from assets: [PHAsset]) -> [AssetModel] {
// return assets.map { asset in
// let assetSize: Double
// if let resource = PHAssetResource.assetResources(for: asset).first,
// let size = resource.value(forKey: "fileSize") as? Int64 {
// assetSize = Double(size)
// } else {
// assetSize = 0
// }
//
// return AssetModel(
// localIdentifier: asset.localIdentifier,
// assetSize: assetSize,
// createDate: asset.creationDate ?? Date(),
// mediaType: 2
// )
// }
// }
private
func
createAssetModels
(
from
assets
:
[
PHAsset
])
async
->
[
AssetModel
]
{
return
await
withTaskGroup
(
of
:
AssetModel
.
self
)
{
modelGroup
in
var
models
:
[
AssetModel
]
=
[]
for
asset
in
assets
{
modelGroup
.
addTask
{
return
await
withCheckedContinuation
{
continuation
in
let
assetSize
:
Double
if
let
resource
=
PHAssetResource
.
assetResources
(
for
:
asset
)
.
first
,
let
size
=
resource
.
value
(
forKey
:
"fileSize"
)
as?
Int64
{
assetSize
=
Double
(
size
)
}
else
{
assetSize
=
0
}
let
model
=
AssetModel
(
localIdentifier
:
asset
.
localIdentifier
,
assetSize
:
assetSize
,
createDate
:
asset
.
creationDate
??
Date
(),
mediaType
:
2
)
continuation
.
resume
(
returning
:
model
)
}
}
}
return
AssetModel
(
localIdentifier
:
asset
.
localIdentifier
,
assetSize
:
assetSize
,
createDate
:
asset
.
creationDate
??
Date
(),
mediaType
:
2
)
for
await
model
in
modelGroup
{
models
.
append
(
model
)
}
return
models
}
}
...
...
@@ -629,7 +662,7 @@ extension VideoSimilarJSONManager {
private
func
savePendingSimilarGroups
()
async
{
await
stateManager
.
savePendingGroups
()
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAll
SimilarGroups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
load
SimilarGroups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
similarGroupsPath
))
}
}
...
...
@@ -639,10 +672,23 @@ extension VideoSimilarJSONManager {
await
stateManager
.
deleteData
(
for
:
ids
)
// 保存到文件
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
stateManager
.
getAll
SimilarGroups
())
{
if
let
data
=
try
?
JSONEncoder
()
.
encode
(
await
load
SimilarGroups
())
{
try
?
data
.
write
(
to
:
URL
(
fileURLWithPath
:
similarGroupsPath
))
}
}
private
func
loadSimilarGroups
()
async
->
[
SimilarGroupModel
]
{
let
groups
=
await
stateManager
.
getAllSimilarGroups
()
// 验证资源有效性
return
groups
.
map
{
group
in
var
validAssets
=
group
.
assets
validAssets
.
removeAll
{
asset
in
let
fetchResult
=
PHAsset
.
fetchAssets
(
withLocalIdentifiers
:
[
asset
.
localIdentifier
],
options
:
nil
)
return
fetchResult
.
firstObject
==
nil
}
return
SimilarGroupModel
(
groupId
:
group
.
groupId
,
assets
:
validAssets
)
}
.
filter
{
!
$0
.
assets
.
isEmpty
}
}
}
...
...
PhoneManager/Class/Page/Compress/Controller/CompressController.swift
View file @
6a947483
...
...
@@ -113,7 +113,7 @@ class CompressController : BaseViewController {
/// 获取当前页面数据
func
getViewData
(){
if
Photo
AndVideoMananger
.
mananger
.
permissionStatus
==
.
denied
{
if
Photo
Manager
.
shared
.
permissionStatus
==
.
denied
{
loadPermissView
(
CGRect
(
x
:
0
,
y
:
200
,
width
:
ScreenW
,
height
:
450
))
return
}
...
...
PhoneManager/Class/Page/Home/Controller/HomeInfoViewController.swift
View file @
6a947483
...
...
@@ -90,12 +90,10 @@ class HomeInfoViewController:BaseViewController {
// 更新免费次数
if
isAfterAdv
==
false
{
updateFreeTimes
()
}
self
.
showDeleteSuccess
(
fileCount
:
tempStringArray
.
count
,
fileSize
:
fileSize
)
PhotoManager
.
shared
.
removeDataWhenDeleteInPage
(
data
:
imgs
)
let
new
=
self
.
ids
?
.
removingElementsAndSmallGroups
(
ids
:
imgs
.
compactMap
{
$0
.
localIdentifier
})
...
...
@@ -410,7 +408,7 @@ class HomeInfoViewController:BaseViewController {
func
setDefaultPage
(){
DispatchQueue
.
main
.
async
{
if
Photo
AndVideoMananger
.
mananger
.
permissionStatus
==
.
denied
{
if
Photo
Manager
.
shared
.
permissionStatus
==
.
denied
{
self
.
loadPermissView
()
}
else
{
if
self
.
ids
?
.
count
==
0
{
...
...
PhoneManager/Class/Page/Home/Controller/HomePhotosDetailViewController.swift
View file @
6a947483
...
...
@@ -183,7 +183,7 @@ class HomePhotosDetailViewController : BaseViewController {
//设置空白页
func
setDefaultPage
(){
DispatchQueue
.
main
.
async
{
if
Photo
AndVideoMananger
.
mananger
.
permissionStatus
==
.
denied
{
if
Photo
Manager
.
shared
.
permissionStatus
==
.
denied
{
self
.
loadPermissView
()
}
else
{
if
self
.
resourceData
.
count
==
0
{
...
...
PhoneManager/Class/Page/Home/Controller/HomeVideoDetailController.swift
View file @
6a947483
...
...
@@ -571,7 +571,7 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie
func
setDefaultPage
(){
DispatchQueue
.
main
.
async
{
if
Photo
AndVideoMananger
.
mananger
.
permissionStatus
==
.
denied
{
if
Photo
Manager
.
shared
.
permissionStatus
==
.
denied
{
self
.
loadPermissView
()
}
else
{
if
self
.
resourceData
.
count
==
0
{
...
...
PhoneManager/Class/Page/Home/View/HomeCollectionViewHeader.swift
View file @
6a947483
...
...
@@ -202,14 +202,17 @@ class CustomProgressBar: UIView {
idleLabel
.
font
=
UIFont
.
systemFont
(
ofSize
:
12
)
idleLabel
.
textColor
=
UIColor
.
colorWithHex
(
hexStr
:
black6Color
)
addSubview
(
idleLabel
)
progressLayer
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
ScreenW
-
48
,
height
:
10
)
progressLayer
.
cornerRadius
=
5
progressLayer
.
masksToBounds
=
true
}
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
progressLayer
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
bounds
.
width
,
height
:
10
)
progressLayer
.
cornerRadius
=
5
progressLayer
.
masksToBounds
=
true
updateProgress
()
// updateProgress()
let
dotY
=
progressLayer
.
frame
.
maxY
+
9
let
usedDotX
=
bounds
.
minX
...
...
@@ -231,11 +234,12 @@ class CustomProgressBar: UIView {
private
func
scheduleProgressUpdate
()
{
// 取消之前的计时器
updateTimer
?
.
invalidate
()
// 设置新的计时器,延迟0.2秒更新UI
updateTimer
=
Timer
.
scheduledTimer
(
withTimeInterval
:
0.2
,
repeats
:
false
)
{
[
weak
self
]
_
in
self
?
.
updateProgress
()
}
// updateTimer?.invalidate()
// // 设置新的计时器,延迟0.2秒更新UI
// updateTimer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { [weak self] _ in
// self?.updateProgress()
// }
updateProgress
()
}
private
func
updateProgress
()
{
...
...
@@ -249,33 +253,26 @@ class CustomProgressBar: UIView {
let
chaoticRatio
=
min
(
max
(
self
.
chaoticProgress
/
total
,
0
),
1
)
// 计算实际宽度
let
usedWidth
=
self
.
bounds
.
width
*
usedRatio
let
chaoticWidth
=
self
.
bounds
.
width
*
chaoticRatio
let
usedWidth
=
(
ScreenW
-
48
)
*
usedRatio
let
chaoticWidth
=
(
ScreenW
-
48
)
*
chaoticRatio
// 设置进度条背景为白色
self
.
progressLayer
.
backgroundColor
=
self
.
idleColor
.
cgColor
// 使用CATransaction确保所有动画同步进行
CATransaction
.
begin
()
CATransaction
.
setAnimationDuration
(
0.3
)
CATransaction
.
setAnimationTimingFunction
(
CAMediaTimingFunction
(
name
:
.
easeInEaseOut
))
// 更新或创建used层
let
usedLayer
=
self
.
progressLayer
.
sublayers
?
.
first
as?
CALayer
??
CALayer
()
usedLayer
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
usedWidth
,
height
:
self
.
progressLayer
.
bounds
.
height
)
usedLayer
.
frame
=
CGRect
(
x
:
0
,
y
:
0
,
width
:
usedWidth
,
height
:
10
)
usedLayer
.
backgroundColor
=
self
.
usedColor
.
cgColor
// 更新或创建chaotic层
let
chaoticLayer
=
self
.
progressLayer
.
sublayers
?[
safe
:
1
]
as?
CALayer
??
CALayer
()
chaoticLayer
.
frame
=
CGRect
(
x
:
usedWidth
,
y
:
0
,
width
:
chaoticWidth
,
height
:
self
.
progressLayer
.
bounds
.
height
)
chaoticLayer
.
frame
=
CGRect
(
x
:
usedWidth
,
y
:
0
,
width
:
chaoticWidth
,
height
:
10
)
chaoticLayer
.
backgroundColor
=
self
.
chaoticColor
.
cgColor
// 一次性设置所有子层
if
self
.
progressLayer
.
sublayers
==
nil
{
self
.
progressLayer
.
sublayers
=
[
usedLayer
,
chaoticLayer
]
}
CATransaction
.
commit
()
}
}
...
...
PhoneManager/Class/Page/Home/View/HomeView.swift
View file @
6a947483
...
...
@@ -82,17 +82,17 @@ class HomeView:UIView {
viewModel
.
homeDataChanged
=
{[
weak
self
]
section
,
row
in
guard
let
weakSelf
=
self
else
{
return
}
DispatchQueue
.
main
.
async
{
if
let
cell
=
weakSelf
.
collectionView
.
cellForItem
(
at
:
IndexPath
(
row
:
row
,
section
:
section
))
as?
HomeTitleCollectionCell
{
// 只更新需要改变的内容
let
model
=
weakSelf
.
viewModel
.
headerGroup
[
row
]
cell
.
reloadUIWithModel
(
model
:
model
)
}
if
let
cell
=
weakSelf
.
collectionView
.
cellForItem
(
at
:
IndexPath
(
row
:
row
,
section
:
section
))
as?
HomeOtherCollectionCell
{
// 只更新需要改变的内容
let
model
=
weakSelf
.
viewModel
.
cardGroup
[
row
]
cell
.
reloadUIWithModel
(
model
:
model
)
}
//
if let cell = weakSelf.collectionView.cellForItem(at: IndexPath(row: row, section: section)) as? HomeTitleCollectionCell {
//
// 只更新需要改变的内容
//
let model = weakSelf.viewModel.headerGroup[row]
//
cell.reloadUIWithModel(model: model)
//
}
//
if let cell = weakSelf.collectionView.cellForItem(at: IndexPath(row: row, section: section)) as? HomeOtherCollectionCell {
//
// 只更新需要改变的内容
//
let model = weakSelf.viewModel.cardGroup[row]
//
cell.reloadUIWithModel(model: model)
//
}
weakSelf
.
collectionView
.
reloadData
()
weakSelf
.
homeHeader
?
.
progressBar
.
chaoticProgress
=
CGFloat
(
weakSelf
.
viewModel
.
totalSize
)
weakSelf
.
reloadHeadSize
()
}
...
...
PhoneManager/Class/Page/Home/View/VideocompressionHeadView.swift
View file @
6a947483
...
...
@@ -11,6 +11,7 @@ class VideocompressionHeadView: UIView {
@IBOutlet
weak
var
sizeL
:
UILabel
!
@IBOutlet
weak
var
sizeW
:
NSLayoutConstraint
!
override
func
awakeFromNib
()
{
super
.
awakeFromNib
()
layer
.
cornerRadius
=
8
...
...
@@ -21,15 +22,20 @@ class VideocompressionHeadView: UIView {
let
totall
=
PhotoManager
.
shared
.
getTotalSize
(
source
:
[
PhotoManager
.
shared
.
videoModels
])
let
sizeKB
:
Double
=
totall
/
2
let
sizeKB
:
Double
=
Double
(
totall
/
2000
)
if
sizeKB
<
1000
{
self
.
sizeL
.
text
=
String
(
format
:
"
(%.2lf)
KB"
,
sizeKB
)
self
.
sizeL
.
text
=
String
(
format
:
"
%.0f
KB"
,
sizeKB
)
}
else
if
sizeKB
<
(
1000
*
1000
)
&&
sizeKB
>
1000
{
self
.
sizeL
.
text
=
String
(
format
:
"
(%.2lf)
MB"
,
sizeKB
/
1000
)
self
.
sizeL
.
text
=
String
(
format
:
"
%.0f
MB"
,
sizeKB
/
1000
)
}
else
{
self
.
sizeL
.
text
=
String
(
format
:
"
(%.2lf)
GB"
,
sizeKB
/
(
1000
*
1000
))
self
.
sizeL
.
text
=
String
(
format
:
"
%.0f
GB"
,
sizeKB
/
(
1000
*
1000
))
}
let
width
=
sizeL
.
text
?
.
textWidthFromTextString
(
textHeight
:
21
,
font
:
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
semibold
))
sizeW
.
constant
=
(
width
??
30
)
+
10
}
...
...
PhoneManager/Class/Page/Home/View/VideocompressionHeadView.xib
View file @
6a947483
...
...
@@ -60,6 +60,7 @@
<freeformSimulatedSizeMetrics
key=
"simulatedDestinationMetrics"
/>
<connections>
<outlet
property=
"sizeL"
destination=
"rDm-i5-MN1"
id=
"AYR-5C-uKV"
/>
<outlet
property=
"sizeW"
destination=
"ijO-3x-MyS"
id=
"zT9-KQ-fTp"
/>
</connections>
<point
key=
"canvasLocation"
x=
"187.78625954198472"
y=
"250"
/>
</view>
...
...
PhoneManager/Class/Page/Home/ViewModel/HomeViewModel.swift
View file @
6a947483
...
...
@@ -10,19 +10,7 @@ class HomeViewModel {
func
config
(){}
var
trash
=
TrashDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
var
keep
=
GroupDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
func
reloadTrashAndKeep
(){
trash
=
TrashDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
keep
=
GroupDatabase
.
shared
.
queryAll
()
.
compactMap
{
$0
.
localIdentifier
}
filterResource
()
}
// 封面图片资源缓存
// actor CoverCacheActor {
//
...
...
@@ -114,17 +102,6 @@ class HomeViewModel {
var
reloadCellHeight
:(()
->
Void
)?
// var dupCoverImage:[AssetModel] = []
//
// var similarCoverImage:[AssetModel] = []
//
// var headCoverImages:[[AssetModel]]{
// return [
// dupCoverImage,
// similarCoverImage
// ]
// }
func
setupBindings
()
{
NotificationCenter
.
default
.
addObserver
(
forName
:
.
getBaseAssetsSuccess
,
object
:
nil
,
queue
:
nil
)
{[
weak
self
]
_
in
...
...
@@ -283,48 +260,14 @@ class HomeViewModel {
}
}
}
extension
HomeViewModel
{
// 基本资源过滤保留和垃圾桶资源
func
filterResource
(){
let
filterArray
=
trash
+
keep
let
others
=
removeAssets
(
withIdentifiers
:
filterArray
,
from
:
photoManager
.
otherModels
)
let
videos
=
removeAssets
(
withIdentifiers
:
filterArray
,
from
:
photoManager
.
videoModels
)
let
screens
=
removeAssets
(
withIdentifiers
:
filterArray
,
from
:
photoManager
.
screenShotModels
)
photoManager
.
filterOtherModels
=
others
photoManager
.
filterVideoModels
=
videos
photoManager
.
filterScreenShotModels
=
screens
let
similarPhotos
=
filterGroups
(
photoManager
.
similarModels
,
byExcludingIDs
:
filterArray
)
let
similarVideos
=
filterGroups
(
photoManager
.
similarVideoModels
,
byExcludingIDs
:
filterArray
)
let
similarShots
=
filterGroups
(
photoManager
.
similarScreenShotModels
,
byExcludingIDs
:
filterArray
)
photoManager
.
filterSimilarModels
=
similarPhotos
photoManager
.
filterSimilarVideoModels
=
similarVideos
photoManager
.
filterSimilarScreenShotModels
=
similarShots
func
reloadTrashAndKeep
(){
photoManager
.
reloadTrashAndKeep
()
reloadCellHeight
?()
}
func
removeAssets
(
withIdentifiers
identifiers
:
[
String
],
from
assets
:
[
AssetModel
])
->
[
AssetModel
]
{
let
identifierSet
=
Set
(
identifiers
)
return
assets
.
filter
{
!
identifierSet
.
contains
(
$0
.
localIdentifier
)
}
}
func
filterGroups
(
_
groups
:
[[
AssetModel
]],
byExcludingIDs
ids
:
[
String
])
->
[[
AssetModel
]]
{
let
excludeSet
=
Set
(
ids
)
return
groups
.
filter
{
group
in
// 检查子数组中是否所有元素的ID都不在排除列表中
group
.
allSatisfy
{
!
excludeSet
.
contains
(
$0
.
localIdentifier
)
}
}
func
filterResource
(){
photoManager
.
filterResource
()
}
}
PhoneManager/Class/Page/Keep/Controller/MaintaiDetailViewController.swift
View file @
6a947483
...
...
@@ -17,6 +17,10 @@ class MaintaiDetailViewController: BaseViewController {
var
scrollIndex
=
0
var
isFirstLoad
=
true
var
removeBtn
:
UIButton
!
var
isSelectAll
=
false
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
configUI
()
...
...
@@ -40,25 +44,56 @@ class MaintaiDetailViewController: BaseViewController {
weakSelf
.
maintaiTipsAlertView
.
disMiss
()
}
maintaiTipsAlertView
.
cancelBlock
=
{[
weak
self
]
in
guard
let
weakSelf
=
self
else
{
return
}
weakSelf
.
isSelectAll
=
false
}
maintaiBottomView
.
removeMaintaiBlock
=
{[
weak
self
]
in
guard
let
weakSelf
=
self
else
{
return
}
weakSelf
.
maintaiTipsAlertView
.
show
()
}
removeBtn
=
UIButton
()
removeBtn
.
setTitle
(
"Un-keep All"
,
for
:
.
normal
)
removeBtn
.
addTarget
(
self
,
action
:
#selector(
removeAll
)
,
for
:
.
touchUpInside
)
removeBtn
.
setTitleColor
(
.
black
,
for
:
.
normal
)
removeBtn
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
semibold
)
removeBtn
.
isHidden
=
true
titleView
.
addSubview
(
removeBtn
)
removeBtn
.
snp
.
makeConstraints
{
make
in
make
.
right
.
equalTo
(
-
16
)
make
.
centerY
.
equalTo
(
titleView
.
titleLabel
)
}
}
// 移除所有
@objc
func
removeAll
(){
isSelectAll
=
true
maintaiTipsAlertView
.
show
()
}
func
removeFromKeep
(){
let
ids
=
selectAsset
.
flatMap
{
$0
}
.
compactMap
{
$0
.
localIdentifier
}
if
GroupDatabase
.
shared
.
batchDelete
(
localIdentifiers
:
ids
){
getData
()
selectAsset
.
removeAll
()
if
isSelectAll
{
let
ids
=
viewModel
.
souces
.
flatMap
{
$0
}
.
compactMap
{
$0
.
localIdentifier
}
if
GroupDatabase
.
shared
.
batchDelete
(
localIdentifiers
:
ids
){
self
.
navigationController
?
.
popViewController
(
animated
:
true
)
}
isSelectAll
=
false
}
else
{
let
ids
=
selectAsset
.
flatMap
{
$0
}
.
compactMap
{
$0
.
localIdentifier
}
if
GroupDatabase
.
shared
.
batchDelete
(
localIdentifiers
:
ids
){
getData
()
selectAsset
.
removeAll
()
}
}
}
func
dealBottomView
(){
if
selectAsset
.
count
>
0
{
let
count
=
selectAsset
.
flatMap
{
$0
}
.
count
maintaiBottomView
.
numberL
.
text
=
"
\(
count
)
"
...
...
@@ -72,10 +107,16 @@ class MaintaiDetailViewController: BaseViewController {
func
getData
(){
viewModel
.
refreshData
{[
weak
self
]
in
guard
let
self
=
self
else
{
return
}
self
.
removeBtn
.
isHidden
=
viewModel
.
souces
.
count
==
0
self
.
tableView
.
reloadData
()
if
self
.
isFirstLoad
{
self
.
tableView
.
scrollToRow
(
at
:
IndexPath
.
init
(
row
:
self
.
scrollIndex
,
section
:
0
),
at
:
.
middle
,
animated
:
true
)
self
.
tableView
.
layoutIfNeeded
(
)
self
.
isFirstLoad
=
false
// 异步执行滚动,确保布局已稳定
DispatchQueue
.
main
.
async
{
self
.
tableView
.
scrollToRow
(
at
:
IndexPath
.
init
(
row
:
self
.
scrollIndex
,
section
:
0
),
at
:
.
middle
,
animated
:
true
)
}
}
}
}
...
...
@@ -123,7 +164,7 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{
func
tableView
(
_
tableView
:
UITableView
,
cellForRowAt
indexPath
:
IndexPath
)
->
UITableViewCell
{
if
viewModel
.
souces
[
indexPath
.
row
]
.
first
?
.
mediaType
==
1
,
viewModel
.
souces
[
indexPath
.
row
]
.
count
>
1
{
if
viewModel
.
souces
[
indexPath
.
row
]
.
first
?
.
mediaType
==
1
{
let
cell
=
tableView
.
dequeueReusableCell
(
withIdentifier
:
"MaintaiDetailTableViewCell"
)
as!
MaintaiDetailTableViewCell
...
...
PhoneManager/Class/Page/Keep/Controller/MaintainViewListController.swift
View file @
6a947483
...
...
@@ -15,6 +15,9 @@ class MaintainViewListController: BaseViewController {
var
viewModel
:
MaintaiViewModel
=
MaintaiViewModel
()
var
removeBtn
:
UIButton
!
var
isSelectAll
=
false
override
func
viewDidLoad
()
{
super
.
viewDidLoad
()
...
...
@@ -37,22 +40,54 @@ class MaintainViewListController: BaseViewController {
weakSelf
.
maintaiTipsAlertView
.
disMiss
()
}
maintaiTipsAlertView
.
cancelBlock
=
{[
weak
self
]
in
guard
let
weakSelf
=
self
else
{
return
}
weakSelf
.
isSelectAll
=
false
}
maintaiBottomView
.
removeMaintaiBlock
=
{[
weak
self
]
in
guard
let
weakSelf
=
self
else
{
return
}
weakSelf
.
maintaiTipsAlertView
.
show
()
}
removeBtn
=
UIButton
()
removeBtn
.
setTitle
(
"Un-keep All"
,
for
:
.
normal
)
removeBtn
.
addTarget
(
self
,
action
:
#selector(
removeAll
)
,
for
:
.
touchUpInside
)
removeBtn
.
setTitleColor
(
.
black
,
for
:
.
normal
)
removeBtn
.
titleLabel
?
.
font
=
UIFont
.
systemFont
(
ofSize
:
14
,
weight
:
.
semibold
)
removeBtn
.
isHidden
=
true
titleView
.
addSubview
(
removeBtn
)
removeBtn
.
snp
.
makeConstraints
{
make
in
make
.
right
.
equalTo
(
-
16
)
make
.
centerY
.
equalTo
(
titleView
.
titleLabel
)
}
}
// 移除所有
@objc
func
removeAll
(){
isSelectAll
=
true
maintaiTipsAlertView
.
show
()
}
func
removeFromKeep
(){
let
ids
=
selectAsset
.
flatMap
{
$0
}
.
compactMap
{
$0
.
localIdentifier
}
if
isSelectAll
{
let
ids
=
viewModel
.
souces
.
flatMap
{
$0
}
.
compactMap
{
$0
.
localIdentifier
}
if
GroupDatabase
.
shared
.
batchDelete
(
localIdentifiers
:
ids
){
getData
()
selectAsset
.
removeAll
()
}
isSelectAll
=
false
}
else
{
let
ids
=
selectAsset
.
flatMap
{
$0
}
.
compactMap
{
$0
.
localIdentifier
}
if
GroupDatabase
.
shared
.
batchDelete
(
localIdentifiers
:
ids
){
getData
()
selectAsset
.
removeAll
()
if
GroupDatabase
.
shared
.
batchDelete
(
localIdentifiers
:
ids
){
getData
()
selectAsset
.
removeAll
()
}
}
}
func
getData
(){
...
...
@@ -63,7 +98,7 @@ class MaintainViewListController: BaseViewController {
}
else
{
self
.
maintaiEmptyView
.
removeFromSuperview
()
}
self
.
removeBtn
.
isHidden
=
viewModel
.
souces
.
count
==
0
self
.
collectionView
.
reloadData
()
}
}
...
...
PhoneManager/Class/Page/Keep/View/MaintaiDetailTableViewCell.swift
View file @
6a947483
...
...
@@ -39,7 +39,6 @@ class MaintaiDetailTableViewCell: UITableViewCell {
}
}
func
configMain
(){
let
layout
=
UICollectionViewFlowLayout
()
...
...
@@ -47,6 +46,7 @@ class MaintaiDetailTableViewCell: UITableViewCell {
layout
.
minimumLineSpacing
=
0
layout
.
minimumInteritemSpacing
=
0
layout
.
scrollDirection
=
.
horizontal
// layout.sectionInset = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
mainCollectionView
.
setCollectionViewLayout
(
layout
,
animated
:
false
)
mainCollectionView
.
dataSource
=
self
...
...
@@ -121,11 +121,7 @@ extension MaintaiDetailTableViewCell:UICollectionViewDelegate,UICollectionViewDa
selectCallBack
?(
selectAsset
)
}
}
extension
MaintaiDetailTableViewCell
:
UIScrollViewDelegate
{
...
...
@@ -173,6 +169,15 @@ extension MaintaiDetailTableViewCell:UIScrollViewDelegate{
}
}
// func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
// if scrollView == mainCollectionView{
// let currentOffset = targetContentOffset.pointee.x
// let page = round(currentOffset / bigW) // 计算目标页(以 Cell 宽度为基准)
// targetContentOffset.pointee.x = page * bigW // 强制对齐到 Cell 边界
// Print("强制对齐",targetContentOffset.pointee.x )
// }
// }
func
setPageOffetX
(
offsetX
:
CGFloat
){
print
(
"----结束滑动----小图"
)
Print
(
"小图滑动距离"
,
offsetX
)
...
...
PhoneManager/Class/Page/Keep/View/MaintaiDetialVideoCell.swift
View file @
6a947483
...
...
@@ -10,12 +10,18 @@ import AVKit
class
MaintaiDetialVideoCell
:
UITableViewCell
{
private
var
player
:
AVPlayer
?
private
var
playerLayer
:
AVPlayerLayer
?
//
private var player: AVPlayer?
//
private var playerLayer: AVPlayerLayer?
var
selectBtn
:
UIButton
!
var
selectChangeBlock
:(()
->
Void
)?
// var videoPath:String?{
// didSet{
// setPlayerInfo()
// }
// }
override
func
awakeFromNib
()
{
super
.
awakeFromNib
()
setupPlayer
()
...
...
@@ -31,22 +37,25 @@ class MaintaiDetialVideoCell: UITableViewCell {
contentView
.
bringSubviewToFront
(
selectBtn
)
selectBtn
.
addTarget
(
self
,
action
:
#selector(
selectChange
)
,
for
:
.
touchUpInside
)
selectBtn
.
snp
.
makeConstraints
{
make
in
make
.
right
.
bottom
.
equalTo
(
0
)
make
.
right
.
equalTo
(
-
15
)
make
.
bottom
.
equalTo
(
-
10
)
make
.
size
.
equalTo
(
30
)
}
}
private
func
setupPlayer
()
{
// 创建播放器层
playerLayer
=
AVPlayerLayer
()
playerLayer
?
.
videoGravity
=
.
resizeAspect
contentView
.
layer
.
addSublayer
(
playerLayer
!
)
//
playerLayer = AVPlayerLayer()
//
playerLayer?.videoGravity = .resizeAspect
contentView
.
layer
.
addSublayer
(
playerLayer
)
}
override
func
layoutSubviews
()
{
super
.
layoutSubviews
()
// 设置播放器层的frame
playerLayer
?
.
frame
=
CGRect
(
x
:
0
,
y
:
10
,
width
:
contentView
.
width
,
height
:
contentView
.
height
-
20
)
playerLayer
.
frame
=
CGRect
(
x
:
15
,
y
:
10
,
width
:
contentView
.
width
-
30
,
height
:
contentView
.
height
-
20
)
playerLayer
.
cornerRadius
=
15
playerLayer
.
masksToBounds
=
true
}
var
model
:
AssetModel
?{
...
...
@@ -62,46 +71,72 @@ class MaintaiDetialVideoCell: UITableViewCell {
}
}
lazy
var
videoPlayer
:
AVPlayer
=
{
let
palyer
=
AVPlayer
.
init
()
palyer
.
volume
=
0
return
palyer
}()
lazy
var
playerLayer
:
AVPlayerLayer
=
{
let
playerLayer
=
AVPlayerLayer
.
init
(
player
:
videoPlayer
)
playerLayer
.
backgroundColor
=
UIColor
.
black
.
cgColor
return
playerLayer
}()
func
configure
(
with
videoURL
:
URL
?)
{
guard
let
videoURL
=
videoURL
else
{
player
?
.
pause
()
player
=
nil
videoPlayer
.
pause
()
return
}
// 创建播放器项
let
playerItem
=
AVPlayerItem
(
url
:
videoURL
)
// 创建播放器
player
=
AVPlayer
(
playerItem
:
playerItem
)
playerLayer
?
.
player
=
player
let
item
=
AVPlayerItem
.
init
(
url
:
videoURL
)
// 设置静音
player
?
.
volume
=
0
videoPlayer
.
replaceCurrentItem
(
with
:
item
)
// 播放视频
player
?
.
play
()
videoPlayer
.
play
()
// // 创建播放器项
// let playerItem = AVPlayerItem(url: videoURL)
//
// // 创建播放器
// player = AVPlayer(playerItem: playerItem)
// playerLayer?.player = player
//
// // 设置静音
// player?.volume = 0
//
// // 播放视频
// player?.play()
//
// 添加播放完成的观察者
NotificationCenter
.
default
.
addObserver
(
self
,
selector
:
#selector(
playerDidFinishPlaying
)
,
name
:
.
AVPlayerItemDidPlayToEndTime
,
object
:
playerI
tem
)
object
:
i
tem
)
}
//
@objc
private
func
playerDidFinishPlaying
()
{
// 播放结束后不做任何操作,因为只需要播放一次
player
?
.
pause
()
player
?
.
seek
(
to
:
.
zero
)
// // 播放结束后不做任何操作,因为只需要播放一次
// player?.pause()
// player?.seek(to: .zero)
//playerLayer.player?.seek(to: .zero)
videoPlayer
.
seek
(
to
:
.
zero
)
videoPlayer
.
play
()
}
override
func
prepareForReuse
()
{
super
.
prepareForReuse
()
// 清理播放器
player
?
.
pause
()
player
=
nil
NotificationCenter
.
default
.
removeObserver
(
self
)
}
//
//
override func prepareForReuse() {
//
super.prepareForReuse()
//
// 清理播放器
//
player?.pause()
//
player = nil
//
NotificationCenter.default.removeObserver(self)
//
}
//
@objc
func
selectChange
(){
selectChangeBlock
?()
...
...
PhoneManager/Class/Page/Keep/View/MaintaiTipsAlertView.swift
View file @
6a947483
...
...
@@ -10,6 +10,8 @@ import UIKit
class
MaintaiTipsAlertView
:
UIView
{
var
confirmBlock
:(()
->
Void
)?
var
cancelBlock
:(()
->
Void
)?
override
func
awakeFromNib
()
{
super
.
awakeFromNib
()
...
...
@@ -25,6 +27,7 @@ class MaintaiTipsAlertView: UIView {
}
func
disMiss
(){
cancelBlock
?()
self
.
removeFromSuperview
()
}
...
...
PhoneManager/Class/Tool/Class/PhotoAndVideoMananger/PhotoAndVideoMananger.swift
View file @
6a947483
...
...
@@ -93,7 +93,7 @@ class PhotoAndVideoMananger {
class
func
getPrivacy
(
suc
:
@escaping
callBack
<
Any
>
=
{
text
in
})
{
PHPhotoLibrary
.
requestAuthorization
{
status
in
Photo
AndVideoMananger
.
mananger
.
permissionStatus
=
status
Photo
Manager
.
shared
.
permissionStatus
=
status
switch
status
{
case
.
authorized
:
// 用户授权访问照片库,可以继续操作
...
...
PhoneManager/Class/Tool/Extension.swift/NSString+Extension.swift
View file @
6a947483
...
...
@@ -138,6 +138,19 @@ extension String {
.
replacingOccurrences
(
of
:
"
\r
"
,
with
:
""
)
return
cleaned
}
/// 动态计算宽度
/// - Parameters:
/// - textWidth: <#textWidth description#>
/// - font: <#font description#>
/// - isBold: <#isBold description#>
/// - Returns: <#description#>
public
func
textWidthFromTextString
(
textHeight
:
CGFloat
,
font
:
UIFont
)
->
CGFloat
{
let
dict
:
NSDictionary
=
NSDictionary
(
object
:
font
,
forKey
:
NSAttributedString
.
Key
.
font
as
NSCopying
)
let
rect
:
CGRect
=
(
self
as
NSString
)
.
boundingRect
(
with
:
CGSize
(
width
:
CGFloat
(
MAXFLOAT
),
height
:
textHeight
),
options
:
[
NSStringDrawingOptions
.
truncatesLastVisibleLine
,
NSStringDrawingOptions
.
usesFontLeading
,
NSStringDrawingOptions
.
usesLineFragmentOrigin
],
attributes
:
dict
as?
[
NSAttributedString
.
Key
:
Any
]
,
context
:
nil
)
return
rect
.
size
.
width
}
}
...
...
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