Commit 3bd07415 authored by shenyong's avatar shenyong

Merge branch 'develop_0409' into Adv_NewClean

# Conflicts:
#	PhoneManager/Class/Database/TrashDatabase.swift
parents 1a9ff85e ba9a2776
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
04197BE82DD1B9DB009FE068 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915D2D9D68AD00055CEB /* WidgetKit.framework */; };
04197BE92DD1B9DB009FE068 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915F2D9D68AD00055CEB /* SwiftUI.framework */; };
04197BF42DD1B9DC009FE068 /* LockSreenExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 04197BE72DD1B9DB009FE068 /* LockSreenExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0496DEF32D9E3F58005B2834 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915D2D9D68AD00055CEB /* WidgetKit.framework */; }; 0496DEF32D9E3F58005B2834 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915D2D9D68AD00055CEB /* WidgetKit.framework */; };
0496DEF42D9E3F58005B2834 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915F2D9D68AD00055CEB /* SwiftUI.framework */; }; 0496DEF42D9E3F58005B2834 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04BD915F2D9D68AD00055CEB /* SwiftUI.framework */; };
0496DEFF2D9E3F59005B2834 /* widgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0496DEF22D9E3F57005B2834 /* widgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 0496DEFF2D9E3F59005B2834 /* widgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0496DEF22D9E3F57005B2834 /* widgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
...@@ -23,13 +20,6 @@ ...@@ -23,13 +20,6 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
04197BF22DD1B9DC009FE068 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = EB388E532D8A61A800629B0D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 04197BE62DD1B9DB009FE068;
remoteInfo = LockSreenExtension;
};
0496DEFD2D9E3F59005B2834 /* PBXContainerItemProxy */ = { 0496DEFD2D9E3F59005B2834 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = EB388E532D8A61A800629B0D /* Project object */; containerPortal = EB388E532D8A61A800629B0D /* Project object */;
...@@ -65,7 +55,6 @@ ...@@ -65,7 +55,6 @@
files = ( files = (
0496DEFF2D9E3F59005B2834 /* widgetExtension.appex in Embed Foundation Extensions */, 0496DEFF2D9E3F59005B2834 /* widgetExtension.appex in Embed Foundation Extensions */,
04CF31772DA7E790001C87CA /* ChargeShow.appex in Embed Foundation Extensions */, 04CF31772DA7E790001C87CA /* ChargeShow.appex in Embed Foundation Extensions */,
04197BF42DD1B9DC009FE068 /* LockSreenExtension.appex in Embed Foundation Extensions */,
); );
name = "Embed Foundation Extensions"; name = "Embed Foundation Extensions";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
...@@ -73,8 +62,6 @@ ...@@ -73,8 +62,6 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
04197BE72DD1B9DB009FE068 /* LockSreenExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = LockSreenExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
04197BF92DD1BA4C009FE068 /* LockSreenExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LockSreenExtension.entitlements; sourceTree = "<group>"; };
0496DEF22D9E3F57005B2834 /* widgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = widgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 0496DEF22D9E3F57005B2834 /* widgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = widgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
0496DF042D9E3FA7005B2834 /* widgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = widgetExtension.entitlements; sourceTree = "<group>"; }; 0496DF042D9E3FA7005B2834 /* widgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = widgetExtension.entitlements; sourceTree = "<group>"; };
04BBB4E52DC0748F00D7E3AB /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; 04BBB4E52DC0748F00D7E3AB /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
...@@ -92,13 +79,6 @@ ...@@ -92,13 +79,6 @@
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
04197BF82DD1B9DC009FE068 /* Exceptions for "LockSreen" folder in "LockSreenExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 04197BE62DD1B9DB009FE068 /* LockSreenExtension */;
};
041E22DC2DCCD63B0028E917 /* Exceptions for "widget" folder in "PhoneManager" target */ = { 041E22DC2DCCD63B0028E917 /* Exceptions for "widget" folder in "PhoneManager" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet; isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = ( membershipExceptions = (
...@@ -130,14 +110,6 @@ ...@@ -130,14 +110,6 @@
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFileSystemSynchronizedRootGroup section */
04197BEA2DD1B9DB009FE068 /* LockSreen */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
04197BF82DD1B9DC009FE068 /* Exceptions for "LockSreen" folder in "LockSreenExtension" target */,
);
path = LockSreen;
sourceTree = "<group>";
};
0496DEF52D9E3F58005B2834 /* widget */ = { 0496DEF52D9E3F58005B2834 /* widget */ = {
isa = PBXFileSystemSynchronizedRootGroup; isa = PBXFileSystemSynchronizedRootGroup;
exceptions = ( exceptions = (
...@@ -166,15 +138,6 @@ ...@@ -166,15 +138,6 @@
/* End PBXFileSystemSynchronizedRootGroup section */ /* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
04197BE42DD1B9DB009FE068 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
04197BE92DD1B9DB009FE068 /* SwiftUI.framework in Frameworks */,
04197BE82DD1B9DB009FE068 /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0496DEEF2D9E3F57005B2834 /* Frameworks */ = { 0496DEEF2D9E3F57005B2834 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -231,13 +194,11 @@ ...@@ -231,13 +194,11 @@
EB388E522D8A61A800629B0D = { EB388E522D8A61A800629B0D = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04197BF92DD1BA4C009FE068 /* LockSreenExtension.entitlements */,
04CF317C2DA7E7BE001C87CA /* Intents.intentdefinition */, 04CF317C2DA7E7BE001C87CA /* Intents.intentdefinition */,
0496DF042D9E3FA7005B2834 /* widgetExtension.entitlements */, 0496DF042D9E3FA7005B2834 /* widgetExtension.entitlements */,
EB388E5D2D8A61A800629B0D /* PhoneManager */, EB388E5D2D8A61A800629B0D /* PhoneManager */,
0496DEF52D9E3F58005B2834 /* widget */, 0496DEF52D9E3F58005B2834 /* widget */,
04CF31712DA7E78F001C87CA /* ChargeShow */, 04CF31712DA7E78F001C87CA /* ChargeShow */,
04197BEA2DD1B9DB009FE068 /* LockSreen */,
EB388E5C2D8A61A800629B0D /* Products */, EB388E5C2D8A61A800629B0D /* Products */,
CB2ACD1E9442B4500087E831 /* Pods */, CB2ACD1E9442B4500087E831 /* Pods */,
27ECDADD9059AB5043B8E1E9 /* Frameworks */, 27ECDADD9059AB5043B8E1E9 /* Frameworks */,
...@@ -250,7 +211,6 @@ ...@@ -250,7 +211,6 @@
EB388E5B2D8A61A800629B0D /* PhoneManager.app */, EB388E5B2D8A61A800629B0D /* PhoneManager.app */,
0496DEF22D9E3F57005B2834 /* widgetExtension.appex */, 0496DEF22D9E3F57005B2834 /* widgetExtension.appex */,
04CF316F2DA7E78F001C87CA /* ChargeShow.appex */, 04CF316F2DA7E78F001C87CA /* ChargeShow.appex */,
04197BE72DD1B9DB009FE068 /* LockSreenExtension.appex */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -258,28 +218,6 @@ ...@@ -258,28 +218,6 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
04197BE62DD1B9DB009FE068 /* LockSreenExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 04197BF52DD1B9DC009FE068 /* Build configuration list for PBXNativeTarget "LockSreenExtension" */;
buildPhases = (
04197BE32DD1B9DB009FE068 /* Sources */,
04197BE42DD1B9DB009FE068 /* Frameworks */,
04197BE52DD1B9DB009FE068 /* Resources */,
);
buildRules = (
);
dependencies = (
);
fileSystemSynchronizedGroups = (
04197BEA2DD1B9DB009FE068 /* LockSreen */,
);
name = LockSreenExtension;
packageProductDependencies = (
);
productName = LockSreenExtension;
productReference = 04197BE72DD1B9DB009FE068 /* LockSreenExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
0496DEF12D9E3F57005B2834 /* widgetExtension */ = { 0496DEF12D9E3F57005B2834 /* widgetExtension */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 0496DF022D9E3F59005B2834 /* Build configuration list for PBXNativeTarget "widgetExtension" */; buildConfigurationList = 0496DF022D9E3F59005B2834 /* Build configuration list for PBXNativeTarget "widgetExtension" */;
...@@ -338,7 +276,6 @@ ...@@ -338,7 +276,6 @@
dependencies = ( dependencies = (
0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */, 0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */,
04CF31762DA7E78F001C87CA /* PBXTargetDependency */, 04CF31762DA7E78F001C87CA /* PBXTargetDependency */,
04197BF32DD1B9DC009FE068 /* PBXTargetDependency */,
); );
fileSystemSynchronizedGroups = ( fileSystemSynchronizedGroups = (
EB388E5D2D8A61A800629B0D /* PhoneManager */, EB388E5D2D8A61A800629B0D /* PhoneManager */,
...@@ -358,9 +295,6 @@ ...@@ -358,9 +295,6 @@
LastSwiftUpdateCheck = 1620; LastSwiftUpdateCheck = 1620;
LastUpgradeCheck = 1620; LastUpgradeCheck = 1620;
TargetAttributes = { TargetAttributes = {
04197BE62DD1B9DB009FE068 = {
CreatedOnToolsVersion = 16.2;
};
0496DEF12D9E3F57005B2834 = { 0496DEF12D9E3F57005B2834 = {
CreatedOnToolsVersion = 16.2; CreatedOnToolsVersion = 16.2;
}; };
...@@ -393,19 +327,11 @@ ...@@ -393,19 +327,11 @@
EB388E5A2D8A61A800629B0D /* PhoneManager */, EB388E5A2D8A61A800629B0D /* PhoneManager */,
0496DEF12D9E3F57005B2834 /* widgetExtension */, 0496DEF12D9E3F57005B2834 /* widgetExtension */,
04CF316E2DA7E78F001C87CA /* ChargeShow */, 04CF316E2DA7E78F001C87CA /* ChargeShow */,
04197BE62DD1B9DB009FE068 /* LockSreenExtension */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
04197BE52DD1B9DB009FE068 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0496DEF02D9E3F57005B2834 /* Resources */ = { 0496DEF02D9E3F57005B2834 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -489,13 +415,6 @@ ...@@ -489,13 +415,6 @@
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
04197BE32DD1B9DB009FE068 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0496DEEE2D9E3F57005B2834 /* Sources */ = { 0496DEEE2D9E3F57005B2834 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -522,11 +441,6 @@ ...@@ -522,11 +441,6 @@
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
04197BF32DD1B9DC009FE068 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 04197BE62DD1B9DB009FE068 /* LockSreenExtension */;
targetProxy = 04197BF22DD1B9DC009FE068 /* PBXContainerItemProxy */;
};
0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */ = { 0496DEFE2D9E3F59005B2834 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 0496DEF12D9E3F57005B2834 /* widgetExtension */; target = 0496DEF12D9E3F57005B2834 /* widgetExtension */;
...@@ -540,72 +454,6 @@ ...@@ -540,72 +454,6 @@
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
04197BF62DD1B9DC009FE068 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = LockSreenExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = LockSreen/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = LockSreen;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.app.phonemanager.lockSreenWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
04197BF72DD1B9DC009FE068 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = LockSreenExtension.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = LockSreen/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = LockSreen;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.app.phonemanager.lockSreenWidget;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
0496DF002D9E3F59005B2834 /* Debug */ = { 0496DF002D9E3F59005B2834 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
...@@ -951,15 +799,6 @@ ...@@ -951,15 +799,6 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
04197BF52DD1B9DC009FE068 /* Build configuration list for PBXNativeTarget "LockSreenExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
04197BF62DD1B9DC009FE068 /* Debug */,
04197BF72DD1B9DC009FE068 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0496DF022D9E3F59005B2834 /* Build configuration list for PBXNativeTarget "widgetExtension" */ = { 0496DF022D9E3F59005B2834 /* Build configuration list for PBXNativeTarget "widgetExtension" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
......
...@@ -50,6 +50,40 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -50,6 +50,40 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return true return true
} }
func applicationWillTerminate(_ application: UIApplication) {
// 保存单利中所有垃圾桶的数据
saveDataToTrashDB(data: Singleton.shared.trashData)
// 保存单利中所有垃圾桶的数据
saveDataToKeepListhDB(data: Singleton.shared.keepList)
}
func saveDataToTrashDB(data : [TrashTypeEnum : [AssetModel]]){
for (key,value) in data {
for item in value {
let success = TrashDatabase.shared.insert(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: key.dbType)
if !success {
Print("保存单利数据到数据库失败")
}
}
}
Singleton.shared.trashData = [:]
}
func saveDataToKeepListhDB(data : [TrashTypeEnum : [AssetModel]]){
for (key,value) in data {
let uniqueId = UUID().uuidString
for item in value {
let success = GroupDatabase.shared.insert(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: key.dbType,groupId: uniqueId)
if !success {
Print("保存保留列表数据失败")
}
}
}
Singleton.shared.keepList = [:]
}
func applicationDidBecomeActive(_ application: UIApplication) { func applicationDidBecomeActive(_ application: UIApplication) {
NotificationCenter.default.post(name: Notification.Name("applicationDidBecomeActive"), object: nil) NotificationCenter.default.post(name: Notification.Name("applicationDidBecomeActive"), object: nil)
......
{
"images" : [
{
"filename" : "Frame.png",
"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" : [
{
"filename" : "Frame.png",
"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" : [
{
"filename" : "Group_1171275102.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group_1171275102@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group_1171275102@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -254,7 +254,8 @@ class TrashDatabase { ...@@ -254,7 +254,8 @@ class TrashDatabase {
sqlite3_exec(db, rollbackTransaction, nil, nil, nil) sqlite3_exec(db, rollbackTransaction, nil, nil, nil)
return false return false
} }
deinit { deinit {
sqlite3_close(db) sqlite3_close(db)
} }
......
...@@ -26,7 +26,7 @@ class ChargeGuideController : BaseViewController,UIScrollViewDelegate,UINavigati ...@@ -26,7 +26,7 @@ class ChargeGuideController : BaseViewController,UIScrollViewDelegate,UINavigati
"Scroll the page and select Charger section", "Scroll the page and select Charger section",
"Select 'ls Connected' and 'Run lmmediately',then tap on Next", "Select 'ls Connected' and 'Run lmmediately',then tap on Next",
"Tap on New Blank Automation to connect the app", "Tap on New Blank Automation to connect the app",
"Type 'Cleanup' & select Run Charging Animation and tap on Done!" "Type 'PhoneManager' & select Run Charging Animation and tap on Done!"
] ]
let numberOfPages = 7 let numberOfPages = 7
......
...@@ -17,6 +17,8 @@ typealias CompressSelectCellCallback = (AssetModel,Bool)->Void ...@@ -17,6 +17,8 @@ typealias CompressSelectCellCallback = (AssetModel,Bool)->Void
class CompressSelectCell : UICollectionViewCell { class CompressSelectCell : UICollectionViewCell {
var indexPath : IndexPath?
var callBack : CompressSelectCellCallback = {model,choose in} var callBack : CompressSelectCellCallback = {model,choose in}
var currentMediaType : CompressType = .compressPhoto { var currentMediaType : CompressType = .compressPhoto {
...@@ -225,23 +227,31 @@ class CompressSelectCell : UICollectionViewCell { ...@@ -225,23 +227,31 @@ class CompressSelectCell : UICollectionViewCell {
@objc func imageClick(){ @objc func imageClick(){
if self.currentMediaType == .compressPhoto { if self.currentMediaType == .compressPhoto {
// 点击之后跳转详情页面 // 点击之后跳转详情页面
if let tempModel = self.model { if let tempModel = self.model {
let vc = PMShowImgVideoController() let vc = PMShowImgVideoController()
vc.state = .similarPhotos vc.state = .similarPhotos
vc.currentIdx = 0 vc.currentIdx = 0
vc.oldPageIndexPath = indexPath
let dataSource = ImageSeletedCollectionItem() let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = true dataSource.isSeleted = self.choose
dataSource.id = tempModel dataSource.id = tempModel
// 获取image // 获取image
dataSource.image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: tempModel.localIdentifier) dataSource.image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: tempModel.localIdentifier)
vc.homeDataSource = [dataSource] vc.homeDataSource = [dataSource]
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
if let data = data{
if let item = data.first{
self.choose = item.isSeleted ?? false
}
}
}
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true) self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
} }
}else{ }else{
...@@ -253,12 +263,21 @@ class CompressSelectCell : UICollectionViewCell { ...@@ -253,12 +263,21 @@ class CompressSelectCell : UICollectionViewCell {
let vc = PMShowImgVideoController() let vc = PMShowImgVideoController()
vc.state = .similarVideos vc.state = .similarVideos
vc.currentIdx = 0 vc.currentIdx = 0
vc.oldPageIndexPath = self.indexPath
let dataSource = ImageSeletedCollectionItem() let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = true dataSource.isSeleted = self.choose
dataSource.id = tempModel dataSource.id = tempModel
dataSource.image = image dataSource.image = image
// 表示这个是视频 // 表示这个是视频
vc.homeDataSource = [dataSource] vc.homeDataSource = [dataSource]
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
if let data = data{
if let item = data.first{
self.choose = item.isSeleted ?? false
}
}
}
vc.getVideoURLFromLocalIdentifier(localIdentifier: tempModel.localIdentifier) { url, error in vc.getVideoURLFromLocalIdentifier(localIdentifier: tempModel.localIdentifier) { url, error in
if url != nil{ if url != nil{
DispatchQueue.main.async { DispatchQueue.main.async {
......
...@@ -19,8 +19,16 @@ class CompressCompletedViewController : BaseViewController{ ...@@ -19,8 +19,16 @@ class CompressCompletedViewController : BaseViewController{
var currentMediaType : CompressType = .compressPhoto var currentMediaType : CompressType = .compressPhoto
lazy var bacView : UIView = {
let view = UIView()
view.layer.cornerRadius = 115
view.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
return view
}()
lazy var animationView : LottieAnimationView = { lazy var animationView : LottieAnimationView = {
let animationView = LottieAnimationView(name: "CompressCompletedLight") let animationView = LottieAnimationView(name: "iOS压缩完成")
animationView.layer.cornerRadius = 12 animationView.layer.cornerRadius = 12
animationView.backgroundColor = .clear animationView.backgroundColor = .clear
animationView.loopMode = .loop animationView.loopMode = .loop
...@@ -153,6 +161,7 @@ class CompressCompletedViewController : BaseViewController{ ...@@ -153,6 +161,7 @@ class CompressCompletedViewController : BaseViewController{
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1) self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.titleView.isHidden = true self.titleView.isHidden = true
self.view.addSubview(self.bacView)
self.view.addSubview(self.animationView) self.view.addSubview(self.animationView)
self.view.addSubview(self.tipLabel) self.view.addSubview(self.tipLabel)
self.view.addSubview(self.detailTiplabel) self.view.addSubview(self.detailTiplabel)
...@@ -168,7 +177,11 @@ class CompressCompletedViewController : BaseViewController{ ...@@ -168,7 +177,11 @@ class CompressCompletedViewController : BaseViewController{
self.infoView.addSubview(self.finalTipLabel) self.infoView.addSubview(self.finalTipLabel)
self.view.addSubview(self.completedButton) self.view.addSubview(self.completedButton)
self.bacView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230)
make.centerX.equalToSuperview()
}
self.animationView.snp.makeConstraints { make in self.animationView.snp.makeConstraints { make in
make.top.equalTo(statusBarHeight + 60) make.top.equalTo(statusBarHeight + 60)
make.width.height.equalTo(230) make.width.height.equalTo(230)
...@@ -366,7 +379,7 @@ class CompressCompletedViewController : BaseViewController{ ...@@ -366,7 +379,7 @@ class CompressCompletedViewController : BaseViewController{
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setUI() setUI()
self.animationView.play(fromProgress: 0, toProgress: 1,loopMode: .playOnce) self.animationView.play(fromProgress: 0, toProgress: 1,loopMode: .loop)
} }
......
...@@ -174,6 +174,7 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo ...@@ -174,6 +174,7 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CompressSelectCell", for: indexPath) as! CompressSelectCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CompressSelectCell", for: indexPath) as! CompressSelectCell
cell.currentMediaType = self.currentResourceType cell.currentMediaType = self.currentResourceType
cell.model = self.resourceData[indexPath.row] cell.model = self.resourceData[indexPath.row]
cell.indexPath = indexPath
if self.selectedModel.count == 0 { if self.selectedModel.count == 0 {
cell.choose = false cell.choose = false
} }
......
//
// VideoViewController.swift
// PhoneManager
//
// Created by edy on 2025/5/13.
//
import Foundation
import AVKit
import MediaPlayer
class VideoViewController: UIViewController {
var url : URL?
var isAutoPlay : Bool = true
// 系统播放器控制器
let playerViewController = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
setupPlayer()
}
func setupPlayer() {
// 1. 创建播放器
if let url = self.url {
let player = AVPlayer(url: url)
// 2. 配置播放器控制器
playerViewController.player = player
playerViewController.delegate = self
playerViewController.showsPlaybackControls = true
// 3. 添加到当前视图
addChild(playerViewController)
view.addSubview(playerViewController.view)
playerViewController.view.frame = view.bounds
playerViewController.didMove(toParent: self)
// 4. 自动播放
if self.isAutoPlay {
player.play()
}
}
}
}
// MARK: - AVPlayerViewControllerDelegate
extension VideoViewController: AVPlayerViewControllerDelegate {
// 处理全屏切换
func playerViewController(_ playerViewController: AVPlayerViewController,
willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
}
func playerViewController(_ playerViewController: AVPlayerViewController,
willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
}
}
...@@ -308,19 +308,15 @@ extension HomePhotosDetailViewController:WaterfallMutiSectionDelegate,UICollecti ...@@ -308,19 +308,15 @@ extension HomePhotosDetailViewController:WaterfallMutiSectionDelegate,UICollecti
cell.cellCallBack = {[weak self] ident,order in cell.cellCallBack = {[weak self] ident,order in
guard let self else {return} guard let self else {return}
DispatchQueue.main.async { DispatchQueue.main.async {
// 点击之后跳转详情页面 // 点击之后跳转详情页面
let vc = PMShowImgVideoController() if self.mediaType == .screenshots {
vc.state = .similarPhotos let vc = PhotoRemoveViewController(data: self.resourceData,currentIndex: indexPath.row,mediaType: .shot)
vc.currentIdx = 0 self.navigationController?.pushViewController(vc, animated: true)
let dataSource = ImageSeletedCollectionItem() }
dataSource.isSeleted = true if self.mediaType == .Other {
dataSource.id = ident let vc = PhotoRemoveViewController(data: self.resourceData,currentIndex: indexPath.row,mediaType: .other)
// 获取image self.navigationController?.pushViewController(vc, animated: true)
dataSource.image = PhotoAndVideoMananger.mananger.getImageFromAssetID(id: ident.localIdentifier) }
vc.homeDataSource = [dataSource]
self.navigationController?.pushViewController(vc, animated: true)
} }
} }
cell.clickCallBack = {[weak self] click,order in cell.clickCallBack = {[weak self] click,order in
......
...@@ -253,32 +253,8 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie ...@@ -253,32 +253,8 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie
// 获取视频的图片 // 获取视频的图片
PhotoAndVideoMananger.mananger.getVideoImageByIdent(ident: ident) { image in PhotoAndVideoMananger.mananger.getVideoImageByIdent(ident: ident) { image in
// 点击之后跳转详情页面 // 点击之后跳转详情页面
let vc = PMShowImgVideoController() let vc = PhotoRemoveViewController(data: self.resourceData,currentIndex: indexPath.row,mediaType: .video)
vc.state = .similarVideos self.navigationController?.pushViewController(vc, animated: true)
vc.currentIdx = 0
let dataSource = ImageSeletedCollectionItem()
dataSource.isSeleted = true
dataSource.id = ident
dataSource.image = image
// 表示这个是视频
vc.homeDataSource = [dataSource]
vc.getVideoURLFromLocalIdentifier(localIdentifier: ident.localIdentifier) { url, error in
if url != nil{
DispatchQueue.main.async {
vc.url = url
self.navigationController?.pushViewController(vc, animated: true)
}
}else{
let alert = UIAlertController(title: nil, message: "ICloud video cannot be viewed", preferredStyle: .alert)
self.present(alert, animated: true, completion: nil)
// 2 秒后关闭弹窗
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true, completion: nil)
}
}
}
} errorHandler: { } errorHandler: {
DispatchQueue.main.async { DispatchQueue.main.async {
let alert = UIAlertController(title: nil, message: "Get Video image failure", preferredStyle: .alert) let alert = UIAlertController(title: nil, message: "Get Video image failure", preferredStyle: .alert)
......
//
// PhotoRemoveViewController.swift
// PhoneManager
//
// Created by edy on 2025/5/13.
//
import UIKit
import SnapKit
import Photos
class PhotoRemoveViewController: BaseViewController {
var mediaType : TrashTypeEnum?
private var bottomConstraint: Constraint?
let formatter = DateFormatter()
lazy var navView : PhotoRemoveNavView = {
let view = PhotoRemoveNavView()
return view
}()
// MARK: - 属性
private var photoViews: [PhotosRemoveBaseView] = []
private var currentIndex : Int
private var dataModel: [AssetModel]
// 配置参数
private let rotationStrength: CGFloat = 320
private let rotationMax: CGFloat = .pi/4
private let scaleStrength: CGFloat = -0.5
private let scaleMax: CGFloat = 0.7
private let actionMargin: CGFloat = 120
lazy var trashSubView : TrashSubView = {
let view = TrashSubView()
view.backgroundColor = .white
view.isHidden = true
return view
}()
// MARK: - 初始化
init(data: [AssetModel],currentIndex:Int,mediaType:TrashTypeEnum) {
self.mediaType = mediaType
let tempData = data
// 从currentIndex截断拼接在末尾,设置currentIndex为0
let result = Array(tempData[currentIndex...]) + Array(tempData[..<currentIndex])
self.currentIndex = 0
self.dataModel = result
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - 生命周期
override func viewDidLoad() {
super.viewDidLoad()
formatter.dateStyle = .medium
formatter.timeStyle = .none
if let type = self.mediaType {
self.navView.mediaType = type
}
self.view.addSubview(self.navView)
self.navView.snp.makeConstraints { make in
make.top.left.right.equalToSuperview()
make.height.equalTo(statusBarHeight + 44)
}
setupViews()
self.view.addSubview(self.trashSubView)
self.trashSubView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
self.bottomConstraint = make.bottom.equalToSuperview().offset(78).constraint
make.height.equalTo(78)
}
self.trashSubView.clearTashDataCallBack = {[weak self] in
guard let self else {return}
// 清除垃圾桶数据
TrashDataManager.clearTrashData(mediaType: self.mediaType) {[weak self] in
guard let self else {return}
self.showCurrentPageUIWhenTashDataChanged()
}
}
self.trashSubView.presentTashDetailViewClickCallBack = {
// 进入垃圾桶详情页面
DispatchQueue.main.async {
let vc : TrashViewController = TrashViewController()
self.present(vc, animated: true)
}
}
showCurrentPageUIWhenTashDataChanged()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// 视图消失的时候存到数据库
saveDataToKeepListDB()
}
func changeDateToString() -> String{
let model = self.dataModel[self.currentIndex]
return formatter.string(from: model.createDate)
}
func chengeSizeToString()-> String {
let model = self.dataModel[self.currentIndex]
return formatFileSize(model.assetSize)
}
func showTrashView(){
DispatchQueue.main.async {
self.trashSubView.isHidden = false
UIView.animate(withDuration: 0.1) {
// 更新约束
self.bottomConstraint?.update(offset: -safeHeight)
}
}
}
func hideTrashView(){
DispatchQueue.main.async {
UIView.animate(withDuration: 0.1) {
// 更新约束
self.bottomConstraint?.update(offset: -78)
}completion: { finished in
self.trashSubView.isHidden = true
}
}
}
func showCurrentPageUIWhenTashDataChanged(){
if let type = self.mediaType{
// 从数据库拿数据
let dataDB = TrashDatabase.shared.queryByMediaType(type.dbType)
var assetModel : [AssetModel] = []
for item in dataDB {
assetModel.append(AssetModel.init(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: item.mediaType))
}
// 从单利拿数据
DispatchQueue.main.async {
if let type = self.mediaType{
if let dataSg = Singleton.shared.trashData[type]{
assetModel = assetModel + dataSg
// 如果单利中有当前数据,显示撤回按钮
if dataSg.count > 0{
self.navView.resetButton.isHidden = false
}else{
self.navView.resetButton.isHidden = true
}
}else {
self.navView.resetButton.isHidden = true
}
}
if assetModel.count > 0 {
// 显示垃圾桶
self.trashSubView.resourceCountlabel.text = String(assetModel.count)
self.showTrashView()
}else{
self.hideTrashView()
}
}
}
}
// MARK: - 视图设置
private func setupViews() {
// 只创建两个视图
for _ in 0..<2 {
let photoView = PhotosRemoveBaseView()
photoView.mediaType = self.mediaType
photoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))
view.addSubview(photoView)
photoView.frame = CGRectMake(15, statusBarHeight + 44, self.view.width - 30, self.view.height - 78 - safeHeight - statusBarHeight - 44)
photoViews.append(photoView)
}
// 加载初始图片
updateViewContents()
bringCurrentViewToFront()
}
// 存垃圾桶数据到单利
func saveDataToSigtonTrash(){
// 拿到单利数据
if let type = self.mediaType{
if let dataSg = Singleton.shared.trashData[type]{
var tempArray = dataSg
tempArray.append(self.dataModel[currentIndex])
Singleton.shared.trashData[type] = tempArray
}else{
Singleton.shared.trashData[type] = [self.dataModel[currentIndex]]
}
}
self.showCurrentPageUIWhenTashDataChanged()
}
// 存保留数据到单利
func saveDataToSigtonKeepList(){
// 拿到单利数据
if let type = self.mediaType{
if let dataSg = Singleton.shared.keepList[type]{
var tempArray = dataSg
tempArray.append(self.dataModel[currentIndex])
Singleton.shared.keepList[type] = tempArray
}else{
Singleton.shared.keepList[type] = [self.dataModel[currentIndex]]
}
}
}
func saveDataToTrashDB(){
if let type = self.mediaType{
if let dataSg = Singleton.shared.trashData[type]{
for item in dataSg{
let success = TrashDatabase.shared.insert(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: type.dbType)
if success {
Print("保留单利数据到数据库垃圾桶成功")
}
}
Singleton.shared.trashData[type] = []
}
}
showCurrentPageUIWhenTashDataChanged()
}
/// 将保留列表单利数据存到数据库
func saveDataToKeepListDB(){
let uinqueId = UUID().uuidString
if let type = self.mediaType{
if let dataSg = Singleton.shared.keepList[type]{
for item in dataSg{
let success = GroupDatabase.shared.insert(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: type.dbType,groupId: uinqueId)
if success == false {
Print("保留单利数据到数据库保留列表失败")
}
}
Singleton.shared.keepList[type] = []
}
}
}
// MARK: - 手势处理
@objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
guard let activeView = gesture.view as? PhotosRemoveBaseView else { return }
// 记录初始位置
let initialCenter = activeView.center
let translation = gesture.translation(in: view)
let velocity = gesture.velocity(in: view)
switch gesture.state {
case .began:
activeView.initialCenter = initialCenter
case .changed:
// 使用增量位移更新位置
activeView.center = CGPoint(
x: activeView.initialCenter.x + translation.x,
y: activeView.initialCenter.y + translation.y
)
updateActionButton(for: activeView, translation: translation)
case .ended, .cancelled:
// 计算实际位移(基于最终位置)
let actualTranslation = CGPoint(
x: activeView.center.x - activeView.initialCenter.x,
y: activeView.center.y - activeView.initialCenter.y
)
// 使用实际位移判断
if abs(actualTranslation.x) > actionMargin || abs(velocity.x) > 500 {
removeCurrentView(translation: actualTranslation, velocity: velocity)
if actualTranslation.x > 0 {
// 保存垃圾桶数据到数据库
saveDataToTrashDB()
// 保留操作
saveDataToSigtonKeepList()
}
if actualTranslation.x < 0 {
// 删除操作,先存到单利
saveDataToSigtonTrash()
}
} else {
resetViewPosition(activeView)
}
gesture.setTranslation(.zero, in: view)
default: break
}
}
// MARK: - 视图更新逻辑
private func updateViewContents() {
for (index, view) in photoViews.enumerated() {
let imageIndex = (currentIndex + index) % dataModel.count
if self.mediaType == .video{
self.getVideoURLFromLocalIdentifier(localIdentifier: dataModel[imageIndex].localIdentifier) { url, error in
if url != nil {
view.url = url
view.reload(index: index)
}
}
}else {
view.configure(with: PhotoAndVideoMananger.mananger.getImageFromAssetID(id: dataModel[imageIndex].localIdentifier) ?? UIImage())
}
}
// 设置顶部title
self.navView.titleLbel.text = changeDateToString()
self.navView.sizeLbel.text = chengeSizeToString()
}
private func updateActionButton(for view: PhotosRemoveBaseView, translation: CGPoint) {
if translation.x > 0 {
view.showRightButton()
} else if translation.x < 0 {
view.showLeftButton()
} else {
view.hideButtons()
}
}
private func removeCurrentView(translation: CGPoint, velocity: CGPoint) {
guard let activeView = photoViews.first else { return }
let direction: CGFloat = translation.x > 0 ? 1 : -1
let screenWidth = UIScreen.main.bounds.width
UIView.animate(withDuration: 0.3) {
activeView.center = CGPoint(
x: direction * (screenWidth * 1.5),
y: activeView.center.y + velocity.y * 0.1
)
activeView.alpha = 0
} completion: { _ in
self.recycleView()
}
}
private func resetViewPosition(_ view: PhotosRemoveBaseView) {
UIView.animate(withDuration: 0.3) {
view.transform = .identity
view.frame = CGRectMake(15, statusBarHeight + 44, self.view.width - 30, self.view.height - 78 - safeHeight - statusBarHeight - 44)
view.hideButtons()
}
}
private func recycleView() {
// 移除旧视图
let removedView = photoViews.removeFirst()
removedView.removeFromSuperview()
// 当划到最后一张的时候就不再滑动了
if currentIndex == dataModel.count{
return
}
// 创建新视图并更新内容
let newView = PhotosRemoveBaseView()
newView.frame = CGRectMake(15, statusBarHeight + 44, self.view.width - 30, self.view.height - 78 - safeHeight - statusBarHeight - 44)
newView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))
newView.alpha = 0
view.addSubview(newView)
photoViews.append(newView)
// 更新索引并加载新内容
currentIndex = (currentIndex + 1) % dataModel.count
updateViewContents()
// 视图层级处理
bringCurrentViewToFront()
UIView.animate(withDuration: 0.3) {
newView.alpha = 1
}
}
private func bringCurrentViewToFront() {
guard photoViews.count >= 2 else { return }
view.bringSubviewToFront(photoViews[1])
view.bringSubviewToFront(photoViews[0])
}
private func getVideoURLFromLocalIdentifier(localIdentifier: String, completion: @escaping (URL?, Error?) -> Void) {
// 通过 localIdentifier 获取 PHAsset
let fetchOptions = PHFetchOptions()
let assets = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: fetchOptions)
guard let asset = assets.firstObject, asset.mediaType == .video else {
DispatchQueue.main.async {
completion(nil, NSError(domain: "com.example.error", code: 1, userInfo: [NSLocalizedDescriptionKey: "未找到对应视频资源"]))
}
return
}
let options = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true // 允许从网络下载
options.deliveryMode = .automatic // 要求高质量格式
PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { (avAsset, audioMix, info) in
if let error = info?[PHImageErrorKey] as? Error {
DispatchQueue.main.async {
completion(nil, error)
}
return
}
if let urlAsset = avAsset as? AVURLAsset {
DispatchQueue.main.async {
completion(urlAsset.url, nil)
}
} else {
DispatchQueue.main.async {
completion(nil, NSError(domain: "CustomErrorDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to get video URL"]))
}
}
}
}
}
...@@ -21,13 +21,13 @@ class PhotoSlideViewController: BaseViewController { ...@@ -21,13 +21,13 @@ class PhotoSlideViewController: BaseViewController {
private lazy var topView: AnchorRotatableView = { private lazy var topView: AnchorRotatableView = {
let view = AnchorRotatableView() let view = AnchorRotatableView()
view.configure(anchorPoint: CGPoint(x: 0.5, y: 0.5))
return view return view
}() }()
private lazy var bottomView: AnchorRotatableView = { private lazy var bottomView: AnchorRotatableView = {
let view = AnchorRotatableView() let view = AnchorRotatableView()
view.configure(anchorPoint: CGPoint(x: 0.5, y: 0.5))
return view return view
}() }()
...@@ -119,7 +119,8 @@ class PhotoSlideViewController: BaseViewController { ...@@ -119,7 +119,8 @@ class PhotoSlideViewController: BaseViewController {
updateCardTransform(translation: translation) updateCardTransform(translation: translation)
updateButtons(progress: progress,translation: translation) updateButtons(progress: progress,translation: translation)
case .ended, .cancelled: case .ended, .cancelled:
endDragAnimation(velocity: velocity) break
// endDragAnimation(velocity: velocity)
default: break default: break
} }
} }
......
...@@ -40,10 +40,3 @@ class AnchorRotatableView: UIView { ...@@ -40,10 +40,3 @@ class AnchorRotatableView: UIView {
} }
extension AnchorRotatableView {
func configure(anchorPoint: CGPoint) {
layer.anchorPoint = anchorPoint
}
}
...@@ -42,7 +42,7 @@ class HomeInfoView :UIView { ...@@ -42,7 +42,7 @@ class HomeInfoView :UIView {
lazy var headerView:HomeInfoTitleView = { lazy var headerView:HomeInfoTitleView = {
let sview:HomeInfoTitleView = HomeInfoTitleView(frame: CGRect(x: 0, y: 0, width: width, height: 84)) let sview:HomeInfoTitleView = HomeInfoTitleView(frame: CGRect(x: 0, y: 0, width: width, height: 84))
sview.titleLabel.text = self.titleText sview.titleLabel.text = self.titleText
sview.filterButton.isHidden = self.type != .similar sview.filterButton.isHidden = self.type != .similar && self.type != .SimilarVideos
tableView.addSubview(sview) tableView.addSubview(sview)
return sview return sview
}() }()
...@@ -117,7 +117,13 @@ class HomeInfoView :UIView { ...@@ -117,7 +117,13 @@ class HomeInfoView :UIView {
// 从源头获取相似数据 // 从源头获取相似数据
PhotoDataManager.manager.loadFromFileSystem(resultModel: {[weak self] model in PhotoDataManager.manager.loadFromFileSystem(resultModel: {[weak self] model in
guard let self else {return} guard let self else {return}
let tempData = self.filterDataByDate(orgModels: model.titleModelArray[1].assets, startDate: filterModel.startDate, endDate: filterModel.endDate) var dataS : [[AssetModel]] = []
if self.type == .SimilarVideos{
dataS = model.otherModelArray[3].assets
}else {
dataS = model.titleModelArray[1].assets
}
let tempData = self.filterDataByDate(orgModels: dataS , startDate: filterModel.startDate, endDate: filterModel.endDate)
// 重新更新下数据源 // 重新更新下数据源
self.ids = self.sortData(source: tempData, type: filterModel.sortType) self.ids = self.sortData(source: tempData, type: filterModel.sortType)
var tempModels : [HomeInfoTableItem] = [] var tempModels : [HomeInfoTableItem] = []
......
//
// PhotoRemoveNavView.swift
// PhoneManager
//
// Created by edy on 2025/5/13.
//
import UIKit
import SnapKit
class PhotoRemoveNavView: UIView {
public var backButton:UIButton!
public var sizeLbel : UILabel!
public var titleLbel : UILabel!
public var resetButton :UIButton!
private var topConstraint: Constraint?
public var mediaType : TrashTypeEnum = .shot {
didSet{
if mediaType == .video {
self.sizeLbel.isHidden = false
self.topConstraint?.update(offset: 22 + statusBarHeight)
}else{
self.sizeLbel.isHidden = true
self.topConstraint?.update(offset: 6 + statusBarHeight)
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
backgroundColor = .white
backButton = UIButton()
backButton.setImage(UIImage(named: "nav_back"), for: .normal)
backButton.addTarget(self, action: #selector(backBtnClick), for: .touchUpInside)
self.addSubview(backButton)
backButton.snp.makeConstraints { make in
make.centerY.equalTo(navCenterY)
make.left.equalToSuperview().offset(marginLR)
make.width.height.equalTo(iconWH)
}
sizeLbel = UILabel()
sizeLbel.textColor = UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1)
sizeLbel.font = UIFont.systemFont(ofSize: 12, weight: .medium)
self.addSubview(sizeLbel)
sizeLbel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(statusBarHeight)
make.height.equalTo(22)
}
titleLbel = UILabel()
titleLbel.textColor = UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1)
titleLbel.font = UIFont.systemFont(ofSize: 12, weight: .medium)
self.addSubview(titleLbel)
titleLbel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
self.topConstraint = make.top.equalToSuperview().offset(6 + statusBarHeight).constraint
make.height.equalTo(22)
}
resetButton = UIButton()
resetButton.setImage(UIImage(named: "Frame 3"), for: .normal)
resetButton.addTarget(self, action: #selector(resetButtonAction), for: .touchUpInside)
resetButton.isHidden = true
self.addSubview(resetButton)
resetButton.snp.makeConstraints { make in
make.centerY.equalTo(navCenterY)
make.right.equalToSuperview().offset(-marginLR)
make.width.height.equalTo(iconWH)
}
}
@objc private func backBtnClick() {
self.responderViewController()?.navigationController?.popViewController(animated: true)
}
@objc private func resetButtonAction() {
}
}
//
// AnchorRotatableView.swift
// AIClean
//
// Created by 赵前 on 2025/5/10.
//
import Foundation
import UIKit
class PhotosRemoveBaseView: UIView {
var currentIndex : Int?
var initialCenter: CGPoint = .zero
var url : URL?
var innerVideoController : VideoViewController?
func reload(index:Int) -> Void {
if let url = url {
self.innerVideoController = VideoViewController()
if let vc = self.innerVideoController {
vc.isAutoPlay = index == 0
vc.url = url
self.imageView.removeFromSuperview()
self.addSubview(vc.view)
vc.view.snp.makeConstraints { make in
make.left.top.bottom.right.equalToSuperview()
}
}
}
}
var mediaType : TrashTypeEnum?
lazy var maskTempleteView : UIView = {
let view = UIView(frame: CGRectMake(0, 0, self.width, self.height))
return view
}()
private let imageView = UIImageView()
private let leftButton = UIButton()
private let rightButton = UIButton()
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = 20
self.clipsToBounds = true
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupUI() {
// 配置图片视图
imageView.contentMode = .scaleAspectFit
addSubview(imageView)
leftButton.frame = CGRect(x: self.width / 2 - 45.5, y: self.height / 2 - 21, width: 95, height: 42)
leftButton.setTitle("Delete", for: .normal)
leftButton.backgroundColor = UIColor(red: 0.95, green: 0.21, blue: 0.21, alpha: 1)
leftButton.tintColor = .white
leftButton.layer.cornerRadius = 21
leftButton.clipsToBounds = true
leftButton.alpha = 0
addSubview(leftButton)
rightButton.frame = CGRect(x: self.width / 2 - 45.5, y: self.height / 2 - 21, width: 95, height: 42)
rightButton.setTitle("Retain", for: .normal)
rightButton.backgroundColor = UIColor(red: 0.18, green: 0.76, blue: 0.35, alpha: 1)
rightButton.tintColor = .white
rightButton.layer.cornerRadius = 21
rightButton.clipsToBounds = true
rightButton.alpha = 0
addSubview(rightButton)
}
func configure(with image: UIImage) {
imageView.image = image
imageView.frame = bounds
}
func showLeftButton() {
self.leftButton.center = self.center
UIView.animate(withDuration: 0.2) {
self.leftButton.alpha = 1
self.maskTempleteView.backgroundColor = UIColor(red: 0.95, green: 0.21, blue: 0.21, alpha: 0.4000)
self.addSubview(self.maskTempleteView)
self.rightButton.alpha = 0
}
}
func showRightButton() {
self.rightButton.center = self.center
UIView.animate(withDuration: 0.2) {
self.rightButton.alpha = 1
self.maskTempleteView.backgroundColor = UIColor(red: 0.26, green: 0.78, blue: 0.41, alpha: 0.4000)
self.addSubview(self.maskTempleteView)
self.leftButton.alpha = 0
}
}
func hideButtons() {
UIView.animate(withDuration: 0.2) {
self.leftButton.alpha = 0
self.rightButton.alpha = 0
self.maskTempleteView.removeFromSuperview()
self.leftButton.center = self.center
self.rightButton.center = self.center
}
}
}
//
// TrashSubView.swift
// PhoneManager
//
// Created by edy on 2025/5/13.
//
import UIKit
class TrashSubView: UIView {
var clearTashDataCallBack : ()->Void = {}
var presentTashDetailViewClickCallBack : ()->Void = {}
lazy var resourceCountlabel : UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 24, weight: .semibold)
label.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
return label
}()
lazy var tipLabel : UILabel = {
let label = UILabel()
label.text = "The photo in the trash can"
label.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
label.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
label.numberOfLines = 0
return label
}()
lazy var emptyButton: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "ic_delete_duplicates"), for: .normal)
button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
button.setTitle("Empty the garbage", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
button.layer.cornerRadius = 19
button.clipsToBounds = true
button.addTarget(self, action: #selector(emptyButtonAction), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
// 给当前视图添加手势
addTapGestureToSelf()
// 添加UI
addUIViews()
setUILocation()
}
private func addUIViews(){
self.addSubview(self.resourceCountlabel)
self.addSubview(self.tipLabel)
self.addSubview(self.emptyButton)
}
private func setUILocation(){
self.resourceCountlabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16)
make.centerY.equalToSuperview()
make.height.equalTo(22)
make.width.equalTo(30)
}
self.tipLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(17)
make.bottom.equalToSuperview().offset(-17)
make.left.equalTo(self.resourceCountlabel.snp.right).offset(11)
make.width.equalTo(100)
}
self.emptyButton.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-9)
make.height.equalTo(38)
make.centerY.equalToSuperview()
make.width.equalTo(145)
}
}
private func addTapGestureToSelf(){
self.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(tapHandle))
self.addGestureRecognizer(tap)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension TrashSubView {
@objc func emptyButtonAction(){
self.clearTashDataCallBack()
}
@objc func tapHandle(){
self.presentTashDetailViewClickCallBack()
}
}
...@@ -217,11 +217,26 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou ...@@ -217,11 +217,26 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou
// 显示保留按钮或者最佳匹配结果按钮 // 显示保留按钮或者最佳匹配结果按钮
cell.allKeepButton.isHidden = indexPath.item != 0 || self.type == .duplicates cell.allKeepButton.isHidden = indexPath.item != 0 || self.type == .duplicates
cell.bestResultButton.isHidden = indexPath.item != 0 || self.type == .duplicates cell.bestResultButton.isHidden = indexPath.item != 0 || self.type == .duplicates
cell.model = model?.smodels?[indexPath.row] cell.model = model?.smodels?[indexPath.row]
cell.photsFileType = model?.type cell.photsFileType = model?.type
cell.keepAllCallBack = {
//存到保留列表
saveAllDataToKeepList()
}
// 存全部数据到保留列表
func saveAllDataToKeepList(){
let uniqueId = UUID().uuidString
if let tempModel = self.model?.smodels {
for item in tempModel {
if let assetModel = item.id {
let success = GroupDatabase.shared.insert(localIdentifier: assetModel.localIdentifier, assetSize: assetModel.assetSize, createDate: assetModel.createDate, mediaType: self.type == .SimilarVideos ? 2 : 1 , groupId: uniqueId)
if success == false {
Print("存入当前数据到保留列表失败")
}
}
}
}
}
cell.callBack = {[weak self] _ in cell.callBack = {[weak self] _ in
guard let self else {return} guard let self else {return}
...@@ -253,9 +268,22 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou ...@@ -253,9 +268,22 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou
}else{ }else{
vc.state = .similarPhotos vc.state = .similarPhotos
} }
vc.oldPageIndexPath = indexPath
vc.currentIdx = indexPath.row vc.currentIdx = indexPath.row
vc.homeDataSource = self.model?.smodels vc.homeDataSource = self.model?.smodels
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true) self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
vc.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
self.model?.smodels = data
DispatchQueue.main.async{
if let view = self.collectionView{
UIView.transition(with: view, duration: 0.3, options: .transitionCrossDissolve, animations: {
view.reloadData()
}, completion: nil)
}
}
}
} }
} }
......
...@@ -19,6 +19,8 @@ class ImageSeletedCollectionCell:UICollectionViewCell { ...@@ -19,6 +19,8 @@ class ImageSeletedCollectionCell:UICollectionViewCell {
var callBack:callBack<Any> = {text in} var callBack:callBack<Any> = {text in}
var keepAllCallBack : ()->Void = {}
lazy var allKeepButton : UIButton = { lazy var allKeepButton : UIButton = {
let button = UIButton(type: .custom) let button = UIButton(type: .custom)
...@@ -37,8 +39,8 @@ class ImageSeletedCollectionCell:UICollectionViewCell { ...@@ -37,8 +39,8 @@ class ImageSeletedCollectionCell:UICollectionViewCell {
let button = UIButton(type: .custom) let button = UIButton(type: .custom)
button.layer.cornerRadius = 8 button.layer.cornerRadius = 8
button.clipsToBounds = true button.clipsToBounds = true
button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1) button.backgroundColor = UIColor(red: 1, green: 0.65, blue: 0, alpha: 1)
button.setTitle( "Best result", for: .normal) button.setTitle( "Best", for: .normal)
button.setImage(UIImage(named: "Frame"), for: .normal) button.setImage(UIImage(named: "Frame"), for: .normal)
button.setTitleColor(.white, for: .normal) button.setTitleColor(.white, for: .normal)
button.isHidden = true button.isHidden = true
...@@ -179,7 +181,7 @@ class ImageSeletedCollectionCell:UICollectionViewCell { ...@@ -179,7 +181,7 @@ class ImageSeletedCollectionCell:UICollectionViewCell {
self.bestResultButton.snp.makeConstraints { make in self.bestResultButton.snp.makeConstraints { make in
make.left.bottom.equalToSuperview() make.left.bottom.equalToSuperview()
make.width.equalTo(81) make.width.equalTo(52)
make.height.equalTo(16) make.height.equalTo(16)
} }
...@@ -222,6 +224,8 @@ class ImageSeletedCollectionCell:UICollectionViewCell { ...@@ -222,6 +224,8 @@ class ImageSeletedCollectionCell:UICollectionViewCell {
extension ImageSeletedCollectionCell { extension ImageSeletedCollectionCell {
@objc func allKeepButtonAction(){ @objc func allKeepButtonAction(){
Print("点击了全部保留按钮") Print("点击了全部保留按钮")
self.keepAllCallBack()
} }
} }
...@@ -28,6 +28,21 @@ class PMShowImgCell: UICollectionViewCell { ...@@ -28,6 +28,21 @@ class PMShowImgCell: UICollectionViewCell {
scaleImg.icon = icon scaleImg.icon = icon
} }
} }
lazy var bestResultButton:UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "Frame"), for: .normal)
button.setTitle("Best", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .semibold)
button.layer.cornerRadius = 10.5
button.clipsToBounds = true
button.backgroundColor = UIColor(red: 1, green: 0.65, blue: 0, alpha: 1)
contentView.addSubview(button)
return button
}()
private lazy var iconView: UIImageView = { private lazy var iconView: UIImageView = {
let info = UIImageView() let info = UIImageView()
...@@ -63,6 +78,14 @@ class PMShowImgCell: UICollectionViewCell { ...@@ -63,6 +78,14 @@ class PMShowImgCell: UICollectionViewCell {
} }
private func setup() -> Void { private func setup() -> Void {
bestResultButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.top.equalToSuperview().offset(34)
make.width.equalTo(63)
make.height.equalTo(21)
}
iconView.snp.makeConstraints { make in iconView.snp.makeConstraints { make in
make.left.right.bottom.top.equalToSuperview() make.left.right.bottom.top.equalToSuperview()
} }
...@@ -74,5 +97,7 @@ class PMShowImgCell: UICollectionViewCell { ...@@ -74,5 +97,7 @@ class PMShowImgCell: UICollectionViewCell {
make.width.height.equalTo(iconWH) make.width.height.equalTo(iconWH)
make.bottom.equalToSuperview().offset(-10) make.bottom.equalToSuperview().offset(-10)
} }
self.contentView.bringSubviewToFront(self.bestResultButton)
} }
} }
...@@ -17,6 +17,8 @@ class PMShowVideoCell: UICollectionViewCell { ...@@ -17,6 +17,8 @@ class PMShowVideoCell: UICollectionViewCell {
var type : Int = 0 var type : Int = 0
var innerVideoController : VideoViewController?
func reload() -> Void { func reload() -> Void {
var url : URL? var url : URL?
if type == 0 { if type == 0 {
...@@ -25,25 +27,39 @@ class PMShowVideoCell: UICollectionViewCell { ...@@ -25,25 +27,39 @@ class PMShowVideoCell: UICollectionViewCell {
url = homeResouceUrl url = homeResouceUrl
} }
if let url = url { if let url = url {
player.playVideo(from: url) self.innerVideoController = VideoViewController()
if let vc = self.innerVideoController {
vc.url = url
self.contentView.addSubview(vc.view)
self.contentView.bringSubviewToFront(self.selectBtn)
vc.view.snp.makeConstraints { make in
make.left.top.bottom.right.equalToSuperview()
}
}
} }
} }
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
setup() self.contentView.addSubview(self.selectBtn)
selectBtn.snp.makeConstraints { make in
make.right.equalToSuperview()
make.width.height.equalTo(iconWH)
make.bottom.equalToSuperview().offset(-10)
}
bestResultButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.top.equalToSuperview().offset(34)
make.width.equalTo(63)
make.height.equalTo(21)
}
self.contentView.bringSubviewToFront(self.bestResultButton)
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
private func setup() -> Void {
player.snp.makeConstraints { make in
make.left.top.bottom.right.equalToSuperview()
}
}
var zPlayer : SecretVideoPlayer { var zPlayer : SecretVideoPlayer {
get { get {
return player return player
...@@ -57,4 +73,44 @@ class PMShowVideoCell: UICollectionViewCell { ...@@ -57,4 +73,44 @@ class PMShowVideoCell: UICollectionViewCell {
contentView.addSubview(p) contentView.addSubview(p)
return p return p
}() }()
var callblock:(()->Void) = {}
@objc private func selectTap() -> Void {
callblock()
}
var isCurrent:Bool = false {
didSet {
selectBtn.isSelected = isCurrent
}
}
lazy var selectBtn: UIButton = {
let select = UIButton(type: .custom)
select.setImage(UIImage(named: "home_info_norl"), for: .normal)
select.setImage(UIImage(named: "home_info_seleted"), for: .selected)
select.addTarget(self, action: #selector(selectTap), for: .touchUpInside)
contentView.addSubview(select)
return select
}()
lazy var bestResultButton:UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "Frame"), for: .normal)
button.setTitle("Best", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .semibold)
button.layer.cornerRadius = 10.5
button.clipsToBounds = true
button.backgroundColor = UIColor(red: 1, green: 0.65, blue: 0, alpha: 1)
contentView.addSubview(button)
return button
}()
} }
...@@ -21,16 +21,32 @@ class PMShowImgVideoController: BaseViewController { ...@@ -21,16 +21,32 @@ class PMShowImgVideoController: BaseViewController {
// 资源类型 0-图片 1-视频 // 资源类型 0-图片 1-视频
var homeMediaType : Int = 0 var homeMediaType : Int = 0
// 记录原来进来的
var oldPageIndexPath : IndexPath?
var state:ShowState = .secret var state:ShowState = .secret
var imageVideoPath:[String] = [] var imageVideoPath:[String] = []
// 首页过来的数据 // 首页过来的数据
var homeDataSource : [ImageSeletedCollectionItem]? var homeDataSource : [ImageSeletedCollectionItem]? {
didSet{
if let data = homeDataSource {
for (index,item) in data.enumerated() {
if item.isSeleted == true {
selectSet.add(index)
}
}
}
}
}
var currentIdx = 0 var currentIdx = 0
var selectSet = NSMutableSet() var selectSet = NSMutableSet()
var backOrgPageCallBack : (IndexPath?,[ImageSeletedCollectionItem]?)->Void = {index,data in}
var url : URL? var url : URL?
override func viewDidLoad() { override func viewDidLoad() {
...@@ -53,6 +69,19 @@ class PMShowImgVideoController: BaseViewController { ...@@ -53,6 +69,19 @@ class PMShowImgVideoController: BaseViewController {
self.MaxCollection.scrollToItem(at: IndexPath(row: currentIdx, section: 0), at: .centeredHorizontally, animated: false) self.MaxCollection.scrollToItem(at: IndexPath(row: currentIdx, section: 0), at: .centeredHorizontally, animated: false)
} }
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 离开返回上一个把选择的数据带过去
for item in self.selectSet {
if let index = item as? Int {
self.homeDataSource?[index].isSeleted = true
}
}
self.backOrgPageCallBack(self.oldPageIndexPath,self.homeDataSource)
}
private lazy var MaxCollection: UICollectionView = { private lazy var MaxCollection: UICollectionView = {
let flowlayout = UICollectionViewFlowLayout() let flowlayout = UICollectionViewFlowLayout()
flowlayout.sectionInset = UIEdgeInsets() flowlayout.sectionInset = UIEdgeInsets()
...@@ -131,8 +160,10 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa ...@@ -131,8 +160,10 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == bottItems { if collectionView == bottItems {
if selectSet.contains(indexPath.row) { if selectSet.contains(indexPath.row) {
self.homeDataSource?[indexPath.row].isSeleted = false
selectSet.remove(indexPath.row) selectSet.remove(indexPath.row)
}else{ }else{
self.homeDataSource?[indexPath.row].isSeleted = true
selectSet.add(indexPath.row) selectSet.add(indexPath.row)
} }
self.MaxCollection.reloadData() self.MaxCollection.reloadData()
...@@ -158,7 +189,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa ...@@ -158,7 +189,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
let showName = imageVideoPath[indexPath.row] let showName = imageVideoPath[indexPath.row]
if !showName.hasSuffix(".png") { if !showName.hasSuffix(".png") {
guard let zCell:PMShowVideoCell = cell as? PMShowVideoCell else { return } guard let zCell:PMShowVideoCell = cell as? PMShowVideoCell else { return }
zCell.zPlayer.pause() zCell.innerVideoController?.playerViewController.player?.pause()
} }
} }
} }
...@@ -172,12 +203,16 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa ...@@ -172,12 +203,16 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
showName.loadPhotoOrVideo { durs, icon in showName.loadPhotoOrVideo { durs, icon in
cell.icon = icon cell.icon = icon
} }
cell.bestResultButton.isHidden = indexPath.row != 0
cell.isCurrent = selectSet.contains(indexPath.row) cell.isCurrent = selectSet.contains(indexPath.row)
cell.callblock = {[weak self] in cell.callblock = {[weak self] in
guard let self = self else { return } guard let self = self else { return }
if self.selectSet.contains(indexPath.row){ if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row) self.selectSet.remove(indexPath.row)
}else{ }else{
self.homeDataSource?[indexPath.row].isSeleted = true
self.selectSet.add(indexPath.row) self.selectSet.add(indexPath.row)
} }
self.MaxCollection.reloadData() self.MaxCollection.reloadData()
...@@ -186,8 +221,21 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa ...@@ -186,8 +221,21 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
return cell return cell
}else{ }else{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PMShowVideoCellID, for: indexPath) as! PMShowVideoCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PMShowVideoCellID, for: indexPath) as! PMShowVideoCell
cell.isCurrent = selectSet.contains(indexPath.row)
cell.playURL = showName cell.playURL = showName
cell.reload() cell.reload()
cell.callblock = {[weak self] in
guard let self = self else { return }
if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row)
}else{
self.homeDataSource?[indexPath.row].isSeleted = true
self.selectSet.add(indexPath.row)
}
self.MaxCollection.reloadData()
self.bottItems.reloadData()
}
return cell return cell
} }
}else{ }else{
...@@ -208,11 +256,14 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa ...@@ -208,11 +256,14 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PMShowImgCellID, for: indexPath) as! PMShowImgCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PMShowImgCellID, for: indexPath) as! PMShowImgCell
cell.icon = self.homeDataSource![indexPath.row].image ?? UIImage() cell.icon = self.homeDataSource![indexPath.row].image ?? UIImage()
cell.isCurrent = selectSet.contains(indexPath.row) cell.isCurrent = selectSet.contains(indexPath.row)
cell.bestResultButton.isHidden = indexPath.row != 0
cell.callblock = {[weak self] in cell.callblock = {[weak self] in
guard let self = self else { return } guard let self = self else { return }
if self.selectSet.contains(indexPath.row){ if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row) self.selectSet.remove(indexPath.row)
}else{ }else{
self.homeDataSource?[indexPath.row].isSeleted = true
self.selectSet.add(indexPath.row) self.selectSet.add(indexPath.row)
} }
self.MaxCollection.reloadData() self.MaxCollection.reloadData()
...@@ -247,6 +298,20 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa ...@@ -247,6 +298,20 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
} }
// 表示这个是视频 // 表示这个是视频
cell.type = 1 cell.type = 1
cell.isCurrent = selectSet.contains(indexPath.row)
cell.bestResultButton.isHidden = indexPath.row != 0
cell.callblock = {[weak self] in
guard let self = self else { return }
if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row)
}else{
self.homeDataSource?[indexPath.row].isSeleted = true
self.selectSet.add(indexPath.row)
}
self.MaxCollection.reloadData()
self.bottItems.reloadData()
}
return cell return cell
}else{ }else{
if indexPath.row < self.homeDataSource?.count ?? 0 { if indexPath.row < self.homeDataSource?.count ?? 0 {
......
...@@ -325,6 +325,16 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo ...@@ -325,6 +325,16 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo
let play = PMShowImgVideoController() let play = PMShowImgVideoController()
play.currentIdx = indexPath.row play.currentIdx = indexPath.row
play.imageVideoPath = dataSource play.imageVideoPath = dataSource
play.oldPageIndexPath = indexPath
play.backOrgPageCallBack = {[weak self]index,data in
guard let self else {return}
self.selectArray = play.selectSet
DispatchQueue.main.async{
UIView.transition(with: self.secretCollect, duration: 0.3, options: .transitionCrossDissolve, animations: {
self.secretCollect.reloadData()
}, completion: nil)
}
}
self.navigationController?.pushViewController(play, animated: true) self.navigationController?.pushViewController(play, animated: true)
} }
......
...@@ -22,6 +22,26 @@ class TrashViewController: UIViewController { ...@@ -22,6 +22,26 @@ class TrashViewController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
configUI() configUI()
getTrashDataAndRefreshPage()
}
/// 获取垃圾桶数据
private func getTrashDataAndRefreshPage(){
for item in self.source {
let data = TrashDataManager.getCurrentMediaTypeTrashData(mediaType: item)
for view in self.contentScrollView.subviews {
if view.isKind(of: TrashContenView.self){
let tempView = view as! TrashContenView
if tempView.trashType == item{
tempView.dataSource = data
DispatchQueue.main.async {
tempView.collectionView.reloadData()
}
}
}
}
}
} }
......
//
// TrashDataManager.swift
// PhoneManager
//
// Created by edy on 2025/5/14.
//
import UIKit
class TrashDataManager {
/// 清除当前垃圾桶的数据
static func clearTrashData(mediaType: TrashTypeEnum?, comlete:@escaping ()->Void){
let trashData = self.getCurrentMediaTypeTrashData(mediaType: mediaType)
if trashData.count > 0 {
PhotoAndVideoMananger.deleteAssets(localIdentifiers: trashData.map({$0.localIdentifier})) {
// 清空单利和数据库的数据
clearCurrentMediaTypeTrashSigtonData()
clearCurrentMediaTypeTrashDBData()
// 删除完成之后重新
comlete()
}
}else{
comlete()
}
func clearCurrentMediaTypeTrashSigtonData(){
if let type = mediaType {
Singleton.shared.trashData[type] = []
Print("删除单利中当前垃圾桶数据成功")
}
}
func clearCurrentMediaTypeTrashDBData(){
if let type = mediaType {
let dataDB = TrashDatabase.shared.queryByMediaType(type.dbType)
let success = TrashDatabase.shared.batchDelete(localIdentifiers: dataDB.map({$0.localIdentifier}))
if success {
Print("删除数据库当前垃圾桶数据成功")
}else {
Print("删除数据库当前垃圾桶数据失败")
}
}
}
}
static func getCurrentMediaTypeTrashData(mediaType: TrashTypeEnum?) -> [AssetModel]{
var assetModel : [AssetModel] = []
if let type = mediaType{
// 从数据库拿数据
let dataDB = TrashDatabase.shared.queryByMediaType(type.dbType)
for item in dataDB {
assetModel.append(AssetModel.init(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: item.mediaType))
}
// 从单利拿数据
if let type = mediaType{
if let dataSg = Singleton.shared.trashData[type]{
assetModel = assetModel + dataSg
}
}
}
return assetModel
}
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import Foundation import Foundation
enum TrashTypeEnum{ enum TrashTypeEnum : CaseIterable{
case video,other,shot,chat case video,other,shot,chat
var dbType:Int{ var dbType:Int{
......
{"v":"5.6.3","fr":25,"ip":0,"op":70,"w":600,"h":600,"nm":"图片压缩动画","ddd":0,"assets":[{"id":"image_0","w":72,"h":12,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAAAMCAYAAADBJPs9AAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAABv0lEQVRIia1WrVIDQQz+0t6VMhj6Bn2EgmAG1BWHAiSC6aMhEMiCQnYGBDMIqEVRjYEXgGB6ZRvys8uw5u42X5Iv2SR7BGVd3nNDHUwANAwMATAAWorb93QPQia/pT4MnFzRvsbLe9fWnIA5E27OD+haCtcUrx54CMIFgMYJJiKYE2xJ4BoGBi5KRoRbgDE+26dFu7ECTR959EWYAdjOdOQF+cu+kOVUlecr8p3j1zqw9w7j8HSP5itDt888/CQ8ARgIhdwTjdoqCszClFZI6hsGDw0jbXx0GbtHO7SoAKDuYVb/JCdVks+ImMRKcqVzyPrWDhDKXpRgq9IGy1EzprsXPukQpg5xuXIwnq5X/jn4v3CJqlraYADEhHG11cfx2tT4n1Yq0feW1gpatUZzJbWj+dYrlTCpNiuMApI5pZ/T81LmtW9qTwbszQ+JkyvnQNNENvT6xuwASgeqpSNtegm1fJRcHJKbxiHCEQBU/brop0o1YjhO7Xk4qyKiJHp6VuVp3Ny9aqPO/pexbqpUFvW2xLYYOSOkvlcxli1NN5qjkgdVve4asISIN5u01ksDSLFSN/rOuYWsts+12e7xNz4FxCSyoDbjAAAAAElFTkSuQmCC","e":1},{"id":"image_1","w":44,"h":77,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAABNCAYAAADdLIb+AAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAALM0lEQVRoge2bS4xcRxWGv+qemTh2ZHceRngMcjuwyCLInV0gC493CAl5ggR5QWIHhKyQEFsgISEkT/agjB0pCcoi45WFEbKtiA1ITI+EYIXSsEjEQ3jyQMZ5eFqZV/reqjosqm7durdvu6dnYjsLShr1uB9z//Ofc6r+8982/H+NvkSkkWg5khp5fl3LpdVEbHddLr23Iq9eXpJm/F51swCmhmmlOKCFaWvYl1pIDSq1oA0YA6mF1NLtrnPogf2qc8MAZwCtcKCmmO4ZmhGgAkBjkcSgUuN+Tw1KW7pLK+x/8D7VHbsRANcSmp5BB8og2jNqLCQatCDaA9UOLIl/XVsaFp4FnvtEAMcpFmF6JaGpPXOpAQ/OMWZROmcwY5HEoKwPIvtsxDDG0gLYFOCYQVEeYAYsv1hgVDvWRFvPoAeqNcoIJL4kEsc+2oAVSDRKHPMY6669IcDlJllLaSY6v3BaTHFcg6EmjWNKjEUlGox1zKWe2Tgb1jqQ2n1G+QAuDARcAGiKKU4i9oz4lLkLiTFIYlHaASIOolQiYn0ZiA8oe92615W24XfRhrfqwgKUdgkRaaz0mEHxbOjivAHKQNHab0N5I4WUl2swS6tnjgiQKw9XFjlwQbQGbXhLhAdfPFqxrb2/LK+nQstEjeK7OtRiqEH/mJiQQqUjgDZ6bwzQCJJqx7oPwKXcf9Y3XhdL20I7rXNm7qjqZhhDSbz5nhxZWqeVAYwZjQFmbMd7p/YXyrYh69NsTdiu3Hvd+1TGpq9xUksX4wH2WJj7gWOzagXAaz0Oa1PcyHUJcBIBv1aKtSnUoNLGNZuxAXhXLG3ZAMCBgK98RLOuimlMI4A2Yr0PYLFhQjAeHCIoCx1rmBsVYHmFGv7lH+VSYxvNNAKTVjAYGs8WGTbRc8YCNVA1qNdA1cP1Ogo6xnJRKzovP6IWNw345GtyfnIn0xljMVsVXe3A+u3LCCjlQJYADlsjBxAAP31Wpu7YzvytYxHACLDN91UkYrBWg9rGAW45gMK29vSv5OQ2xYyyeQ1mbKqaA/kJA+xbjR2wazuIwNsf0EExe/ohdaYSMMAz5+QgluPKMqUtjboaKcWbAnjPXpjcCV+ahIl6vt+/vwrz/4C/v8uJFx5Vs5WA4/XUOWmNwUERphRMITSuF8DsEMoaOt5e/7wInXfY//IjanEkAb+ZAPoA1nJVl8aTRbRlVkmCNy4z8+wh9dyWJo6qABo74J5JmNzVn+L4mC9MGtkWWpIB4YQ1sJYw9/iX1dEtCfgXv6U6ItIFd3otJxyZqDudm1ropbDa84CGMBhNGcVTNN9CG7AJAS8iTQuHjaFlhcMrCY1sgkgtLH/shE0mO02Ufl2uzwhUWgE0HgQQd/2hgJdEmg04nDqA08s9GnFaMwGfzWeeQVVgsEJ/9KW9ogxi8PWaE/B9NSwiDQtPeAanU0NDG0jFjzluFJcwJLqL54yKZ0s7KVmWnboUQPaZ8HypRLTTIp1fPKru62N4aUVayz3OG+s0RVxr/jFcPEphNlgGRsMUkbMeyiQ85oeSpH7y0BZS7UcmP5VY4cwEnMgwBoYvL0nTKuZTSzMWOHGT6NLzGUDbr5ulkP4IYPwer4nFM6u0BREWraUtQjupczEW7wWGP0p4IrWRwVHRxRngoOSiegsy0w2nQch70S6pRlk/bWQTirWIgUVrWBChPQ7tF7+n3rpWTwXAV9eYCjWoS00ypIurmsczmjPoS8MKiyLMi2VhHNovDQE4EPB/lmjcMu4ZjAD2dXE5tXGJCBjt2Lf+x1gUTou0a+PMvvyYujgKwPIKNXzqD/L6HTto9XVxBNhUAS5pZwEnPRXUx7xOjpbAItBRigs1zV9nHxtt+gh/7ifn5fnP7eR4EOeRxCylOX/Os6jqfrqo9wMctkYNIPz5Y2eluWuC128bp5FG4KoYVDX3ySoGt7riABLLQlnEFy731DlpjVnOjwlNb2JgxTN4nQACbBuHfbvhi7vh7rugcStcWYZ3uvCXReY++C8nZv32Vnn5Z87KkZrioMAU0LyeAPffBXt35YotLdpcrCbw27/R/tnX1KGBgON17Kw0x2FqKwFkAO/eDV+4C/bujLSIKR5KZQGfGlhL4U//5NDM11V75ARvJICBACvABElZeq7876urzB79ijqx5Yo8dlaae3dyeM/tHP/87TT3lwBW+cUFr660E8VHfzhZXZAXvvuAenDThnZiHMvGMpVaWrH+uLp2jRSXZWYFo31movXWAiMY2olhShQHsUytpbSyWwA9L2yCSMqczJJYGiCSAoNljVw2ctQwQztmcC3lQCQN4+m2fLcnN7DzexOSRmrMA3Ress4PnyQCXtbDxrJYsxswtI2FXomNUsMUhHyoSW+xao1K/InpfTnRJr8BU9YnfUajC+KSsXyj2tBekfnUMjXM0PY1J7EDH89rNppM4vKIzcTyvYySmdi1QsdaLgwztKfC2J3VWkm5RROIyl7LUhqVgtO8uni7oILBzIlfspaOFS5i6bzyfbUwqJ/6DO2yaK8yuAc2SfF+RlbL2ZgeHHdj6Focg9TovPLkYIADAV9dpWGj7SeYHLYIsNC9pT22wtB2qRbwKZ4bxuCwVW1oe9ETl0IV0NiBz5ok84vBiaaS29lR0DaWhbEe7dnSvDYS4JOvyfnJXUxn7NoIXBWDNn60XsX1Axy2Rg6gYGjfuYP5bfXSPujqLwDLQKMqGdzqGhrANQ3tjEFz/QAW1r7PwJ5dzkhc6cG/3qfz7ytDDO0f/loOi+FIMLT9rYHrAnA37GnAvZNOMI3X+/XHG5eh8w4nfvrVDRjaz5yTgwpaYplWitZWDe2MwXsnYc9OuKVePJyMhV58YvreebcLv3tjE4b2qAHEAAOD2eFjKGjkqjuv8T3DKyscP3q/OrUlPVwOYN9uGnt2wb173NiTpTjWwmkFg2Vd3Hdoudfmvn3/Fg3t0990JdUzgOQqLrXwcQrLvQEMRjWqKwBX+iHiJpuRAK+nMjUxxoHUMG0sreUeuzJN0YvSHFxNgzKCJP5Yjme4OP1lR6lggeVCqTMUsIhMWcsBI0xboZUYGmtJoYulzFihBr2G0LaCwUEAo9fjw2uizqlKwOupTNUVJ63QWu55U8V7wN5px1iUT3EQ8JmtGqm63MG0XhgZMiu239yOjvcwIvkgrTBz+jvOUCk03dKqzFg4WdUkIe1RQwRD2utiE0vKoqx0X+oQ/8Wk0pc7YgkQDisHtK3GmHnp8VwsBcBvLknzVuFSaJDSthMPiJVN4i4gqfZfRopZlNy09p5xfOyHeyMWOmJpW0VbKxbKZnahJOzHnFzSpbE8+j2JHJk+IzvPgirvodGXPHLJ6R7FCh0RFsw1AA4E/OFq/s2pWOMW/GEvhApbT7lJfKrjGoxGnw5COwB8cnR5GQC//SHN7RODu9bYou9VNafZEvtE36EYm6AzVmOuZvjr7COqPSrQbIUa/vnvZf7O7e62QblpKhgsbDuZZyzK/cV6PXc8B1y1q4SO1LgwagDhT/74N3Lys7cxA0UwWYMUUmxyTbwhgMNRbDiAwiV+dE5e316nFW70RTUYUux18Wbc9pEDUMyVTe2C0jXjHPooZW41gfXU/fQMSA3GtsH4Nhi/Bcauk7EdltAQ9+2AuXHF/LGz0sxjqVjHX5WG2cGBmmXaQks5W/WmLYHF+jr3zR5V3Q3x9CkJ4Pjphzeph29GAArmTj28ST3sp9kF/3OjAhh8U2ar67oEoDhy+iF15ob8L4OtBiCw+MLDaj/cpP/HMUoAAoupcCjbi28K4PKqCKCJomvhwtgapzbjwX1q1v8AwN4AzxG4R1MAAAAASUVORK5CYII=","e":1},{"id":"image_2","w":258,"h":24,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_3","w":258,"h":30,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_4","w":108,"h":108,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_5","w":450,"h":450,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_6","w":504,"h":504,"u":"","p":"data:image/png;base64,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","e":1},{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":2,"nm":"小帽子","parent":3,"refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[129,-12,0],"ix":2},"a":{"a":0,"k":[36,6,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"弹簧","parent":3,"refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.45,"y":1},"o":{"x":0.55,"y":0},"t":30,"s":[130.431,-48.53,0],"e":[130.431,-31.53,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.45,"y":0.45},"o":{"x":0.55,"y":0.55},"t":35,"s":[130.431,-31.53,0],"e":[130.431,-31.53,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.45,"y":1},"o":{"x":0.55,"y":0},"t":40,"s":[130.431,-31.53,0],"e":[130.431,-48.53,0],"to":[0,0,0],"ti":[0,0,0]},{"t":45}],"ix":2},"a":{"a":0,"k":[22,38.5,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.45,0.45,0.45],"y":[1,1,1]},"o":{"x":[0.55,0.55,0.55],"y":[0,0,0]},"t":30,"s":[97.471,97.471,100],"e":[97.471,42.926,100]},{"i":{"x":[0.45,0.45,0.45],"y":[1,1,1]},"o":{"x":[0.55,0.55,0.55],"y":[0,0,0]},"t":35,"s":[97.471,42.926,100],"e":[97.471,42.926,100]},{"i":{"x":[0.45,0.45,0.45],"y":[1,1,1]},"o":{"x":[0.55,0.55,0.55],"y":[0,0,0]},"t":40,"s":[97.471,42.926,100],"e":[97.471,97.471,100]},{"t":45}],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"上压缩盖","refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.32,"y":1},"o":{"x":0.68,"y":0},"t":20,"s":[300,246,0],"e":[300,390.09,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.3,"y":0.3},"o":{"x":0.68,"y":0.68},"t":35,"s":[300,390.09,0],"e":[300,390.09,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.3,"y":1},"o":{"x":0.7,"y":0},"t":40,"s":[300,390.09,0],"e":[300,246.09,0],"to":[0,0,0],"ti":[0,0,0]},{"t":55}],"ix":2},"a":{"a":0,"k":[129,12,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"下压缩盖","refId":"image_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,417,0],"ix":2},"a":{"a":0,"k":[129,15,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"icon_yasuo_home","refId":"image_4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0],"e":[100]},{"t":15}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.35,"y":1},"o":{"x":0.167,"y":0},"t":0,"s":[601.689,330,0],"e":[300,330,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.35,"y":0.35},"o":{"x":0.167,"y":0.167},"t":15,"s":[300,330,0],"e":[300,330,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"t":20,"s":[300,330,0],"e":[300,409.925,0],"to":[0,0,0],"ti":[0,0,0]},{"t":35}],"ix":2},"a":{"a":0,"k":[54,54,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":20,"s":[100,100,100],"e":[20,20,100]},{"t":35}],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"白色实心圆-小","refId":"image_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[225,225,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"白色边框圆-大","refId":"image_6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20.625,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34.375,"s":[100],"e":[0]},{"t":55}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[252,252,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100],"e":[118.254,118.254,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":20.625,"s":[118.254,118.254,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":34.375,"s":[100,100,100],"e":[118.254,118.254,100]},{"t":55}],"ix":6}},"ao":0,"ip":0,"op":75,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":55,"s":[100],"e":[0]},{"t":69}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":0,"op":75,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
...@@ -19,6 +19,10 @@ class Singleton { ...@@ -19,6 +19,10 @@ class Singleton {
var maxDeleteCount : Int = 25 var maxDeleteCount : Int = 25
var trashData : [TrashTypeEnum : [AssetModel]] = [:]
var keepList : [TrashTypeEnum : [AssetModel]] = [:]
var photoPermission : PrivacyType? var photoPermission : PrivacyType?
......
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