keep edit
This commit is contained in:
@@ -34,7 +34,6 @@
|
||||
18E7B31826F097E00064BC9B /* UserInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E7B31726F097E00064BC9B /* UserInfoModel.m */; };
|
||||
23116B0B2BDB8FDC00F7F97A /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2368ECD72BC38FED00EDF4C9 /* PrivacyInfo.xcprivacy */; };
|
||||
232EBBFF2BD7A25500E8CEAD /* MSParamsDecode.m in Sources */ = {isa = PBXBuildFile; fileRef = 232EBBFE2BD7A25500E8CEAD /* MSParamsDecode.m */; };
|
||||
2331C1BD2A60F69E00E1D940 /* UILabel+Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 2331C1BC2A60F69E00E1D940 /* UILabel+Utils.m */; };
|
||||
235A45232B04BEB6009753F5 /* PIBaseModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 235A45222B04BEB6009753F5 /* PIBaseModel.m */; };
|
||||
2368ECCF2BC38F9800EDF4C9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2368ECCD2BC38F9800EDF4C9 /* InfoPlist.strings */; };
|
||||
2368ECD32BC38FDA00EDF4C9 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2368ECD52BC38FDA00EDF4C9 /* Launch Screen.storyboard */; };
|
||||
@@ -45,7 +44,6 @@
|
||||
2377010E2BCF73F400D661F1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2377010D2BCF73F400D661F1 /* CoreGraphics.framework */; };
|
||||
237701102BCF740400D661F1 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 2377010F2BCF740400D661F1 /* libsqlite3.tbd */; };
|
||||
237701122BCF742C00D661F1 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 237701112BCF742C00D661F1 /* libz.tbd */; };
|
||||
23959FE72BB15C930085A282 /* UploadFileModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 23959FE62BB15C930085A282 /* UploadFileModel.m */; };
|
||||
23CEFC4A2AFB8FC100576D89 /* BSNSStringUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CEFC0C2AFB8FC100576D89 /* BSNSStringUtil.m */; };
|
||||
23CEFC4B2AFB8FC100576D89 /* BSUIDemoUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CEFC0D2AFB8FC100576D89 /* BSUIDemoUtil.m */; };
|
||||
23CEFC4C2AFB8FC100576D89 /* BS_UIColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 23CEFC0F2AFB8FC100576D89 /* BS_UIColor.m */; };
|
||||
@@ -138,11 +136,9 @@
|
||||
4CF464322EA1277C005E96C0 /* TTAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF464222EA1277C005E96C0 /* TTAlertView.m */; };
|
||||
73FFADDC93E195344047A2EC /* Pods_YuMi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CACF623970097D653132D69A /* Pods_YuMi.framework */; };
|
||||
9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B0E1C5826E77022005D4442 /* BaseNavigationController.m */; };
|
||||
9B33E3CB27D85379003B0E62 /* UploadFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B33E3C927D85379003B0E62 /* UploadFile.m */; };
|
||||
9BA8A47527C60D9F000365A3 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BA8A47427C60D9F000365A3 /* AudioToolbox.framework */; };
|
||||
9BA8A47727C60DF7000365A3 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BA8A47627C60DF7000365A3 /* AVFoundation.framework */; };
|
||||
E8098CA7282E00920090B9F0 /* Api+Moments.m in Sources */ = {isa = PBXBuildFile; fileRef = E8098CA6282E00920090B9F0 /* Api+Moments.m */; };
|
||||
E80CBDEA27D0C53F001E1EC2 /* XPWeakTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = E80CBDE927D0C53F001E1EC2 /* XPWeakTimer.m */; };
|
||||
E80E09A92A40B70100CD2BE7 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E80E09AB2A40B70100CD2BE7 /* Localizable.strings */; };
|
||||
E80E2377299A47F60013FD40 /* AESUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E80E2376299A47F60013FD40 /* AESUtils.m */; };
|
||||
E81366E726F0A49E0076364C /* NSString+Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = E81366E626F0A49E0076364C /* NSString+Utils.m */; };
|
||||
@@ -237,8 +233,6 @@
|
||||
18E7B31726F097E00064BC9B /* UserInfoModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UserInfoModel.m; sourceTree = "<group>"; };
|
||||
232EBBFD2BD7A25500E8CEAD /* MSParamsDecode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MSParamsDecode.h; sourceTree = "<group>"; };
|
||||
232EBBFE2BD7A25500E8CEAD /* MSParamsDecode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MSParamsDecode.m; sourceTree = "<group>"; };
|
||||
2331C1BB2A60F69E00E1D940 /* UILabel+Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UILabel+Utils.h"; sourceTree = "<group>"; };
|
||||
2331C1BC2A60F69E00E1D940 /* UILabel+Utils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UILabel+Utils.m"; sourceTree = "<group>"; };
|
||||
235A45212B04BEB6009753F5 /* PIBaseModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PIBaseModel.h; sourceTree = "<group>"; };
|
||||
235A45222B04BEB6009753F5 /* PIBaseModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PIBaseModel.m; sourceTree = "<group>"; };
|
||||
2368ECCA2BC38F6F00EDF4C9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
@@ -254,8 +248,6 @@
|
||||
2377010D2BCF73F400D661F1 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
2377010F2BCF740400D661F1 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
|
||||
237701112BCF742C00D661F1 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
23959FE52BB15C930085A282 /* UploadFileModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UploadFileModel.h; sourceTree = "<group>"; };
|
||||
23959FE62BB15C930085A282 /* UploadFileModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UploadFileModel.m; sourceTree = "<group>"; };
|
||||
23CEFC0B2AFB8FC100576D89 /* BSXWDateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSXWDateUtil.h; sourceTree = "<group>"; };
|
||||
23CEFC0C2AFB8FC100576D89 /* BSNSStringUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSNSStringUtil.m; sourceTree = "<group>"; };
|
||||
23CEFC0D2AFB8FC100576D89 /* BSUIDemoUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSUIDemoUtil.m; sourceTree = "<group>"; };
|
||||
@@ -417,16 +409,12 @@
|
||||
7DB00EC07F1D0ADFF900B38D /* Pods-YuMi.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YuMi.debug.xcconfig"; path = "Target Support Files/Pods-YuMi/Pods-YuMi.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9B0E1C5726E77022005D4442 /* BaseNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseNavigationController.h; sourceTree = "<group>"; };
|
||||
9B0E1C5826E77022005D4442 /* BaseNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseNavigationController.m; sourceTree = "<group>"; };
|
||||
9B33E3C927D85379003B0E62 /* UploadFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UploadFile.m; sourceTree = "<group>"; };
|
||||
9B33E3CA27D85379003B0E62 /* UploadFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UploadFile.h; sourceTree = "<group>"; };
|
||||
9BA8A47427C60D9F000365A3 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
9BA8A47627C60DF7000365A3 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
||||
B66633E061B1B34177CD011C /* Pods-YuMi.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YuMi.release.xcconfig"; path = "Target Support Files/Pods-YuMi/Pods-YuMi.release.xcconfig"; sourceTree = "<group>"; };
|
||||
CACF623970097D653132D69A /* Pods_YuMi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_YuMi.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E8098CA5282E00920090B9F0 /* Api+Moments.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Api+Moments.h"; sourceTree = "<group>"; };
|
||||
E8098CA6282E00920090B9F0 /* Api+Moments.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "Api+Moments.m"; sourceTree = "<group>"; };
|
||||
E80CBDE827D0C53F001E1EC2 /* XPWeakTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPWeakTimer.h; sourceTree = "<group>"; };
|
||||
E80CBDE927D0C53F001E1EC2 /* XPWeakTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPWeakTimer.m; sourceTree = "<group>"; };
|
||||
E80E2375299A47F60013FD40 /* AESUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AESUtils.h; sourceTree = "<group>"; };
|
||||
E80E2376299A47F60013FD40 /* AESUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AESUtils.m; sourceTree = "<group>"; };
|
||||
E81366E526F0A49E0076364C /* NSString+Utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+Utils.h"; sourceTree = "<group>"; };
|
||||
@@ -683,12 +671,9 @@
|
||||
23CEFC082AFB8FC100576D89 /* sdkContent */,
|
||||
E83645A42A40AEF600E0DBE4 /* Bundle */,
|
||||
E8F61356291E269700E12650 /* Safe */,
|
||||
9B33E3C827D85379003B0E62 /* File */,
|
||||
E80CBDE727D0C528001E1EC2 /* Timer */,
|
||||
180116F6279E8C3100F2CBC0 /* Date */,
|
||||
E88863D0278ED4A0004BCFAB /* Timestamp */,
|
||||
E8EEB8EA26FC2050007C6EBA /* SDPhotoBrowser */,
|
||||
2331C1BA2A60F67F00E1D940 /* UILabel */,
|
||||
E81366E426F0A4820076364C /* NSString */,
|
||||
E82109AA26F1C86E00FC3319 /* CountDown */,
|
||||
E81C278726EAFABF0031E639 /* Security */,
|
||||
@@ -748,15 +733,6 @@
|
||||
path = YMTabbar;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2331C1BA2A60F67F00E1D940 /* UILabel */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2331C1BB2A60F69E00E1D940 /* UILabel+Utils.h */,
|
||||
2331C1BC2A60F69E00E1D940 /* UILabel+Utils.m */,
|
||||
);
|
||||
path = UILabel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
236B2E1B2AA0786E003967A8 /* Library */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -971,14 +947,14 @@
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4C0642752E97BD6D00BAF413 /* NewMine */ = {
|
||||
4C0642752E97BD6D00BAF413 /* Mine */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C1E98BE2E9A3A540031AE79 /* Services */,
|
||||
4C0642712E97BD6D00BAF413 /* Controllers */,
|
||||
4C0642742E97BD6D00BAF413 /* Views */,
|
||||
);
|
||||
path = NewMine;
|
||||
path = Mine;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4C0642782E97BD6D00BAF413 /* Controllers */ = {
|
||||
@@ -1011,32 +987,32 @@
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4C06427C2E97BD6D00BAF413 /* NewMoments */ = {
|
||||
4C06427C2E97BD6D00BAF413 /* Moments */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C0642952E98F76F00BAF413 /* Services */,
|
||||
4C0642782E97BD6D00BAF413 /* Controllers */,
|
||||
4C06427B2E97BD6D00BAF413 /* Views */,
|
||||
);
|
||||
path = NewMoments;
|
||||
path = Moments;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4C06427E2E97BD6D00BAF413 /* NewTabBar */ = {
|
||||
4C06427E2E97BD6D00BAF413 /* TabBar */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C06428A2E98DC5F00BAF413 /* EPTabBarController.swift */,
|
||||
);
|
||||
path = NewTabBar;
|
||||
path = TabBar;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4C0642922E98EF0A00BAF413 /* E-P */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4CD19C852E9CB31C0069DAA0 /* NewLogin */,
|
||||
4CD19C852E9CB31C0069DAA0 /* Login */,
|
||||
4C1E98C22E9A45160031AE79 /* Common */,
|
||||
4C0642752E97BD6D00BAF413 /* NewMine */,
|
||||
4C06427C2E97BD6D00BAF413 /* NewMoments */,
|
||||
4C06427E2E97BD6D00BAF413 /* NewTabBar */,
|
||||
4C0642752E97BD6D00BAF413 /* Mine */,
|
||||
4C06427C2E97BD6D00BAF413 /* Moments */,
|
||||
4C06427E2E97BD6D00BAF413 /* TabBar */,
|
||||
);
|
||||
path = "E-P";
|
||||
sourceTree = "<group>";
|
||||
@@ -1109,7 +1085,7 @@
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4CD19C852E9CB31C0069DAA0 /* NewLogin */ = {
|
||||
4CD19C852E9CB31C0069DAA0 /* Login */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4CD19C8D2E9CBBC80069DAA0 /* Services */,
|
||||
@@ -1117,7 +1093,7 @@
|
||||
4CD19C812E9CB31C0069DAA0 /* Models */,
|
||||
4CD19C842E9CB31C0069DAA0 /* Views */,
|
||||
);
|
||||
path = NewLogin;
|
||||
path = Login;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4CD19C8D2E9CBBC80069DAA0 /* Services */ = {
|
||||
@@ -1328,17 +1304,6 @@
|
||||
path = TTPopup;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9B33E3C827D85379003B0E62 /* File */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9B33E3CA27D85379003B0E62 /* UploadFile.h */,
|
||||
9B33E3C927D85379003B0E62 /* UploadFile.m */,
|
||||
23959FE52BB15C930085A282 /* UploadFileModel.h */,
|
||||
23959FE62BB15C930085A282 /* UploadFileModel.m */,
|
||||
);
|
||||
path = File;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9B9DFDA227DB4F68000F95B3 /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1373,15 +1338,6 @@
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E80CBDE727D0C528001E1EC2 /* Timer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E80CBDE827D0C53F001E1EC2 /* XPWeakTimer.h */,
|
||||
E80CBDE927D0C53F001E1EC2 /* XPWeakTimer.m */,
|
||||
);
|
||||
path = Timer;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E81366E426F0A4820076364C /* NSString */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1743,7 +1699,6 @@
|
||||
18E7B31826F097E00064BC9B /* UserInfoModel.m in Sources */,
|
||||
4C0642912E98DC8700BAF413 /* EPMomentViewController.m in Sources */,
|
||||
232EBBFF2BD7A25500E8CEAD /* MSParamsDecode.m in Sources */,
|
||||
23959FE72BB15C930085A282 /* UploadFileModel.m in Sources */,
|
||||
189DD73F26E21C3F00AB55B1 /* YYUtility+Carrier.m in Sources */,
|
||||
23CEFC5D2AFB8FC100576D89 /* BSRecordModel.m in Sources */,
|
||||
9B0E1C5926E77022005D4442 /* BaseNavigationController.m in Sources */,
|
||||
@@ -1758,7 +1713,6 @@
|
||||
23CEFC622AFB8FC100576D89 /* BSLogNetDetailViewController.m in Sources */,
|
||||
4C7B909B2E9F822900A5E236 /* EPEmotionColorWheelView.m in Sources */,
|
||||
4C7B8F632E9F6E1300A5E236 /* EPSignatureColorGuideView.m in Sources */,
|
||||
9B33E3CB27D85379003B0E62 /* UploadFile.m in Sources */,
|
||||
4CD19EAE2E9CDFC30069DAA0 /* EPLoginButton.swift in Sources */,
|
||||
4CD19EAF2E9CDFC30069DAA0 /* EPLoginInputView.swift in Sources */,
|
||||
4C0642852E97BD9500BAF413 /* APIConfig.swift in Sources */,
|
||||
@@ -1788,7 +1742,6 @@
|
||||
187EEEDC26E89B32002833B2 /* BaseModel.m in Sources */,
|
||||
E80E2377299A47F60013FD40 /* AESUtils.m in Sources */,
|
||||
23CEFC642AFB8FC100576D89 /* BSkObject.m in Sources */,
|
||||
2331C1BD2A60F69E00E1D940 /* UILabel+Utils.m in Sources */,
|
||||
E83645A82A40AF5400E0DBE4 /* NSBundle+Localizable.m in Sources */,
|
||||
4C06429C2E99120600BAF413 /* EPMomentPublishViewController.m in Sources */,
|
||||
23CEFC632AFB8FC100576D89 /* BSRealTextView.m in Sources */,
|
||||
@@ -1816,7 +1769,6 @@
|
||||
4CD19C8E2E9CBBC80069DAA0 /* EPLoginService.swift in Sources */,
|
||||
4CD19C8F2E9CBBC80069DAA0 /* EPLoginManager.swift in Sources */,
|
||||
4C1E98BF2E9A3A540031AE79 /* EPMineAPIHelper.m in Sources */,
|
||||
E80CBDEA27D0C53F001E1EC2 /* XPWeakTimer.m in Sources */,
|
||||
189DD55026DE37F900AB55B1 /* MvpViewController.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by admin on 2023/3/9.
|
||||
//
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
15
YuMi/Appdelegate/AppDelegate.h.backup
Normal file
15
YuMi/Appdelegate/AppDelegate.h.backup
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// YUMI
|
||||
//
|
||||
// Created by admin on 2023/3/9.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@end
|
||||
|
@@ -1,9 +1,6 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by admin on 2023/3/9.
|
||||
//
|
||||
|
||||
|
||||
#import "AppDelegate.h"
|
||||
@@ -40,9 +37,9 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
|
||||
// MARK: - Helper Methods
|
||||
|
||||
/// 获取 keyWindow(iOS 13+ 兼容)
|
||||
|
||||
- (UIWindow *)getKeyWindow {
|
||||
// iOS 13+ 使用 connectedScenes 获取 window
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
||||
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
||||
@@ -51,13 +48,13 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
return window;
|
||||
}
|
||||
}
|
||||
// 如果没有 keyWindow,返回第一个 window
|
||||
|
||||
return scene.windows.firstObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iOS 13 以下,使用旧方法(已废弃但仍然可用)
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
return [UIApplication sharedApplication].keyWindow;
|
||||
@@ -74,44 +71,44 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
}else{
|
||||
[self toHomeTabbarPage];
|
||||
|
||||
// 延迟检查专属颜色(等待 window 初始化完成)
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[self checkAndShowSignatureColorGuide];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查并显示专属颜色引导页
|
||||
|
||||
- (void)checkAndShowSignatureColorGuide {
|
||||
UIWindow *keyWindow = [self getKeyWindow];
|
||||
if (!keyWindow) return;
|
||||
|
||||
BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor];
|
||||
|
||||
#if DEBUG
|
||||
// Debug 环境:总是显示引导页
|
||||
NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@)", hasSignatureColor ? @"YES" : @"NO");
|
||||
//#if DEBUG
|
||||
//
|
||||
// NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@)", hasSignatureColor ? @"YES" : @"NO");
|
||||
//
|
||||
// EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
|
||||
//
|
||||
//
|
||||
// guideView.onColorConfirmed = ^(NSString *hexColor) {
|
||||
// [EPEmotionColorStorage saveUserSignatureColor:hexColor];
|
||||
// NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor);
|
||||
// };
|
||||
//
|
||||
//
|
||||
// if (hasSignatureColor) {
|
||||
// guideView.onSkipTapped = ^{
|
||||
// NSLog(@"[AppDelegate] 用户跳过专属颜色选择");
|
||||
// };
|
||||
// }
|
||||
//
|
||||
//
|
||||
// [guideView showInWindow:keyWindow showSkipButton:hasSignatureColor];
|
||||
//
|
||||
//#else
|
||||
|
||||
EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
|
||||
|
||||
// 设置颜色确认回调
|
||||
guideView.onColorConfirmed = ^(NSString *hexColor) {
|
||||
[EPEmotionColorStorage saveUserSignatureColor:hexColor];
|
||||
NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor);
|
||||
};
|
||||
|
||||
// 如果已有颜色,设置 Skip 回调
|
||||
if (hasSignatureColor) {
|
||||
guideView.onSkipTapped = ^{
|
||||
NSLog(@"[AppDelegate] 用户跳过专属颜色选择");
|
||||
};
|
||||
}
|
||||
|
||||
// 显示引导页,已有颜色时显示 Skip 按钮
|
||||
[guideView showInWindow:keyWindow showSkipButton:hasSignatureColor];
|
||||
|
||||
#else
|
||||
// Release 环境:仅在未设置专属颜色时显示
|
||||
if (!hasSignatureColor) {
|
||||
EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
|
||||
guideView.onColorConfirmed = ^(NSString *hexColor) {
|
||||
@@ -120,11 +117,11 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
};
|
||||
[guideView showInWindow:keyWindow];
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
|
||||
- (void)toLoginPage {
|
||||
// 使用新的 Swift 登录页面
|
||||
|
||||
EPLoginViewController *lvc = [[EPLoginViewController alloc] init];
|
||||
BaseNavigationController *navigationController =
|
||||
[[BaseNavigationController alloc] initWithRootViewController:lvc];
|
||||
@@ -159,10 +156,10 @@ UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
case ATTrackingManagerAuthorizationStatusAuthorized:
|
||||
break;
|
||||
case ATTrackingManagerAuthorizationStatusNotDetermined: {
|
||||
// NSLog(@"用户未做选择或未弹窗IDFA");
|
||||
//请求弹出用户授权框,只会在程序运行是弹框1次,除非卸载app重装,通地图、相机等权限弹框一样
|
||||
|
||||
|
||||
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
|
||||
// NSLog(@"app追踪IDFA权限:%lu",(unsigned long)status);
|
||||
|
||||
}];
|
||||
}
|
||||
break;
|
||||
|
176
YuMi/Appdelegate/AppDelegate.m.backup
Normal file
176
YuMi/Appdelegate/AppDelegate.m.backup
Normal file
@@ -0,0 +1,176 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// YUMI
|
||||
//
|
||||
// Created by admin on 2023/3/9.
|
||||
//
|
||||
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "BaseNavigationController.h"
|
||||
#import <AppTrackingTransparency/AppTrackingTransparency.h>
|
||||
#import "YuMi-swift.h"
|
||||
|
||||
UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
||||
UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:@"Launch Screen" bundle:nil];
|
||||
UIViewController *launchScreenVC = [launchStoryboard instantiateInitialViewController];
|
||||
self.window.rootViewController = launchScreenVC;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[self loadMainPage];
|
||||
|
||||
if (@available(iOS 15, *)) {
|
||||
[[UITableView appearance] setSectionHeaderTopPadding:0];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// MARK: - Helper Methods
|
||||
|
||||
/// 获取 keyWindow(iOS 13+ 兼容)
|
||||
- (UIWindow *)getKeyWindow {
|
||||
// iOS 13+ 使用 connectedScenes 获取 window
|
||||
if (@available(iOS 13.0, *)) {
|
||||
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
||||
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
||||
for (UIWindow *window in scene.windows) {
|
||||
if (window.isKeyWindow) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
// 如果没有 keyWindow,返回第一个 window
|
||||
return scene.windows.firstObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iOS 13 以下,使用旧方法(已废弃但仍然可用)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
return [UIApplication sharedApplication].keyWindow;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
|
||||
- (void)loadMainPage {
|
||||
AccountModel *accountModel = [[AccountInfoStorage instance] getCurrentAccountInfo];
|
||||
if (accountModel == nil ||
|
||||
accountModel.uid == nil ||
|
||||
accountModel.access_token == nil) {
|
||||
[self toLoginPage];
|
||||
}else{
|
||||
[self toHomeTabbarPage];
|
||||
|
||||
// 延迟检查专属颜色(等待 window 初始化完成)
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[self checkAndShowSignatureColorGuide];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查并显示专属颜色引导页
|
||||
- (void)checkAndShowSignatureColorGuide {
|
||||
UIWindow *keyWindow = [self getKeyWindow];
|
||||
if (!keyWindow) return;
|
||||
|
||||
BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor];
|
||||
|
||||
#if DEBUG
|
||||
// Debug 环境:总是显示引导页
|
||||
NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@)", hasSignatureColor ? @"YES" : @"NO");
|
||||
|
||||
EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
|
||||
|
||||
// 设置颜色确认回调
|
||||
guideView.onColorConfirmed = ^(NSString *hexColor) {
|
||||
[EPEmotionColorStorage saveUserSignatureColor:hexColor];
|
||||
NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor);
|
||||
};
|
||||
|
||||
// 如果已有颜色,设置 Skip 回调
|
||||
if (hasSignatureColor) {
|
||||
guideView.onSkipTapped = ^{
|
||||
NSLog(@"[AppDelegate] 用户跳过专属颜色选择");
|
||||
};
|
||||
}
|
||||
|
||||
// 显示引导页,已有颜色时显示 Skip 按钮
|
||||
[guideView showInWindow:keyWindow showSkipButton:hasSignatureColor];
|
||||
|
||||
#else
|
||||
// Release 环境:仅在未设置专属颜色时显示
|
||||
if (!hasSignatureColor) {
|
||||
EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init];
|
||||
guideView.onColorConfirmed = ^(NSString *hexColor) {
|
||||
[EPEmotionColorStorage saveUserSignatureColor:hexColor];
|
||||
NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor);
|
||||
};
|
||||
[guideView showInWindow:keyWindow];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)toLoginPage {
|
||||
// 使用新的 Swift 登录页面
|
||||
EPLoginViewController *lvc = [[EPLoginViewController alloc] init];
|
||||
BaseNavigationController *navigationController =
|
||||
[[BaseNavigationController alloc] initWithRootViewController:lvc];
|
||||
navigationController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||
self.window.rootViewController = navigationController;
|
||||
}
|
||||
|
||||
- (void)toHomeTabbarPage {
|
||||
EPTabBarController *epTabBar = [EPTabBarController create];
|
||||
[epTabBar refreshTabBarWithIsLogin:YES];
|
||||
|
||||
UIWindow *window = [self getKeyWindow];
|
||||
if (window) {
|
||||
window.rootViewController = epTabBar;
|
||||
[window makeKeyAndVisible];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
[self getAdvertisingTrackingAuthority];
|
||||
[[NSNotificationCenter defaultCenter]postNotificationName:@"kAppDidBecomeActive" object:nil];
|
||||
}
|
||||
|
||||
- (void)getAdvertisingTrackingAuthority {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
if (@available(iOS 14, *)) {
|
||||
ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus;
|
||||
switch (status) {
|
||||
case ATTrackingManagerAuthorizationStatusDenied:
|
||||
break;
|
||||
case ATTrackingManagerAuthorizationStatusAuthorized:
|
||||
break;
|
||||
case ATTrackingManagerAuthorizationStatusNotDetermined: {
|
||||
// NSLog(@"用户未做选择或未弹窗IDFA");
|
||||
//请求弹出用户授权框,只会在程序运行是弹框1次,除非卸载app重装,通地图、相机等权限弹框一样
|
||||
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
|
||||
// NSLog(@"app追踪IDFA权限:%lu",(unsigned long)status);
|
||||
}];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
@@ -1,44 +1,39 @@
|
||||
//
|
||||
// APIConfig.swift
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by AI on 2025-10-09.
|
||||
// Copyright © 2025 YuMi. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
import Foundation
|
||||
|
||||
/// API 域名配置类
|
||||
/// 使用 XOR + Base64 双重混淆防止反编译
|
||||
|
||||
@objc class APIConfig: NSObject {
|
||||
|
||||
// MARK: - Private Properties
|
||||
|
||||
/// XOR 加密密钥
|
||||
|
||||
private static let xorKey: UInt8 = 77
|
||||
|
||||
/// RELEASE 环境域名(加密后)
|
||||
/// 原始域名:https://api.epartylive.com
|
||||
|
||||
private static let releaseEncodedParts: [String] = [
|
||||
"JTk5PT53YmI=", // https:// (XOR 后 Base64)
|
||||
"LD0kYw==", // api. (XOR 后 Base64)
|
||||
"KD0sPzk0ISQ7KGMuIiA=", // epartylive.com (XOR 后 Base64)
|
||||
"JTk5PT53YmI=",
|
||||
"LD0kYw==",
|
||||
"KD0sPzk0ISQ7KGMuIiA=",
|
||||
]
|
||||
|
||||
// MARK: - Public Methods
|
||||
|
||||
/// 获取 API 基础域名
|
||||
/// - Returns: 根据编译环境返回对应的域名
|
||||
|
||||
@objc static func baseURL() -> String {
|
||||
#if DEBUG
|
||||
// DEV 环境:临时使用硬编码(等 Bridging 修复后再改回 HttpRequestHelper)
|
||||
|
||||
// TODO: 修复后改为 return HttpRequestHelper.getHostUrl()
|
||||
return getDevBaseURL()
|
||||
#else
|
||||
// RELEASE 环境:使用动态生成的新域名
|
||||
|
||||
let url = decodeURL(from: releaseEncodedParts)
|
||||
|
||||
// 验证解密结果
|
||||
|
||||
if url.isEmpty || !url.hasPrefix("http") {
|
||||
NSLog("[APIConfig] 警告:域名解密失败,使用备用域名")
|
||||
return backupURL()
|
||||
@@ -48,33 +43,29 @@ import Foundation
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 获取 DEV 环境域名(临时方案)
|
||||
/// - Returns: DEV 域名
|
||||
|
||||
private static func getDevBaseURL() -> String {
|
||||
// 从 UserDefaults 读取(原 HttpRequestHelper 的逻辑)
|
||||
|
||||
#if DEBUG
|
||||
let isProduction = UserDefaults.standard.string(forKey: "kIsProductionEnvironment")
|
||||
if isProduction == "YES" {
|
||||
return "https://api.epartylive.com" // 正式环境
|
||||
return "https://api.epartylive.com"
|
||||
} else {
|
||||
return "https://test-api.yourdomain.com" // 测试环境(请替换为实际测试域名)
|
||||
return "https://test-api.yourdomain.com"
|
||||
}
|
||||
#else
|
||||
return "https://api.epartylive.com"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 备用域名(降级方案)
|
||||
/// - Returns: 原域名(仅在解密失败时使用)
|
||||
|
||||
@objc static func backupURL() -> String {
|
||||
return getDevBaseURL()
|
||||
}
|
||||
|
||||
// MARK: - Private Methods
|
||||
|
||||
/// 解密域名
|
||||
/// - Parameter parts: 加密后的域名片段数组
|
||||
/// - Returns: 解密后的完整域名
|
||||
|
||||
private static func decodeURL(from parts: [String]) -> String {
|
||||
let decoded = parts.compactMap { part -> String? in
|
||||
guard let data = Data(base64Encoded: part) else {
|
||||
@@ -99,7 +90,7 @@ import Foundation
|
||||
|
||||
#if DEBUG
|
||||
extension APIConfig {
|
||||
/// 测试方法:验证域名加密/解密是否正常
|
||||
|
||||
@objc static func testEncryption() {
|
||||
print("=== APIConfig 加密测试 ===")
|
||||
print("Release 域名: \(decodeURL(from: releaseEncodedParts))")
|
||||
|
110
YuMi/Config/APIConfig.swift.backup
Normal file
110
YuMi/Config/APIConfig.swift.backup
Normal file
@@ -0,0 +1,110 @@
|
||||
//
|
||||
// APIConfig.swift
|
||||
// YuMi
|
||||
//
|
||||
// Created by AI on 2025-10-09.
|
||||
// Copyright © 2025 YuMi. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// API 域名配置类
|
||||
/// 使用 XOR + Base64 双重混淆防止反编译
|
||||
@objc class APIConfig: NSObject {
|
||||
|
||||
// MARK: - Private Properties
|
||||
|
||||
/// XOR 加密密钥
|
||||
private static let xorKey: UInt8 = 77
|
||||
|
||||
/// RELEASE 环境域名(加密后)
|
||||
/// 原始域名:https://api.epartylive.com
|
||||
private static let releaseEncodedParts: [String] = [
|
||||
"JTk5PT53YmI=", // https:// (XOR 后 Base64)
|
||||
"LD0kYw==", // api. (XOR 后 Base64)
|
||||
"KD0sPzk0ISQ7KGMuIiA=", // epartylive.com (XOR 后 Base64)
|
||||
]
|
||||
|
||||
// MARK: - Public Methods
|
||||
|
||||
/// 获取 API 基础域名
|
||||
/// - Returns: 根据编译环境返回对应的域名
|
||||
@objc static func baseURL() -> String {
|
||||
#if DEBUG
|
||||
// DEV 环境:临时使用硬编码(等 Bridging 修复后再改回 HttpRequestHelper)
|
||||
// TODO: 修复后改为 return HttpRequestHelper.getHostUrl()
|
||||
return getDevBaseURL()
|
||||
#else
|
||||
// RELEASE 环境:使用动态生成的新域名
|
||||
let url = decodeURL(from: releaseEncodedParts)
|
||||
|
||||
// 验证解密结果
|
||||
if url.isEmpty || !url.hasPrefix("http") {
|
||||
NSLog("[APIConfig] 警告:域名解密失败,使用备用域名")
|
||||
return backupURL()
|
||||
}
|
||||
|
||||
return url
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 获取 DEV 环境域名(临时方案)
|
||||
/// - Returns: DEV 域名
|
||||
private static func getDevBaseURL() -> String {
|
||||
// 从 UserDefaults 读取(原 HttpRequestHelper 的逻辑)
|
||||
#if DEBUG
|
||||
let isProduction = UserDefaults.standard.string(forKey: "kIsProductionEnvironment")
|
||||
if isProduction == "YES" {
|
||||
return "https://api.epartylive.com" // 正式环境
|
||||
} else {
|
||||
return "https://test-api.yourdomain.com" // 测试环境(请替换为实际测试域名)
|
||||
}
|
||||
#else
|
||||
return "https://api.epartylive.com"
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 备用域名(降级方案)
|
||||
/// - Returns: 原域名(仅在解密失败时使用)
|
||||
@objc static func backupURL() -> String {
|
||||
return getDevBaseURL()
|
||||
}
|
||||
|
||||
// MARK: - Private Methods
|
||||
|
||||
/// 解密域名
|
||||
/// - Parameter parts: 加密后的域名片段数组
|
||||
/// - Returns: 解密后的完整域名
|
||||
private static func decodeURL(from parts: [String]) -> String {
|
||||
let decoded = parts.compactMap { part -> String? in
|
||||
guard let data = Data(base64Encoded: part) else {
|
||||
NSLog("[APIConfig] Base64 解码失败: \(part)")
|
||||
return nil
|
||||
}
|
||||
let xored = data.map { $0 ^ xorKey }
|
||||
return String(bytes: xored, encoding: .utf8)
|
||||
}
|
||||
|
||||
let result = decoded.joined()
|
||||
|
||||
#if DEBUG
|
||||
NSLog("[APIConfig] 解密后的域名: \(result)")
|
||||
#endif
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Debug Helper
|
||||
|
||||
#if DEBUG
|
||||
extension APIConfig {
|
||||
/// 测试方法:验证域名加密/解密是否正常
|
||||
@objc static func testEncryption() {
|
||||
print("=== APIConfig 加密测试 ===")
|
||||
print("Release 域名: \(decodeURL(from: releaseEncodedParts))")
|
||||
print("当前环境域名: \(baseURL())")
|
||||
print("备用域名: \(backupURL())")
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// DJDKMIMOMColor.h
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by YUMI on 2021/9/9.
|
||||
//
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -13,62 +11,58 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DJDKMIMOMColor : NSObject
|
||||
/// 主题色0x9682FF
|
||||
|
||||
+ (UIColor *)appMainColor;
|
||||
///强调色 #248CFE
|
||||
|
||||
+ (UIColor *)appEmphasizeColor;
|
||||
///强调色1 0xBF36FF
|
||||
|
||||
+ (UIColor *)appEmphasizeColor1;
|
||||
///强调色2 0xFB486A
|
||||
|
||||
+ (UIColor *)appEmphasizeColor2;
|
||||
/* ------页面相关颜色 START------ */
|
||||
/// view的背景色 0xF3F5FA
|
||||
|
||||
|
||||
+ (UIColor *)appBackgroundColor;
|
||||
/// cell的背景色 0xFFFFFF
|
||||
|
||||
+ (UIColor *)appCellBackgroundColor;
|
||||
///正文颜色 0x333333
|
||||
|
||||
+ (UIColor *)mainTextColor;
|
||||
/// 二级文字颜色 0x666666
|
||||
|
||||
+ (UIColor *)secondTextColor;
|
||||
///三级文字的颜色 0x999999
|
||||
|
||||
+ (UIColor *)textThirdColor;
|
||||
///分割线的颜色 0xE8E8E8
|
||||
|
||||
+ (UIColor *)dividerColor;
|
||||
/* ------页面相关颜色 END------ */
|
||||
|
||||
/* ------Button 相关颜色 START------ */
|
||||
/// button 可用 渐变色的开始 0xFFA936
|
||||
|
||||
+ (UIColor *)confirmButtonGradientStartColor;
|
||||
/// button 可用 渐变色的中间 #9CB3FF
|
||||
+ (UIColor *)confirmButtonGradientMiddleColor;
|
||||
/// button 可用 渐变色的开始 0xFFCB47
|
||||
+ (UIColor *)confirmButtonGradientEndColor;
|
||||
/// 确定的按钮文字颜色 #FFFFFF
|
||||
+ (UIColor *)confirmButtonTextColor;
|
||||
/// 取消按钮 渐变色的开始 0xF7DDBF
|
||||
+ (UIColor *)cancelButtonGradientStartColor;
|
||||
/// 取消按钮 渐变色的结束 0xF7E8C4
|
||||
+ (UIColor *)cancelButtonGradientEndColor;
|
||||
/// 取消的按钮文字颜色 0xFFA936
|
||||
+ (UIColor *)cancelButtonTextColor;
|
||||
/// 取消按钮单一普通背景色 0xFFCE4E
|
||||
+ (UIColor *)cancelButtonNormalBgColor;
|
||||
/// 按钮不可点击背景色 0xD2D5D7
|
||||
+ (UIColor *)disableButtonColor;
|
||||
/// 按钮不可点击文字颜色 0xF9F9F9
|
||||
+ (UIColor *)disableButtonTextColor;
|
||||
/* ------Button 相关颜色 END------ */
|
||||
|
||||
/* ------弹窗相关颜色 START------ */
|
||||
+ (UIColor *)confirmButtonGradientMiddleColor;
|
||||
|
||||
+ (UIColor *)confirmButtonGradientEndColor;
|
||||
|
||||
+ (UIColor *)confirmButtonTextColor;
|
||||
|
||||
+ (UIColor *)cancelButtonGradientStartColor;
|
||||
|
||||
+ (UIColor *)cancelButtonGradientEndColor;
|
||||
|
||||
+ (UIColor *)cancelButtonTextColor;
|
||||
|
||||
+ (UIColor *)cancelButtonNormalBgColor;
|
||||
|
||||
+ (UIColor *)disableButtonColor;
|
||||
|
||||
+ (UIColor *)disableButtonTextColor;
|
||||
|
||||
|
||||
+ (UIColor *)alertBackgroundColor;
|
||||
+ (UIColor *)alertTitleColor;
|
||||
+ (UIColor *)alertMessageColor;
|
||||
+ (UIColor *)actionSeparatorColor;
|
||||
/* ------弹窗相关颜色 END------ */
|
||||
|
||||
///tabbar 没有点击的时候颜色 0x333333, 0.4
|
||||
|
||||
+ (UIColor *)tabbarNormalColor;
|
||||
/// tabbar的View的color 0xFFFFFF
|
||||
|
||||
+ (UIColor *)tabbarViewColor;
|
||||
|
||||
+ (UIColor *)colorWithHexString:(NSString *)hexString;
|
||||
|
79
YuMi/CustomUI/DJDKMIMOMColor.h.backup
Normal file
79
YuMi/CustomUI/DJDKMIMOMColor.h.backup
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// DJDKMIMOMColor.h
|
||||
// YUMI
|
||||
//
|
||||
// Created by YUMI on 2021/9/9.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
|
||||
|
||||
#define UIColorRGBAlpha(rgbValue,a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:(a)]
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface DJDKMIMOMColor : NSObject
|
||||
/// 主题色0x9682FF
|
||||
+ (UIColor *)appMainColor;
|
||||
///强调色 #248CFE
|
||||
+ (UIColor *)appEmphasizeColor;
|
||||
///强调色1 0xBF36FF
|
||||
+ (UIColor *)appEmphasizeColor1;
|
||||
///强调色2 0xFB486A
|
||||
+ (UIColor *)appEmphasizeColor2;
|
||||
/* ------页面相关颜色 START------ */
|
||||
/// view的背景色 0xF3F5FA
|
||||
+ (UIColor *)appBackgroundColor;
|
||||
/// cell的背景色 0xFFFFFF
|
||||
+ (UIColor *)appCellBackgroundColor;
|
||||
///正文颜色 0x333333
|
||||
+ (UIColor *)mainTextColor;
|
||||
/// 二级文字颜色 0x666666
|
||||
+ (UIColor *)secondTextColor;
|
||||
///三级文字的颜色 0x999999
|
||||
+ (UIColor *)textThirdColor;
|
||||
///分割线的颜色 0xE8E8E8
|
||||
+ (UIColor *)dividerColor;
|
||||
/* ------页面相关颜色 END------ */
|
||||
|
||||
/* ------Button 相关颜色 START------ */
|
||||
/// button 可用 渐变色的开始 0xFFA936
|
||||
+ (UIColor *)confirmButtonGradientStartColor;
|
||||
/// button 可用 渐变色的中间 #9CB3FF
|
||||
+ (UIColor *)confirmButtonGradientMiddleColor;
|
||||
/// button 可用 渐变色的开始 0xFFCB47
|
||||
+ (UIColor *)confirmButtonGradientEndColor;
|
||||
/// 确定的按钮文字颜色 #FFFFFF
|
||||
+ (UIColor *)confirmButtonTextColor;
|
||||
/// 取消按钮 渐变色的开始 0xF7DDBF
|
||||
+ (UIColor *)cancelButtonGradientStartColor;
|
||||
/// 取消按钮 渐变色的结束 0xF7E8C4
|
||||
+ (UIColor *)cancelButtonGradientEndColor;
|
||||
/// 取消的按钮文字颜色 0xFFA936
|
||||
+ (UIColor *)cancelButtonTextColor;
|
||||
/// 取消按钮单一普通背景色 0xFFCE4E
|
||||
+ (UIColor *)cancelButtonNormalBgColor;
|
||||
/// 按钮不可点击背景色 0xD2D5D7
|
||||
+ (UIColor *)disableButtonColor;
|
||||
/// 按钮不可点击文字颜色 0xF9F9F9
|
||||
+ (UIColor *)disableButtonTextColor;
|
||||
/* ------Button 相关颜色 END------ */
|
||||
|
||||
/* ------弹窗相关颜色 START------ */
|
||||
+ (UIColor *)alertBackgroundColor;
|
||||
+ (UIColor *)alertTitleColor;
|
||||
+ (UIColor *)alertMessageColor;
|
||||
+ (UIColor *)actionSeparatorColor;
|
||||
/* ------弹窗相关颜色 END------ */
|
||||
|
||||
///tabbar 没有点击的时候颜色 0x333333, 0.4
|
||||
+ (UIColor *)tabbarNormalColor;
|
||||
/// tabbar的View的color 0xFFFFFF
|
||||
+ (UIColor *)tabbarViewColor;
|
||||
|
||||
+ (UIColor *)colorWithHexString:(NSString *)hexString;
|
||||
|
||||
+ (UIColor *)inputTextColor;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,105 +1,99 @@
|
||||
//
|
||||
// DJDKMIMOMColor.m
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by YUMI on 2021/9/9.
|
||||
//
|
||||
|
||||
|
||||
#import "DJDKMIMOMColor.h"
|
||||
|
||||
@implementation DJDKMIMOMColor
|
||||
/// 主题色0x9682FF
|
||||
|
||||
+ (UIColor *)appMainColor {
|
||||
return UIColorFromRGB(0x9682FF);
|
||||
}
|
||||
|
||||
///强调色 #248CFE
|
||||
|
||||
+ (UIColor *)appEmphasizeColor {
|
||||
return UIColorFromRGB(0x248CFE);
|
||||
}
|
||||
|
||||
///强调色1 0xBF36FF
|
||||
|
||||
+ (UIColor *)appEmphasizeColor1 {
|
||||
return UIColorFromRGB(0xBF36FF);
|
||||
}
|
||||
|
||||
///强调色2 0xFB486A
|
||||
|
||||
+ (UIColor *)appEmphasizeColor2 {
|
||||
return UIColorFromRGB(0xFB486A);
|
||||
}
|
||||
|
||||
/* ------页面相关颜色 START------ */
|
||||
/// view的背景色 0xF3F5FA
|
||||
|
||||
+ (UIColor *)appBackgroundColor {
|
||||
return UIColorFromRGB(0xF3F5FA);
|
||||
}
|
||||
/// cell的背景色 0xFFFFFF
|
||||
|
||||
+ (UIColor *)appCellBackgroundColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
///正文颜色 0x333333
|
||||
|
||||
+ (UIColor *)mainTextColor {
|
||||
return UIColorFromRGB(0x161958);
|
||||
}
|
||||
/// 二级文字颜色 0x666666
|
||||
|
||||
+ (UIColor *)secondTextColor {
|
||||
return UIColorFromRGB(0x8A8CAB);
|
||||
}
|
||||
///三级文字的颜色 0x999999
|
||||
|
||||
+ (UIColor *)textThirdColor {
|
||||
return UIColorFromRGB(0xBABBCD);
|
||||
}
|
||||
///分割线的颜色 0xE8E8E8
|
||||
|
||||
+ (UIColor *)dividerColor {
|
||||
return UIColorFromRGB(0xE8E8E8);
|
||||
}
|
||||
/* ------页面相关颜色 END------ */
|
||||
|
||||
/* ------Button 相关颜色 START------ */
|
||||
/// button 可用 渐变色的开始 0x3CAAFF
|
||||
|
||||
+ (UIColor *)confirmButtonGradientStartColor {
|
||||
return UIColorFromRGB(0x13E2F5);
|
||||
}
|
||||
/// button 可用 渐变色的开始 0xB176FF
|
||||
|
||||
+ (UIColor *)confirmButtonGradientEndColor {
|
||||
return UIColorFromRGB(0xCC66FF);
|
||||
}
|
||||
/// 确定的按钮文字颜色 #FFFFFF
|
||||
|
||||
+ (UIColor *)confirmButtonTextColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
/// 取消按钮 渐变色的开始 0xF7DDBF
|
||||
|
||||
+ (UIColor *)cancelButtonGradientStartColor {
|
||||
return UIColorFromRGB(0xCEEFFD);
|
||||
}
|
||||
|
||||
/// button 可用 渐变色的中间 #9CB3FF
|
||||
|
||||
+ (UIColor *)confirmButtonGradientMiddleColor {
|
||||
return UIColorFromRGB(0xf9CB3FF);
|
||||
}
|
||||
/// 取消按钮 渐变色的结束 0xF7E8C4
|
||||
|
||||
+ (UIColor *)cancelButtonGradientEndColor {
|
||||
return UIColorFromRGB(0xD2F4F4);
|
||||
}
|
||||
/// 取消的按钮文字颜色 0xFFA936
|
||||
|
||||
+ (UIColor *)cancelButtonTextColor {
|
||||
return UIColorFromRGB(0x5FCCE4);
|
||||
}
|
||||
/// 取消按钮单一普通背景色 0xFFCE4E
|
||||
|
||||
+ (UIColor *)cancelButtonNormalBgColor {
|
||||
return UIColorFromRGB(0xCEEFFD);
|
||||
}
|
||||
/// 按钮不可点击背景色 0xD2D5D7
|
||||
|
||||
+ (UIColor *)disableButtonColor {
|
||||
return UIColorFromRGB(0xCEEFFD);
|
||||
}
|
||||
/// 按钮不可点击文字颜色 0xF9F9F9
|
||||
|
||||
+ (UIColor *)disableButtonTextColor {
|
||||
return UIColorFromRGB(0xB3B3C3);
|
||||
}
|
||||
/* ------Button 相关颜色 END------ */
|
||||
|
||||
/* ------弹窗相关颜色 START------ */
|
||||
|
||||
+ (UIColor *)alertBackgroundColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
@@ -112,13 +106,12 @@
|
||||
+ (UIColor *)actionSeparatorColor {
|
||||
return UIColorFromRGB(0xF0F0F0);
|
||||
}
|
||||
/* ------弹窗相关颜色 END------ */
|
||||
|
||||
///tabbar 没有点击的时候颜色 0x333333, 0.4
|
||||
|
||||
+ (UIColor *)tabbarNormalColor {
|
||||
return UIColorRGBAlpha(0x333333, 0.4);
|
||||
}
|
||||
/// tabbar的View的color 0xFFFFFF
|
||||
|
||||
+ (UIColor *)tabbarViewColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
@@ -130,25 +123,25 @@
|
||||
NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
|
||||
CGFloat alpha, red, blue, green;
|
||||
switch ([colorString length]) {
|
||||
case 3: // #RGB
|
||||
case 3:
|
||||
alpha = 1.0f;
|
||||
red = [self colorComponentFrom: colorString start: 0 length: 1];
|
||||
green = [self colorComponentFrom: colorString start: 1 length: 1];
|
||||
blue = [self colorComponentFrom: colorString start: 2 length: 1];
|
||||
break;
|
||||
case 4: // #ARGB
|
||||
case 4:
|
||||
alpha = [self colorComponentFrom: colorString start: 0 length: 1];
|
||||
red = [self colorComponentFrom: colorString start: 1 length: 1];
|
||||
green = [self colorComponentFrom: colorString start: 2 length: 1];
|
||||
blue = [self colorComponentFrom: colorString start: 3 length: 1];
|
||||
break;
|
||||
case 6: // #RRGGBB
|
||||
case 6:
|
||||
alpha = 1.0f;
|
||||
red = [self colorComponentFrom: colorString start: 0 length: 2];
|
||||
green = [self colorComponentFrom: colorString start: 2 length: 2];
|
||||
blue = [self colorComponentFrom: colorString start: 4 length: 2];
|
||||
break;
|
||||
case 8: // #AARRGGBB
|
||||
case 8:
|
||||
alpha = [self colorComponentFrom: colorString start: 0 length: 2];
|
||||
red = [self colorComponentFrom: colorString start: 2 length: 2];
|
||||
green = [self colorComponentFrom: colorString start: 4 length: 2];
|
||||
@@ -169,7 +162,7 @@
|
||||
return hexComponent / 255.0;
|
||||
}
|
||||
|
||||
///输入框的文本颜色 #1F1A4E
|
||||
|
||||
+ (UIColor *)inputTextColor {
|
||||
return [self colorWithHexString:@"#1F1A4E"];
|
||||
}
|
||||
|
177
YuMi/CustomUI/DJDKMIMOMColor.m.backup
Normal file
177
YuMi/CustomUI/DJDKMIMOMColor.m.backup
Normal file
@@ -0,0 +1,177 @@
|
||||
//
|
||||
// DJDKMIMOMColor.m
|
||||
// YUMI
|
||||
//
|
||||
// Created by YUMI on 2021/9/9.
|
||||
//
|
||||
|
||||
#import "DJDKMIMOMColor.h"
|
||||
|
||||
@implementation DJDKMIMOMColor
|
||||
/// 主题色0x9682FF
|
||||
+ (UIColor *)appMainColor {
|
||||
return UIColorFromRGB(0x9682FF);
|
||||
}
|
||||
|
||||
///强调色 #248CFE
|
||||
+ (UIColor *)appEmphasizeColor {
|
||||
return UIColorFromRGB(0x248CFE);
|
||||
}
|
||||
|
||||
///强调色1 0xBF36FF
|
||||
+ (UIColor *)appEmphasizeColor1 {
|
||||
return UIColorFromRGB(0xBF36FF);
|
||||
}
|
||||
|
||||
///强调色2 0xFB486A
|
||||
+ (UIColor *)appEmphasizeColor2 {
|
||||
return UIColorFromRGB(0xFB486A);
|
||||
}
|
||||
|
||||
/* ------页面相关颜色 START------ */
|
||||
/// view的背景色 0xF3F5FA
|
||||
+ (UIColor *)appBackgroundColor {
|
||||
return UIColorFromRGB(0xF3F5FA);
|
||||
}
|
||||
/// cell的背景色 0xFFFFFF
|
||||
+ (UIColor *)appCellBackgroundColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
///正文颜色 0x333333
|
||||
+ (UIColor *)mainTextColor {
|
||||
return UIColorFromRGB(0x161958);
|
||||
}
|
||||
/// 二级文字颜色 0x666666
|
||||
+ (UIColor *)secondTextColor {
|
||||
return UIColorFromRGB(0x8A8CAB);
|
||||
}
|
||||
///三级文字的颜色 0x999999
|
||||
+ (UIColor *)textThirdColor {
|
||||
return UIColorFromRGB(0xBABBCD);
|
||||
}
|
||||
///分割线的颜色 0xE8E8E8
|
||||
+ (UIColor *)dividerColor {
|
||||
return UIColorFromRGB(0xE8E8E8);
|
||||
}
|
||||
/* ------页面相关颜色 END------ */
|
||||
|
||||
/* ------Button 相关颜色 START------ */
|
||||
/// button 可用 渐变色的开始 0x3CAAFF
|
||||
+ (UIColor *)confirmButtonGradientStartColor {
|
||||
return UIColorFromRGB(0x13E2F5);
|
||||
}
|
||||
/// button 可用 渐变色的开始 0xB176FF
|
||||
+ (UIColor *)confirmButtonGradientEndColor {
|
||||
return UIColorFromRGB(0xCC66FF);
|
||||
}
|
||||
/// 确定的按钮文字颜色 #FFFFFF
|
||||
+ (UIColor *)confirmButtonTextColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
/// 取消按钮 渐变色的开始 0xF7DDBF
|
||||
+ (UIColor *)cancelButtonGradientStartColor {
|
||||
return UIColorFromRGB(0xCEEFFD);
|
||||
}
|
||||
|
||||
/// button 可用 渐变色的中间 #9CB3FF
|
||||
+ (UIColor *)confirmButtonGradientMiddleColor {
|
||||
return UIColorFromRGB(0xf9CB3FF);
|
||||
}
|
||||
/// 取消按钮 渐变色的结束 0xF7E8C4
|
||||
+ (UIColor *)cancelButtonGradientEndColor {
|
||||
return UIColorFromRGB(0xD2F4F4);
|
||||
}
|
||||
/// 取消的按钮文字颜色 0xFFA936
|
||||
+ (UIColor *)cancelButtonTextColor {
|
||||
return UIColorFromRGB(0x5FCCE4);
|
||||
}
|
||||
/// 取消按钮单一普通背景色 0xFFCE4E
|
||||
+ (UIColor *)cancelButtonNormalBgColor {
|
||||
return UIColorFromRGB(0xCEEFFD);
|
||||
}
|
||||
/// 按钮不可点击背景色 0xD2D5D7
|
||||
+ (UIColor *)disableButtonColor {
|
||||
return UIColorFromRGB(0xCEEFFD);
|
||||
}
|
||||
/// 按钮不可点击文字颜色 0xF9F9F9
|
||||
+ (UIColor *)disableButtonTextColor {
|
||||
return UIColorFromRGB(0xB3B3C3);
|
||||
}
|
||||
/* ------Button 相关颜色 END------ */
|
||||
|
||||
/* ------弹窗相关颜色 START------ */
|
||||
+ (UIColor *)alertBackgroundColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
+ (UIColor *)alertTitleColor {
|
||||
return UIColorFromRGB(0x333333);
|
||||
}
|
||||
+ (UIColor *)alertMessageColor {
|
||||
return UIColorFromRGB(0x333333);
|
||||
}
|
||||
+ (UIColor *)actionSeparatorColor {
|
||||
return UIColorFromRGB(0xF0F0F0);
|
||||
}
|
||||
/* ------弹窗相关颜色 END------ */
|
||||
|
||||
///tabbar 没有点击的时候颜色 0x333333, 0.4
|
||||
+ (UIColor *)tabbarNormalColor {
|
||||
return UIColorRGBAlpha(0x333333, 0.4);
|
||||
}
|
||||
/// tabbar的View的color 0xFFFFFF
|
||||
+ (UIColor *)tabbarViewColor {
|
||||
return UIColorFromRGB(0xFFFFFF);
|
||||
}
|
||||
|
||||
+ (UIColor *)colorWithHexString: (NSString *) hexString {
|
||||
if (hexString.length == 0) {
|
||||
return [UIColor blackColor];
|
||||
}
|
||||
NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
|
||||
CGFloat alpha, red, blue, green;
|
||||
switch ([colorString length]) {
|
||||
case 3: // #RGB
|
||||
alpha = 1.0f;
|
||||
red = [self colorComponentFrom: colorString start: 0 length: 1];
|
||||
green = [self colorComponentFrom: colorString start: 1 length: 1];
|
||||
blue = [self colorComponentFrom: colorString start: 2 length: 1];
|
||||
break;
|
||||
case 4: // #ARGB
|
||||
alpha = [self colorComponentFrom: colorString start: 0 length: 1];
|
||||
red = [self colorComponentFrom: colorString start: 1 length: 1];
|
||||
green = [self colorComponentFrom: colorString start: 2 length: 1];
|
||||
blue = [self colorComponentFrom: colorString start: 3 length: 1];
|
||||
break;
|
||||
case 6: // #RRGGBB
|
||||
alpha = 1.0f;
|
||||
red = [self colorComponentFrom: colorString start: 0 length: 2];
|
||||
green = [self colorComponentFrom: colorString start: 2 length: 2];
|
||||
blue = [self colorComponentFrom: colorString start: 4 length: 2];
|
||||
break;
|
||||
case 8: // #AARRGGBB
|
||||
alpha = [self colorComponentFrom: colorString start: 0 length: 2];
|
||||
red = [self colorComponentFrom: colorString start: 2 length: 2];
|
||||
green = [self colorComponentFrom: colorString start: 4 length: 2];
|
||||
blue = [self colorComponentFrom: colorString start: 6 length: 2];
|
||||
break;
|
||||
default:
|
||||
[NSException raise:@"Invalid color value" format: @"Color value %@ is invalid. It should be a hex value of the form #RBG, #ARGB, #RRGGBB, or #AARRGGBB", hexString];
|
||||
break;
|
||||
}
|
||||
return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
|
||||
}
|
||||
|
||||
+ (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length {
|
||||
NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
|
||||
NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
|
||||
unsigned hexComponent;
|
||||
[[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
|
||||
return hexComponent / 255.0;
|
||||
}
|
||||
|
||||
///输入框的文本颜色 #1F1A4E
|
||||
+ (UIColor *)inputTextColor {
|
||||
return [self colorWithHexString:@"#1F1A4E"];
|
||||
}
|
||||
|
||||
@end
|
@@ -1,60 +1,46 @@
|
||||
//
|
||||
// TTActionSheetConfig.h
|
||||
// AFNetworking
|
||||
//
|
||||
// Created by lee on 2019/5/23.
|
||||
// action sheet item 配置
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
TTItemSelectNormal,
|
||||
TTItemSelectHighLight,
|
||||
} TTItemSelectType;
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef void(^TTActionSheetClickAction)(void);
|
||||
|
||||
@interface TTActionSheetConfig : NSObject
|
||||
|
||||
/** 标题 */
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
|
||||
/**
|
||||
标题颜色
|
||||
*/
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
/** 是否选中 */
|
||||
@property (nonatomic, assign) TTItemSelectType type;
|
||||
|
||||
/** 点击事件 */
|
||||
@property (nonatomic, copy) TTActionSheetClickAction clickAction;
|
||||
|
||||
@property(nonatomic, assign) BOOL displayMoliCoin;
|
||||
|
||||
/**
|
||||
构建 actionSheet item 实例
|
||||
|
||||
@param title 标题
|
||||
@param clickAction 点击事件
|
||||
@return item 实例
|
||||
*/
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title
|
||||
clickAction:(TTActionSheetClickAction)clickAction;
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title
|
||||
selectColorType:(TTItemSelectType)type clickAction:(TTActionSheetClickAction)clickAction;
|
||||
|
||||
|
||||
/// 构建实例
|
||||
/// @param title 标题
|
||||
/// @param textColor 颜色
|
||||
/// @param handler 事件处理
|
||||
+ (TTActionSheetConfig *)actionWithTitle:(NSString *)title
|
||||
color:(UIColor *)textColor
|
||||
handler:(TTActionSheetClickAction)handler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lee on 2019/5/23.
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
TTItemSelectNormal,
|
||||
TTItemSelectHighLight,
|
||||
} TTItemSelectType;
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef void(^TTActionSheetClickAction)(void);
|
||||
|
||||
@interface TTActionSheetConfig : NSObject
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
|
||||
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
|
||||
@property (nonatomic, assign) TTItemSelectType type;
|
||||
|
||||
|
||||
@property (nonatomic, copy) TTActionSheetClickAction clickAction;
|
||||
|
||||
@property(nonatomic, assign) BOOL displayMoliCoin;
|
||||
|
||||
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title
|
||||
clickAction:(TTActionSheetClickAction)clickAction;
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title
|
||||
selectColorType:(TTItemSelectType)type clickAction:(TTActionSheetClickAction)clickAction;
|
||||
|
||||
|
||||
+ (TTActionSheetConfig *)actionWithTitle:(NSString *)title
|
||||
color:(UIColor *)textColor
|
||||
handler:(TTActionSheetClickAction)handler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
60
YuMi/CustomUI/TTPopup/Config/TTActionSheetConfig.h.backup
Normal file
60
YuMi/CustomUI/TTPopup/Config/TTActionSheetConfig.h.backup
Normal file
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// TTActionSheetConfig.h
|
||||
// AFNetworking
|
||||
//
|
||||
// Created by lee on 2019/5/23.
|
||||
// action sheet item 配置
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
TTItemSelectNormal,
|
||||
TTItemSelectHighLight,
|
||||
} TTItemSelectType;
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef void(^TTActionSheetClickAction)(void);
|
||||
|
||||
@interface TTActionSheetConfig : NSObject
|
||||
|
||||
/** 标题 */
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
|
||||
/**
|
||||
标题颜色
|
||||
*/
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
/** 是否选中 */
|
||||
@property (nonatomic, assign) TTItemSelectType type;
|
||||
|
||||
/** 点击事件 */
|
||||
@property (nonatomic, copy) TTActionSheetClickAction clickAction;
|
||||
|
||||
@property(nonatomic, assign) BOOL displayMoliCoin;
|
||||
|
||||
/**
|
||||
构建 actionSheet item 实例
|
||||
|
||||
@param title 标题
|
||||
@param clickAction 点击事件
|
||||
@return item 实例
|
||||
*/
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title
|
||||
clickAction:(TTActionSheetClickAction)clickAction;
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title
|
||||
selectColorType:(TTItemSelectType)type clickAction:(TTActionSheetClickAction)clickAction;
|
||||
|
||||
|
||||
/// 构建实例
|
||||
/// @param title 标题
|
||||
/// @param textColor 颜色
|
||||
/// @param handler 事件处理
|
||||
+ (TTActionSheetConfig *)actionWithTitle:(NSString *)title
|
||||
color:(UIColor *)textColor
|
||||
handler:(TTActionSheetClickAction)handler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,22 +1,14 @@
|
||||
//
|
||||
// TTActionSheetConfig.m
|
||||
// AFNetworking
|
||||
//
|
||||
|
||||
|
||||
// Created by lee on 2019/5/23.
|
||||
//
|
||||
|
||||
|
||||
#import "TTActionSheetConfig.h"
|
||||
#import "DJDKMIMOMColor.h"
|
||||
|
||||
@implementation TTActionSheetConfig
|
||||
|
||||
/**
|
||||
构建 actionSheet item 实例
|
||||
|
||||
@param title 标题
|
||||
@param clickAction 点击事件
|
||||
@return item 实例
|
||||
*/
|
||||
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title clickAction:(TTActionSheetClickAction)clickAction {
|
||||
|
||||
return [self normalTitle:title selectColorType:TTItemSelectNormal clickAction:clickAction];
|
||||
|
49
YuMi/CustomUI/TTPopup/Config/TTActionSheetConfig.m.backup
Normal file
49
YuMi/CustomUI/TTPopup/Config/TTActionSheetConfig.m.backup
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// TTActionSheetConfig.m
|
||||
// AFNetworking
|
||||
//
|
||||
// Created by lee on 2019/5/23.
|
||||
//
|
||||
|
||||
#import "TTActionSheetConfig.h"
|
||||
#import "DJDKMIMOMColor.h"
|
||||
|
||||
@implementation TTActionSheetConfig
|
||||
|
||||
/**
|
||||
构建 actionSheet item 实例
|
||||
|
||||
@param title 标题
|
||||
@param clickAction 点击事件
|
||||
@return item 实例
|
||||
*/
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title clickAction:(TTActionSheetClickAction)clickAction {
|
||||
|
||||
return [self normalTitle:title selectColorType:TTItemSelectNormal clickAction:clickAction];
|
||||
}
|
||||
|
||||
+ (TTActionSheetConfig *)normalTitle:(NSString *)title selectColorType:(TTItemSelectType)type clickAction:(TTActionSheetClickAction)clickAction {
|
||||
|
||||
UIColor *color = type == TTItemSelectHighLight ? [DJDKMIMOMColor alertTitleColor] : [DJDKMIMOMColor alertTitleColor];
|
||||
|
||||
TTActionSheetConfig *config = [self actionWithTitle:title color:color handler:clickAction];
|
||||
config.type = type;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
+ (TTActionSheetConfig *)actionWithTitle:(NSString *)title
|
||||
color:(UIColor *)textColor
|
||||
handler:(TTActionSheetClickAction)handler {
|
||||
|
||||
TTActionSheetConfig *config = [[TTActionSheetConfig alloc] init];
|
||||
config.type = TTItemSelectNormal;
|
||||
config.title = title;
|
||||
config.titleColor = textColor;
|
||||
config.clickAction = handler;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -1,30 +1,28 @@
|
||||
//
|
||||
// TTAlertButtonConfig.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// alert 按钮配置
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertButtonConfig : NSObject
|
||||
/** 按钮标题 */
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
/** 按钮字体 */
|
||||
@property (nonatomic, strong) UIFont *font;
|
||||
/** 按钮字体颜色 */
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
/** 背景色 */
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
/** 背景图 */
|
||||
@property (nonatomic, strong) UIImage *backgroundImage;
|
||||
/** 圆角 */
|
||||
@property (nonatomic, assign) CGFloat cornerRadius;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertButtonConfig : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
|
||||
@property (nonatomic, strong) UIFont *font;
|
||||
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
|
||||
@property (nonatomic, strong) UIImage *backgroundImage;
|
||||
|
||||
@property (nonatomic, assign) CGFloat cornerRadius;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
30
YuMi/CustomUI/TTPopup/Config/TTAlertButtonConfig.h.backup
Normal file
30
YuMi/CustomUI/TTPopup/Config/TTAlertButtonConfig.h.backup
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// TTAlertButtonConfig.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// alert 按钮配置
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertButtonConfig : NSObject
|
||||
/** 按钮标题 */
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
/** 按钮字体 */
|
||||
@property (nonatomic, strong) UIFont *font;
|
||||
/** 按钮字体颜色 */
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
/** 背景色 */
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
/** 背景图 */
|
||||
@property (nonatomic, strong) UIImage *backgroundImage;
|
||||
/** 圆角 */
|
||||
@property (nonatomic, assign) CGFloat cornerRadius;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTAlertButtonConfig.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTAlertButtonConfig.h"
|
||||
|
||||
|
13
YuMi/CustomUI/TTPopup/Config/TTAlertButtonConfig.m.backup
Normal file
13
YuMi/CustomUI/TTPopup/Config/TTAlertButtonConfig.m.backup
Normal file
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// TTAlertButtonConfig.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTAlertButtonConfig.h"
|
||||
|
||||
@implementation TTAlertButtonConfig
|
||||
|
||||
@end
|
@@ -1,86 +1,70 @@
|
||||
//
|
||||
// TTAlertConfig.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// alert 配置
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTAlertButtonConfig.h"
|
||||
#import "TTAlertMessageAttributedConfig.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTAlertActionStyle) {
|
||||
TTAlertActionConfirmStyle = 0, // 只有确定按钮
|
||||
TTAlertActionCancelStyle = 1, // 只有取消按钮
|
||||
TTAlertActionBothStyle = 2, // 全部按钮
|
||||
};
|
||||
|
||||
|
||||
@interface TTAlertConfig : NSObject
|
||||
// 按钮显示风格
|
||||
@property (nonatomic, assign) TTAlertActionStyle actionStyle;
|
||||
// 容器背景设置
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
|
||||
// 标题设置
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, strong) UIFont *titleFont;
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
// 内容设置
|
||||
@property (nonatomic, copy) NSString *message;
|
||||
@property (nonatomic, strong) UIFont *messageFont;
|
||||
@property (nonatomic, strong) UIColor *messageColor;
|
||||
/** 内容的行间距,默认不设置,当值为 0 或负数时无效 */
|
||||
@property (nonatomic, assign) CGFloat messageLineSpacing;
|
||||
@property(nonatomic, assign) NSTextAlignment messageTextAlignment;
|
||||
/** 内容富文本配置 */
|
||||
@property (nonatomic, strong) NSArray<TTAlertMessageAttributedConfig *> *messageAttributedConfig;
|
||||
///配置内容的富文本
|
||||
@property (nonatomic,strong) NSMutableAttributedString *messageAttributed;
|
||||
|
||||
// 取消按钮配置
|
||||
@property (nonatomic, strong) TTAlertButtonConfig *cancelButtonConfig;
|
||||
|
||||
// 确定按钮配置
|
||||
@property (nonatomic, strong) TTAlertButtonConfig *confirmButtonConfig;
|
||||
|
||||
/**
|
||||
背景蒙层的透明度
|
||||
@Description 默认是 000000 黑色 0.3 alpha
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat maskBackgroundAlpha;
|
||||
|
||||
// 圆角
|
||||
@property (nonatomic, assign) CGFloat cornerRadius;
|
||||
|
||||
// 点击蒙层是否消失,默认:YES
|
||||
@property (nonatomic, assign) BOOL shouldDismissOnBackgroundTouch;
|
||||
|
||||
/**
|
||||
点击‘确定’‘取消’按钮时禁止弹窗自动消失,默认:NO
|
||||
|
||||
@discussion 若值为 YES,需要主动调用 [TTPopup dismiss] 消除弹窗
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL disableAutoDismissWhenClickButton;
|
||||
|
||||
/**
|
||||
重复弹窗过滤,默认:NO
|
||||
|
||||
@discussion 设置过滤时,队列中将不会出现相同过滤标识的弹窗
|
||||
过滤标识通过 #<filterIdentifier> 设置
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldFilterPopup;
|
||||
|
||||
/**
|
||||
过滤标识,默认:nil
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *filterIdentifier;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTAlertButtonConfig.h"
|
||||
#import "TTAlertMessageAttributedConfig.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTAlertActionStyle) {
|
||||
TTAlertActionConfirmStyle = 0,
|
||||
TTAlertActionCancelStyle = 1,
|
||||
TTAlertActionBothStyle = 2,
|
||||
};
|
||||
|
||||
|
||||
@interface TTAlertConfig : NSObject
|
||||
|
||||
@property (nonatomic, assign) TTAlertActionStyle actionStyle;
|
||||
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, strong) UIFont *titleFont;
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *message;
|
||||
@property (nonatomic, strong) UIFont *messageFont;
|
||||
@property (nonatomic, strong) UIColor *messageColor;
|
||||
|
||||
@property (nonatomic, assign) CGFloat messageLineSpacing;
|
||||
@property(nonatomic, assign) NSTextAlignment messageTextAlignment;
|
||||
|
||||
@property (nonatomic, strong) NSArray<TTAlertMessageAttributedConfig *> *messageAttributedConfig;
|
||||
|
||||
@property (nonatomic,strong) NSMutableAttributedString *messageAttributed;
|
||||
|
||||
|
||||
@property (nonatomic, strong) TTAlertButtonConfig *cancelButtonConfig;
|
||||
|
||||
|
||||
@property (nonatomic, strong) TTAlertButtonConfig *confirmButtonConfig;
|
||||
|
||||
|
||||
@property (nonatomic, assign) CGFloat maskBackgroundAlpha;
|
||||
|
||||
|
||||
@property (nonatomic, assign) CGFloat cornerRadius;
|
||||
|
||||
|
||||
@property (nonatomic, assign) BOOL shouldDismissOnBackgroundTouch;
|
||||
|
||||
|
||||
@property (nonatomic, assign) BOOL disableAutoDismissWhenClickButton;
|
||||
|
||||
|
||||
@property (nonatomic, assign) BOOL shouldFilterPopup;
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *filterIdentifier;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
86
YuMi/CustomUI/TTPopup/Config/TTAlertConfig.h.backup
Normal file
86
YuMi/CustomUI/TTPopup/Config/TTAlertConfig.h.backup
Normal file
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// TTAlertConfig.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// alert 配置
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTAlertButtonConfig.h"
|
||||
#import "TTAlertMessageAttributedConfig.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTAlertActionStyle) {
|
||||
TTAlertActionConfirmStyle = 0, // 只有确定按钮
|
||||
TTAlertActionCancelStyle = 1, // 只有取消按钮
|
||||
TTAlertActionBothStyle = 2, // 全部按钮
|
||||
};
|
||||
|
||||
|
||||
@interface TTAlertConfig : NSObject
|
||||
// 按钮显示风格
|
||||
@property (nonatomic, assign) TTAlertActionStyle actionStyle;
|
||||
// 容器背景设置
|
||||
@property (nonatomic, strong) UIColor *backgroundColor;
|
||||
|
||||
// 标题设置
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, strong) UIFont *titleFont;
|
||||
@property (nonatomic, strong) UIColor *titleColor;
|
||||
|
||||
// 内容设置
|
||||
@property (nonatomic, copy) NSString *message;
|
||||
@property (nonatomic, strong) UIFont *messageFont;
|
||||
@property (nonatomic, strong) UIColor *messageColor;
|
||||
/** 内容的行间距,默认不设置,当值为 0 或负数时无效 */
|
||||
@property (nonatomic, assign) CGFloat messageLineSpacing;
|
||||
@property(nonatomic, assign) NSTextAlignment messageTextAlignment;
|
||||
/** 内容富文本配置 */
|
||||
@property (nonatomic, strong) NSArray<TTAlertMessageAttributedConfig *> *messageAttributedConfig;
|
||||
///配置内容的富文本
|
||||
@property (nonatomic,strong) NSMutableAttributedString *messageAttributed;
|
||||
|
||||
// 取消按钮配置
|
||||
@property (nonatomic, strong) TTAlertButtonConfig *cancelButtonConfig;
|
||||
|
||||
// 确定按钮配置
|
||||
@property (nonatomic, strong) TTAlertButtonConfig *confirmButtonConfig;
|
||||
|
||||
/**
|
||||
背景蒙层的透明度
|
||||
@Description 默认是 000000 黑色 0.3 alpha
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat maskBackgroundAlpha;
|
||||
|
||||
// 圆角
|
||||
@property (nonatomic, assign) CGFloat cornerRadius;
|
||||
|
||||
// 点击蒙层是否消失,默认:YES
|
||||
@property (nonatomic, assign) BOOL shouldDismissOnBackgroundTouch;
|
||||
|
||||
/**
|
||||
点击‘确定’‘取消’按钮时禁止弹窗自动消失,默认:NO
|
||||
|
||||
@discussion 若值为 YES,需要主动调用 [TTPopup dismiss] 消除弹窗
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL disableAutoDismissWhenClickButton;
|
||||
|
||||
/**
|
||||
重复弹窗过滤,默认:NO
|
||||
|
||||
@discussion 设置过滤时,队列中将不会出现相同过滤标识的弹窗
|
||||
过滤标识通过 #<filterIdentifier> 设置
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldFilterPopup;
|
||||
|
||||
/**
|
||||
过滤标识,默认:nil
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *filterIdentifier;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTAlertConfig.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTAlertConfig.h"
|
||||
#import "UIImage+Utils.h"
|
||||
@@ -26,36 +24,35 @@ static CGFloat kAlertButtonCornerRadius = 8.f;
|
||||
|
||||
_backgroundColor = [DJDKMIMOMColor alertBackgroundColor];
|
||||
|
||||
//背景颜色
|
||||
|
||||
kAlertTitleFont = 16.f;
|
||||
kAlertCornerRadius = 14.f;
|
||||
kAlertButtonCornerRadius = 19.f;
|
||||
|
||||
_actionStyle = TTAlertActionBothStyle;
|
||||
|
||||
// title
|
||||
_title = @"";// 标题
|
||||
_titleFont = [UIFont fontWithName:@"PingFangSC-Medium" size:kAlertTitleFont];// 字体
|
||||
_titleColor = [DJDKMIMOMColor alertTitleColor];// 颜色
|
||||
|
||||
// message
|
||||
_title = @"";
|
||||
_titleFont = [UIFont fontWithName:@"PingFangSC-Medium" size:kAlertTitleFont];
|
||||
_titleColor = [DJDKMIMOMColor alertTitleColor];
|
||||
|
||||
|
||||
_message = @"";
|
||||
_messageFont = [UIFont systemFontOfSize:kAlertMessageFont];// 内容
|
||||
_messageColor = [DJDKMIMOMColor alertMessageColor];// 颜色
|
||||
_messageLineSpacing = kAlertMessageFontLineSpace;// 字体行间距
|
||||
_messageAttributedConfig = @[];// 自定义富文本样式
|
||||
_messageFont = [UIFont systemFontOfSize:kAlertMessageFont];
|
||||
_messageColor = [DJDKMIMOMColor alertMessageColor];
|
||||
_messageLineSpacing = kAlertMessageFontLineSpace;
|
||||
_messageAttributedConfig = @[];
|
||||
_messageTextAlignment = NSTextAlignmentCenter;
|
||||
|
||||
// cancel button
|
||||
|
||||
_cancelButtonConfig = [[TTAlertButtonConfig alloc] init];
|
||||
_cancelButtonConfig.title = YMLocalizedString(@"XPRoomSettingInputView4");// 取消按钮
|
||||
_cancelButtonConfig.font = [UIFont systemFontOfSize:kAlertButtonFont];// 按钮字体
|
||||
_cancelButtonConfig.titleColor = [DJDKMIMOMColor cancelButtonTextColor];// 字体颜色
|
||||
_cancelButtonConfig.title = YMLocalizedString(@"XPRoomSettingInputView4");
|
||||
_cancelButtonConfig.font = [UIFont systemFontOfSize:kAlertButtonFont];
|
||||
_cancelButtonConfig.titleColor = [DJDKMIMOMColor cancelButtonTextColor];
|
||||
_cancelButtonConfig.backgroundImage = [UIImage gradientColorImageFromColors:@[[DJDKMIMOMColor cancelButtonGradientStartColor], [DJDKMIMOMColor cancelButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
|
||||
_cancelButtonConfig.cornerRadius = kAlertButtonCornerRadius;// 按钮背景图
|
||||
_cancelButtonConfig.cornerRadius = kAlertButtonCornerRadius;
|
||||
|
||||
|
||||
// confirm button
|
||||
_confirmButtonConfig = [[TTAlertButtonConfig alloc] init];
|
||||
_confirmButtonConfig.title = YMLocalizedString(@"TTAlertConfig0");
|
||||
_confirmButtonConfig.font = [UIFont systemFontOfSize:kAlertButtonFont];
|
||||
@@ -65,22 +62,12 @@ static CGFloat kAlertButtonCornerRadius = 8.f;
|
||||
imgSize:CGSizeMake(10, 10)];
|
||||
_confirmButtonConfig.cornerRadius = kAlertButtonCornerRadius;
|
||||
|
||||
// // 创建渐变图层
|
||||
// CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
// gradientLayer.colors = @[(__bridge id)UIColorFromRGB(0xE29030).CGColor,
|
||||
// (__bridge id)UIColorFromRGB(0xFCC074).CGColor];
|
||||
// gradientLayer.startPoint = CGPointMake(0.0, 0.0); // 顶部中央
|
||||
// gradientLayer.endPoint = CGPointMake(0.0, 1.0); // 底部中央
|
||||
// gradientLayer.frame = CGRectMake(0, 0, 120, 38); // 设置渐变图层大小
|
||||
//
|
||||
// // 将渐变图层添加到按钮图层
|
||||
// [_previewActionButton.layer insertSublayer:gradientLayer atIndex:0];
|
||||
|
||||
_cornerRadius = kAlertCornerRadius;// 默认圆角
|
||||
_shouldDismissOnBackgroundTouch = YES;// 点击蒙层是否消失
|
||||
_cornerRadius = kAlertCornerRadius;
|
||||
_shouldDismissOnBackgroundTouch = YES;
|
||||
|
||||
// mask default 0.3 black
|
||||
_maskBackgroundAlpha = kAlertBackgroundColorAlpha; // alert 背景色
|
||||
|
||||
_maskBackgroundAlpha = kAlertBackgroundColorAlpha;
|
||||
_disableAutoDismissWhenClickButton = NO;
|
||||
}
|
||||
return self;
|
||||
|
90
YuMi/CustomUI/TTPopup/Config/TTAlertConfig.m.backup
Normal file
90
YuMi/CustomUI/TTPopup/Config/TTAlertConfig.m.backup
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// TTAlertConfig.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTAlertConfig.h"
|
||||
#import "UIImage+Utils.h"
|
||||
#import "DJDKMIMOMColor.h"
|
||||
|
||||
static CGFloat kAlertTitleFont = 18.f;
|
||||
static CGFloat kAlertButtonFont = 15.f;
|
||||
static CGFloat kAlertMessageFont = 15.f;
|
||||
static CGFloat kAlertCornerRadius = 12.f;
|
||||
static CGFloat kAlertBackgroundColorAlpha = 0.3;
|
||||
static CGFloat kAlertMessageFontLineSpace = -1;
|
||||
static CGFloat kAlertButtonCornerRadius = 8.f;
|
||||
|
||||
@implementation TTAlertConfig
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
_backgroundColor = [DJDKMIMOMColor alertBackgroundColor];
|
||||
|
||||
//背景颜色
|
||||
kAlertTitleFont = 16.f;
|
||||
kAlertCornerRadius = 14.f;
|
||||
kAlertButtonCornerRadius = 19.f;
|
||||
|
||||
_actionStyle = TTAlertActionBothStyle;
|
||||
|
||||
// title
|
||||
_title = @"";// 标题
|
||||
_titleFont = [UIFont fontWithName:@"PingFangSC-Medium" size:kAlertTitleFont];// 字体
|
||||
_titleColor = [DJDKMIMOMColor alertTitleColor];// 颜色
|
||||
|
||||
// message
|
||||
_message = @"";
|
||||
_messageFont = [UIFont systemFontOfSize:kAlertMessageFont];// 内容
|
||||
_messageColor = [DJDKMIMOMColor alertMessageColor];// 颜色
|
||||
_messageLineSpacing = kAlertMessageFontLineSpace;// 字体行间距
|
||||
_messageAttributedConfig = @[];// 自定义富文本样式
|
||||
_messageTextAlignment = NSTextAlignmentCenter;
|
||||
|
||||
// cancel button
|
||||
_cancelButtonConfig = [[TTAlertButtonConfig alloc] init];
|
||||
_cancelButtonConfig.title = YMLocalizedString(@"XPRoomSettingInputView4");// 取消按钮
|
||||
_cancelButtonConfig.font = [UIFont systemFontOfSize:kAlertButtonFont];// 按钮字体
|
||||
_cancelButtonConfig.titleColor = [DJDKMIMOMColor cancelButtonTextColor];// 字体颜色
|
||||
_cancelButtonConfig.backgroundImage = [UIImage gradientColorImageFromColors:@[[DJDKMIMOMColor cancelButtonGradientStartColor], [DJDKMIMOMColor cancelButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(10, 10)];
|
||||
_cancelButtonConfig.cornerRadius = kAlertButtonCornerRadius;// 按钮背景图
|
||||
|
||||
|
||||
// confirm button
|
||||
_confirmButtonConfig = [[TTAlertButtonConfig alloc] init];
|
||||
_confirmButtonConfig.title = YMLocalizedString(@"TTAlertConfig0");
|
||||
_confirmButtonConfig.font = [UIFont systemFontOfSize:kAlertButtonFont];
|
||||
_confirmButtonConfig.titleColor = [DJDKMIMOMColor confirmButtonTextColor];
|
||||
_confirmButtonConfig.backgroundImage = [UIImage gradientColorImageFromColors:@[UIColorFromRGB(0xE29030), UIColorFromRGB(0xFCC074)]
|
||||
gradientType:GradientTypeLeftToRight
|
||||
imgSize:CGSizeMake(10, 10)];
|
||||
_confirmButtonConfig.cornerRadius = kAlertButtonCornerRadius;
|
||||
|
||||
// // 创建渐变图层
|
||||
// CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
// gradientLayer.colors = @[(__bridge id)UIColorFromRGB(0xE29030).CGColor,
|
||||
// (__bridge id)UIColorFromRGB(0xFCC074).CGColor];
|
||||
// gradientLayer.startPoint = CGPointMake(0.0, 0.0); // 顶部中央
|
||||
// gradientLayer.endPoint = CGPointMake(0.0, 1.0); // 底部中央
|
||||
// gradientLayer.frame = CGRectMake(0, 0, 120, 38); // 设置渐变图层大小
|
||||
//
|
||||
// // 将渐变图层添加到按钮图层
|
||||
// [_previewActionButton.layer insertSublayer:gradientLayer atIndex:0];
|
||||
|
||||
_cornerRadius = kAlertCornerRadius;// 默认圆角
|
||||
_shouldDismissOnBackgroundTouch = YES;// 点击蒙层是否消失
|
||||
|
||||
// mask default 0.3 black
|
||||
_maskBackgroundAlpha = kAlertBackgroundColorAlpha; // alert 背景色
|
||||
_disableAutoDismissWhenClickButton = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -1,34 +1,28 @@
|
||||
//
|
||||
// TTAlertContentAttributedConfig.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// alert 提示内容富文本配置
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertMessageAttributedConfig : NSObject
|
||||
|
||||
/** 富文本字段需要特殊显示的文本 */
|
||||
@property (nonatomic, copy) NSString *text;
|
||||
|
||||
/** 颜色 */
|
||||
@property (nonatomic, strong) UIColor *color;
|
||||
|
||||
/** 字体 */
|
||||
@property (nonatomic, strong) UIFont *font;
|
||||
|
||||
/**
|
||||
目标文本指定位置,一旦设置则无视 text 的值
|
||||
|
||||
@discussion 内容文本中出现相同的目标文本时,可通过设置 range 精确指定位置
|
||||
*/
|
||||
@property (nonatomic, assign) NSRange range;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertMessageAttributedConfig : NSObject
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *text;
|
||||
|
||||
|
||||
@property (nonatomic, strong) UIColor *color;
|
||||
|
||||
|
||||
@property (nonatomic, strong) UIFont *font;
|
||||
|
||||
|
||||
@property (nonatomic, assign) NSRange range;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// TTAlertContentAttributedConfig.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// alert 提示内容富文本配置
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertMessageAttributedConfig : NSObject
|
||||
|
||||
/** 富文本字段需要特殊显示的文本 */
|
||||
@property (nonatomic, copy) NSString *text;
|
||||
|
||||
/** 颜色 */
|
||||
@property (nonatomic, strong) UIColor *color;
|
||||
|
||||
/** 字体 */
|
||||
@property (nonatomic, strong) UIFont *font;
|
||||
|
||||
/**
|
||||
目标文本指定位置,一旦设置则无视 text 的值
|
||||
|
||||
@discussion 内容文本中出现相同的目标文本时,可通过设置 range 精确指定位置
|
||||
*/
|
||||
@property (nonatomic, assign) NSRange range;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTAlertContentAttributedConfig.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTAlertMessageAttributedConfig.h"
|
||||
|
||||
|
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// TTAlertContentAttributedConfig.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTAlertMessageAttributedConfig.h"
|
||||
|
||||
@implementation TTAlertMessageAttributedConfig
|
||||
|
||||
@end
|
@@ -1,38 +1,23 @@
|
||||
//
|
||||
// TTPopupConstants.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
Popup 组件通用回调
|
||||
*/
|
||||
typedef void(^TTPopupCompletionHandler)(void);
|
||||
|
||||
/**
|
||||
弹窗类型
|
||||
|
||||
- TTPopupStyleAlert: Alert
|
||||
- TTPopupStyleActionSheet: ActionSheet
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, TTPopupStyle) {
|
||||
TTPopupStyleAlert = 0,
|
||||
TTPopupStyleActionSheet
|
||||
};
|
||||
|
||||
/**
|
||||
弹窗优先级
|
||||
|
||||
- TTPopupPriorityNormal: 普通
|
||||
- TTPopupPriorityHigh: 高
|
||||
- TTPopupPriorityRequired: 必须
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, TTPopupPriority) {
|
||||
TTPopupPriorityNormal = 0,
|
||||
TTPopupPriorityHigh,
|
||||
TTPopupPriorityRequired
|
||||
};
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
typedef void(^TTPopupCompletionHandler)(void);
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTPopupStyle) {
|
||||
TTPopupStyleAlert = 0,
|
||||
TTPopupStyleActionSheet
|
||||
};
|
||||
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTPopupPriority) {
|
||||
TTPopupPriorityNormal = 0,
|
||||
TTPopupPriorityHigh,
|
||||
TTPopupPriorityRequired
|
||||
};
|
||||
|
38
YuMi/CustomUI/TTPopup/Header/TTPopupConstants.h.backup
Normal file
38
YuMi/CustomUI/TTPopup/Header/TTPopupConstants.h.backup
Normal file
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// TTPopupConstants.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/**
|
||||
Popup 组件通用回调
|
||||
*/
|
||||
typedef void(^TTPopupCompletionHandler)(void);
|
||||
|
||||
/**
|
||||
弹窗类型
|
||||
|
||||
- TTPopupStyleAlert: Alert
|
||||
- TTPopupStyleActionSheet: ActionSheet
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, TTPopupStyle) {
|
||||
TTPopupStyleAlert = 0,
|
||||
TTPopupStyleActionSheet
|
||||
};
|
||||
|
||||
/**
|
||||
弹窗优先级
|
||||
|
||||
- TTPopupPriorityNormal: 普通
|
||||
- TTPopupPriorityHigh: 高
|
||||
- TTPopupPriorityRequired: 必须
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, TTPopupPriority) {
|
||||
TTPopupPriorityNormal = 0,
|
||||
TTPopupPriorityHigh,
|
||||
TTPopupPriorityRequired
|
||||
};
|
@@ -1,24 +1,21 @@
|
||||
//
|
||||
// TTPopupManagerService.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupManagerServiceProtocol.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTPopupManagerService : NSObject<TTPopupManagerServiceProtocol>
|
||||
/**
|
||||
当前显示的弹窗服务
|
||||
*/
|
||||
@property (nonatomic, strong) id<TTPopupServiceProtocol> currentPopupService;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupManagerServiceProtocol.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTPopupManagerService : NSObject<TTPopupManagerServiceProtocol>
|
||||
|
||||
|
||||
@property (nonatomic, strong) id<TTPopupServiceProtocol> currentPopupService;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
24
YuMi/CustomUI/TTPopup/Manager/TTPopupManagerService.h.backup
Normal file
24
YuMi/CustomUI/TTPopup/Manager/TTPopupManagerService.h.backup
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// TTPopupManagerService.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupManagerServiceProtocol.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTPopupManagerService : NSObject<TTPopupManagerServiceProtocol>
|
||||
/**
|
||||
当前显示的弹窗服务
|
||||
*/
|
||||
@property (nonatomic, strong) id<TTPopupServiceProtocol> currentPopupService;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTPopupManagerService.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTPopupManagerService.h"
|
||||
|
||||
@@ -13,9 +11,8 @@
|
||||
@interface TTPopupManagerService ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray< id<TTPopupServiceProtocol> > *queue;
|
||||
/**
|
||||
当前是否正在显示状态
|
||||
*/
|
||||
|
||||
|
||||
@property (nonatomic, assign, getter=isShowingPopup) BOOL showingPopup;
|
||||
|
||||
@end
|
||||
@@ -53,7 +50,7 @@
|
||||
return;
|
||||
}
|
||||
[_queue insertObject:service atIndex:insertPosition];
|
||||
//当前没有弹窗显示且队列只有一个元素时,显示弹窗
|
||||
|
||||
if (_currentPopupService == nil && _queue.count == 1) {
|
||||
[self showPopup];
|
||||
}
|
||||
@@ -61,8 +58,7 @@
|
||||
|
||||
- (void)removePopupService {
|
||||
|
||||
//防止当弹窗还未显示完成,在显示过程中频繁调用 dismiss
|
||||
//使得 _currentPopupService 被清空,导致弹窗无法消失,从而假死现象
|
||||
|
||||
if (!self.isShowingPopup) {
|
||||
return;
|
||||
}
|
||||
@@ -79,11 +75,7 @@
|
||||
_currentPopupService = nil;
|
||||
}
|
||||
|
||||
/**
|
||||
点击蒙层时移除队列中的数据源
|
||||
|
||||
@discussion 注意无需调用 dismissPopupForView
|
||||
*/
|
||||
|
||||
- (void)removeSourceWhenTouchMaskView {
|
||||
if (_currentPopupService == nil) {
|
||||
return;
|
||||
@@ -95,9 +87,8 @@
|
||||
}
|
||||
|
||||
#pragma mark - Private Methods
|
||||
/**
|
||||
显示弹窗
|
||||
*/
|
||||
|
||||
|
||||
- (void)showPopup {
|
||||
if (self.isShowingPopup) {
|
||||
return;
|
||||
@@ -131,27 +122,26 @@
|
||||
|
||||
[popup showWithLayout:FFPopupLayoutMake(horizontalLayout, verticalLayout) duration:0.0];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
// 不管是调用’dismissPopupForView:animated:‘ 还是‘点击蒙层消除’,最终都会走到这里
|
||||
// 适合在此展示队列中下一个弹窗
|
||||
// 通过 _currentPopupService 是否为空可以判断是哪种消除方式
|
||||
|
||||
|
||||
popup.didFinishDismissingBlock = ^{
|
||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||
BOOL isDismissOnBackgroundTouch = strongSelf.currentPopupService != nil;
|
||||
if (isDismissOnBackgroundTouch) {
|
||||
// ‘点击蒙层消除’时,在展现下一个弹窗前移除数据源
|
||||
|
||||
[self removeSourceWhenTouchMaskView];
|
||||
}
|
||||
if (popupService.didFinishDismissHandler) {
|
||||
popupService.didFinishDismissHandler(isDismissOnBackgroundTouch);
|
||||
}
|
||||
// 弹窗消除结束,更新状态
|
||||
|
||||
strongSelf.showingPopup = NO;
|
||||
// 显示下一个弹窗
|
||||
|
||||
[strongSelf showPopup];
|
||||
};
|
||||
|
||||
popup.didFinishShowingBlock = ^{
|
||||
// 开始弹窗,更新状态
|
||||
|
||||
self.showingPopup = YES;
|
||||
if (popupService.didFinishShowingHandler) {
|
||||
popupService.didFinishShowingHandler();
|
||||
@@ -159,11 +149,7 @@
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
弹窗将要插入队列的位置
|
||||
@param service 弹窗服务实例
|
||||
@return 队列的位置
|
||||
*/
|
||||
|
||||
- (NSInteger)insertPositionForPopupService:(id<TTPopupServiceProtocol>)service {
|
||||
__block NSInteger result = NSNotFound;
|
||||
if (service == nil) {
|
||||
@@ -172,7 +158,7 @@
|
||||
if (_queue.count == 0) {
|
||||
return 0;
|
||||
}
|
||||
// 设置重复弹窗过滤
|
||||
|
||||
if (service.shouldFilterPopup && service.filterIdentifier.length > 0) {
|
||||
BOOL filterFlag = NO;
|
||||
for (id<TTPopupServiceProtocol> serv in _queue) {
|
||||
@@ -186,13 +172,13 @@
|
||||
}
|
||||
}
|
||||
[_queue enumerateObjectsUsingBlock:^(id<TTPopupServiceProtocol> _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// 找到队中比当前弹窗优先级低的位置
|
||||
|
||||
if (service.priority > model.priority) {
|
||||
result = idx;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
// 如果没有合适的位置,则将新的弹窗放在队尾
|
||||
|
||||
result = MIN(result, _queue.count);
|
||||
return result;
|
||||
}
|
||||
|
200
YuMi/CustomUI/TTPopup/Manager/TTPopupManagerService.m.backup
Normal file
200
YuMi/CustomUI/TTPopup/Manager/TTPopupManagerService.m.backup
Normal file
@@ -0,0 +1,200 @@
|
||||
//
|
||||
// TTPopupManagerService.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopupManagerService.h"
|
||||
|
||||
#import <FFPopup/FFPopup.h>
|
||||
|
||||
@interface TTPopupManagerService ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray< id<TTPopupServiceProtocol> > *queue;
|
||||
/**
|
||||
当前是否正在显示状态
|
||||
*/
|
||||
@property (nonatomic, assign, getter=isShowingPopup) BOOL showingPopup;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TTPopupManagerService
|
||||
|
||||
#pragma mark - Life Cycle
|
||||
+ (instancetype)sharedInstance {
|
||||
static TTPopupManagerService *instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[self alloc] init];
|
||||
});
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_queue = [NSMutableArray array];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - TTPopupManagerServiceProtocol
|
||||
- (void)addPopupService:(id<TTPopupServiceProtocol>)service {
|
||||
if (![service conformsToProtocol:@protocol(TTPopupServiceProtocol)]) {
|
||||
return;
|
||||
}
|
||||
if ([_queue containsObject:service]) {
|
||||
return;
|
||||
}
|
||||
NSInteger insertPosition = [self insertPositionForPopupService:service];
|
||||
if (insertPosition == NSNotFound) {
|
||||
return;
|
||||
}
|
||||
[_queue insertObject:service atIndex:insertPosition];
|
||||
//当前没有弹窗显示且队列只有一个元素时,显示弹窗
|
||||
if (_currentPopupService == nil && _queue.count == 1) {
|
||||
[self showPopup];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removePopupService {
|
||||
|
||||
//防止当弹窗还未显示完成,在显示过程中频繁调用 dismiss
|
||||
//使得 _currentPopupService 被清空,导致弹窗无法消失,从而假死现象
|
||||
if (!self.isShowingPopup) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentPopupService == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_queue.count > 0) {
|
||||
[_queue removeObjectAtIndex:0];
|
||||
}
|
||||
|
||||
[FFPopup dismissPopupForView:_currentPopupService.contentView animated:YES];
|
||||
_currentPopupService = nil;
|
||||
}
|
||||
|
||||
/**
|
||||
点击蒙层时移除队列中的数据源
|
||||
|
||||
@discussion 注意无需调用 dismissPopupForView
|
||||
*/
|
||||
- (void)removeSourceWhenTouchMaskView {
|
||||
if (_currentPopupService == nil) {
|
||||
return;
|
||||
}
|
||||
if (_queue.count > 0) {
|
||||
[_queue removeObjectAtIndex:0];
|
||||
}
|
||||
_currentPopupService = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Private Methods
|
||||
/**
|
||||
显示弹窗
|
||||
*/
|
||||
- (void)showPopup {
|
||||
if (self.isShowingPopup) {
|
||||
return;
|
||||
}
|
||||
if (_currentPopupService) {
|
||||
return;
|
||||
}
|
||||
if (_queue.count == 0) {
|
||||
return;
|
||||
}
|
||||
id<TTPopupServiceProtocol> popupService = _queue.firstObject;
|
||||
if (![popupService conformsToProtocol:@protocol(TTPopupServiceProtocol)]) {
|
||||
return;
|
||||
}
|
||||
_currentPopupService = popupService;
|
||||
FFPopupHorizontalLayout horizontalLayout = FFPopupHorizontalLayout_Center;
|
||||
FFPopupVerticalLayout verticalLayout = FFPopupVerticalLayout_Center;
|
||||
FFPopupShowType showType = (FFPopupShowType)popupService.showType;
|
||||
FFPopupDismissType dismissType = FFPopupDismissType_GrowOut;
|
||||
if (popupService.style == TTPopupStyleActionSheet) {
|
||||
verticalLayout = FFPopupVerticalLayout_Bottom;
|
||||
showType = FFPopupShowType_SlideInFromBottom;
|
||||
dismissType = FFPopupDismissType_SlideOutToBottom;
|
||||
}
|
||||
FFPopup *popup = [FFPopup popupWithContentView:popupService.contentView];
|
||||
popup.showType = showType;
|
||||
popup.dismissType = dismissType;
|
||||
popup.maskType = FFPopupMaskType_Dimmed;
|
||||
popup.dimmedMaskAlpha = popupService.maskBackgroundAlpha;
|
||||
popup.shouldDismissOnBackgroundTouch = popupService.shouldDismissOnBackgroundTouch;
|
||||
|
||||
[popup showWithLayout:FFPopupLayoutMake(horizontalLayout, verticalLayout) duration:0.0];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
// 不管是调用’dismissPopupForView:animated:‘ 还是‘点击蒙层消除’,最终都会走到这里
|
||||
// 适合在此展示队列中下一个弹窗
|
||||
// 通过 _currentPopupService 是否为空可以判断是哪种消除方式
|
||||
popup.didFinishDismissingBlock = ^{
|
||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||
BOOL isDismissOnBackgroundTouch = strongSelf.currentPopupService != nil;
|
||||
if (isDismissOnBackgroundTouch) {
|
||||
// ‘点击蒙层消除’时,在展现下一个弹窗前移除数据源
|
||||
[self removeSourceWhenTouchMaskView];
|
||||
}
|
||||
if (popupService.didFinishDismissHandler) {
|
||||
popupService.didFinishDismissHandler(isDismissOnBackgroundTouch);
|
||||
}
|
||||
// 弹窗消除结束,更新状态
|
||||
strongSelf.showingPopup = NO;
|
||||
// 显示下一个弹窗
|
||||
[strongSelf showPopup];
|
||||
};
|
||||
|
||||
popup.didFinishShowingBlock = ^{
|
||||
// 开始弹窗,更新状态
|
||||
self.showingPopup = YES;
|
||||
if (popupService.didFinishShowingHandler) {
|
||||
popupService.didFinishShowingHandler();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
弹窗将要插入队列的位置
|
||||
@param service 弹窗服务实例
|
||||
@return 队列的位置
|
||||
*/
|
||||
- (NSInteger)insertPositionForPopupService:(id<TTPopupServiceProtocol>)service {
|
||||
__block NSInteger result = NSNotFound;
|
||||
if (service == nil) {
|
||||
return result;
|
||||
}
|
||||
if (_queue.count == 0) {
|
||||
return 0;
|
||||
}
|
||||
// 设置重复弹窗过滤
|
||||
if (service.shouldFilterPopup && service.filterIdentifier.length > 0) {
|
||||
BOOL filterFlag = NO;
|
||||
for (id<TTPopupServiceProtocol> serv in _queue) {
|
||||
if ([serv.filterIdentifier isEqualToString:service.filterIdentifier]) {
|
||||
filterFlag = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filterFlag) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
[_queue enumerateObjectsUsingBlock:^(id<TTPopupServiceProtocol> _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// 找到队中比当前弹窗优先级低的位置
|
||||
if (service.priority > model.priority) {
|
||||
result = idx;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
// 如果没有合适的位置,则将新的弹窗放在队尾
|
||||
result = MIN(result, _queue.count);
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,25 +1,17 @@
|
||||
//
|
||||
// TTPopupManagerServiceProtocol.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopupServiceProtocol.h"
|
||||
|
||||
@protocol TTPopupManagerServiceProtocol <NSObject>
|
||||
|
||||
/**
|
||||
添加一个弹窗
|
||||
|
||||
@param service 服从弹窗服务的实例
|
||||
*/
|
||||
- (void)addPopupService:(id<TTPopupServiceProtocol>)service;
|
||||
|
||||
/**
|
||||
移除一个弹窗
|
||||
*/
|
||||
- (void)removePopupService;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import "TTPopupServiceProtocol.h"
|
||||
|
||||
@protocol TTPopupManagerServiceProtocol <NSObject>
|
||||
|
||||
|
||||
- (void)addPopupService:(id<TTPopupServiceProtocol>)service;
|
||||
|
||||
|
||||
- (void)removePopupService;
|
||||
|
||||
@end
|
||||
|
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// TTPopupManagerServiceProtocol.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopupServiceProtocol.h"
|
||||
|
||||
@protocol TTPopupManagerServiceProtocol <NSObject>
|
||||
|
||||
/**
|
||||
添加一个弹窗
|
||||
|
||||
@param service 服从弹窗服务的实例
|
||||
*/
|
||||
- (void)addPopupService:(id<TTPopupServiceProtocol>)service;
|
||||
|
||||
/**
|
||||
移除一个弹窗
|
||||
*/
|
||||
- (void)removePopupService;
|
||||
|
||||
@end
|
@@ -1,22 +1,19 @@
|
||||
//
|
||||
// TTPopupService.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupServiceProtocol.h"
|
||||
|
||||
// TTPopupConfig 是 TTPopupService 的别称
|
||||
// 具体信息见 TTPopupService
|
||||
#define TTPopupConfig TTPopupService
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTPopupService : NSObject<TTPopupServiceProtocol>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupServiceProtocol.h"
|
||||
|
||||
|
||||
#define TTPopupConfig TTPopupService
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTPopupService : NSObject<TTPopupServiceProtocol>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
22
YuMi/CustomUI/TTPopup/Service/TTPopupService.h.backup
Normal file
22
YuMi/CustomUI/TTPopup/Service/TTPopupService.h.backup
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// TTPopupService.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupServiceProtocol.h"
|
||||
|
||||
// TTPopupConfig 是 TTPopupService 的别称
|
||||
// 具体信息见 TTPopupService
|
||||
#define TTPopupConfig TTPopupService
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTPopupService : NSObject<TTPopupServiceProtocol>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTPopupService.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTPopupService.h"
|
||||
|
||||
|
36
YuMi/CustomUI/TTPopup/Service/TTPopupService.m.backup
Normal file
36
YuMi/CustomUI/TTPopup/Service/TTPopupService.m.backup
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// TTPopupService.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopupService.h"
|
||||
|
||||
@implementation TTPopupService
|
||||
|
||||
@synthesize style = _style;
|
||||
@synthesize priority = _priority;
|
||||
@synthesize contentView = _contentView;
|
||||
@synthesize maskBackgroundAlpha = _maskBackgroundAlpha;
|
||||
@synthesize shouldDismissOnBackgroundTouch = _shouldDismissOnBackgroundTouch;
|
||||
@synthesize didFinishDismissHandler = _didFinishDismissHandler;
|
||||
@synthesize didFinishShowingHandler = _didFinishShowingHandler;
|
||||
@synthesize shouldFilterPopup = _shouldFilterPopup;
|
||||
@synthesize filterIdentifier = _filterIdentifier;
|
||||
@synthesize showType = _showType;
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_style = TTPopupStyleAlert;
|
||||
_priority = TTPopupPriorityNormal;
|
||||
_maskBackgroundAlpha = 0.5;
|
||||
_shouldDismissOnBackgroundTouch = YES;
|
||||
_shouldFilterPopup = NO;
|
||||
_showType = TTPopupShowTypeDefault;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,78 +1,47 @@
|
||||
//
|
||||
// TTPopupServiceProtocol.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTPopupShowType) {
|
||||
TTPopupShowType_FadeIn = 1,
|
||||
TTPopupShowTypeDefault = 8,
|
||||
};
|
||||
|
||||
@class UIView;
|
||||
|
||||
@protocol TTPopupServiceProtocol <NSObject>
|
||||
|
||||
/**
|
||||
弹窗样式,默认:TTPopupStyleAlert
|
||||
*/
|
||||
@property (nonatomic, assign) TTPopupStyle style;
|
||||
|
||||
/**
|
||||
弹窗优先级权重,默认:TTPopupPriorityNormal
|
||||
|
||||
@discussion 权重越高在弹窗队列的优先级越高,即优先弹出;相同权重按先来后到原则
|
||||
*/
|
||||
@property (nonatomic, assign) TTPopupPriority priority;
|
||||
|
||||
/**
|
||||
自定义视图内容,默认:nil
|
||||
|
||||
@discussion 如果未配置,或 contentView 未继承自 UIView 及其子类,将忽略该弹窗
|
||||
*/
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
|
||||
/**
|
||||
背景蒙层透明度,默认:0x000000 0.3 alpha
|
||||
|
||||
@discussion 由于第三方原因,暂不支持蒙层颜色修改
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat maskBackgroundAlpha;
|
||||
|
||||
/**
|
||||
点击蒙层是否消除弹窗,默认:YES
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldDismissOnBackgroundTouch;
|
||||
|
||||
/**
|
||||
弹窗消失回调,isDismissOnBackgroundTouch 区分是否点击蒙层触发
|
||||
*/
|
||||
@property (nonatomic, copy) void (^didFinishDismissHandler)(BOOL isDismissOnBackgroundTouch);
|
||||
|
||||
/**
|
||||
弹窗显示成功回调
|
||||
*/
|
||||
@property (nonatomic, copy) void (^didFinishShowingHandler)(void);
|
||||
|
||||
/**
|
||||
重复弹窗过滤,默认:NO
|
||||
|
||||
@discussion 设置过滤时,队列中将不会出现相同过滤标识的弹窗
|
||||
过滤标识通过 #<filterIdentifier> 设置
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldFilterPopup;
|
||||
|
||||
/**
|
||||
过滤标识,默认:nil
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *filterIdentifier;
|
||||
|
||||
/**
|
||||
显示动画类型, 默认是 default
|
||||
*/
|
||||
@property (nonatomic, assign) TTPopupShowType showType;
|
||||
@end
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTPopupShowType) {
|
||||
TTPopupShowType_FadeIn = 1,
|
||||
TTPopupShowTypeDefault = 8,
|
||||
};
|
||||
|
||||
@class UIView;
|
||||
|
||||
@protocol TTPopupServiceProtocol <NSObject>
|
||||
|
||||
|
||||
@property (nonatomic, assign) TTPopupStyle style;
|
||||
|
||||
|
||||
@property (nonatomic, assign) TTPopupPriority priority;
|
||||
|
||||
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
|
||||
|
||||
@property (nonatomic, assign) CGFloat maskBackgroundAlpha;
|
||||
|
||||
|
||||
@property (nonatomic, assign) BOOL shouldDismissOnBackgroundTouch;
|
||||
|
||||
|
||||
@property (nonatomic, copy) void (^didFinishDismissHandler)(BOOL isDismissOnBackgroundTouch);
|
||||
|
||||
|
||||
@property (nonatomic, copy) void (^didFinishShowingHandler)(void);
|
||||
|
||||
|
||||
@property (nonatomic, assign) BOOL shouldFilterPopup;
|
||||
|
||||
|
||||
@property (nonatomic, copy) NSString *filterIdentifier;
|
||||
|
||||
|
||||
@property (nonatomic, assign) TTPopupShowType showType;
|
||||
@end
|
||||
|
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// TTPopupServiceProtocol.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/21.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, TTPopupShowType) {
|
||||
TTPopupShowType_FadeIn = 1,
|
||||
TTPopupShowTypeDefault = 8,
|
||||
};
|
||||
|
||||
@class UIView;
|
||||
|
||||
@protocol TTPopupServiceProtocol <NSObject>
|
||||
|
||||
/**
|
||||
弹窗样式,默认:TTPopupStyleAlert
|
||||
*/
|
||||
@property (nonatomic, assign) TTPopupStyle style;
|
||||
|
||||
/**
|
||||
弹窗优先级权重,默认:TTPopupPriorityNormal
|
||||
|
||||
@discussion 权重越高在弹窗队列的优先级越高,即优先弹出;相同权重按先来后到原则
|
||||
*/
|
||||
@property (nonatomic, assign) TTPopupPriority priority;
|
||||
|
||||
/**
|
||||
自定义视图内容,默认:nil
|
||||
|
||||
@discussion 如果未配置,或 contentView 未继承自 UIView 及其子类,将忽略该弹窗
|
||||
*/
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
|
||||
/**
|
||||
背景蒙层透明度,默认:0x000000 0.3 alpha
|
||||
|
||||
@discussion 由于第三方原因,暂不支持蒙层颜色修改
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat maskBackgroundAlpha;
|
||||
|
||||
/**
|
||||
点击蒙层是否消除弹窗,默认:YES
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldDismissOnBackgroundTouch;
|
||||
|
||||
/**
|
||||
弹窗消失回调,isDismissOnBackgroundTouch 区分是否点击蒙层触发
|
||||
*/
|
||||
@property (nonatomic, copy) void (^didFinishDismissHandler)(BOOL isDismissOnBackgroundTouch);
|
||||
|
||||
/**
|
||||
弹窗显示成功回调
|
||||
*/
|
||||
@property (nonatomic, copy) void (^didFinishShowingHandler)(void);
|
||||
|
||||
/**
|
||||
重复弹窗过滤,默认:NO
|
||||
|
||||
@discussion 设置过滤时,队列中将不会出现相同过滤标识的弹窗
|
||||
过滤标识通过 #<filterIdentifier> 设置
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldFilterPopup;
|
||||
|
||||
/**
|
||||
过滤标识,默认:nil
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *filterIdentifier;
|
||||
|
||||
/**
|
||||
显示动画类型, 默认是 default
|
||||
*/
|
||||
@property (nonatomic, assign) TTPopupShowType showType;
|
||||
@end
|
@@ -1,126 +1,78 @@
|
||||
//
|
||||
// TTPopup.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// 弹窗工具类
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupConstants.h"
|
||||
#import "TTAlertConfig.h"
|
||||
#import "TTActionSheetConfig.h"
|
||||
#import "TTPopupService.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class UIView;
|
||||
|
||||
@interface TTPopup : NSObject
|
||||
|
||||
#pragma mark Alert
|
||||
/**
|
||||
显示 alert 弹窗
|
||||
|
||||
@discussion 显示四个内容:默认标题‘提示’,提示内容,取消按钮,确认按钮
|
||||
|
||||
@param message 提示内容,不能为空(⊙o⊙)哦
|
||||
@param confirmHandler 确认操作
|
||||
@param cancelHandler 取消操作
|
||||
*/
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
|
||||
/**
|
||||
显示 alert 弹窗
|
||||
|
||||
@discussion 显示四个内容:默认标题‘提示’,提示内容,取消按钮,确认按钮
|
||||
|
||||
@param config 完善的视图配置,为您变态的需求保驾护航
|
||||
@param isShowBorder 是否显示边框
|
||||
@param confirmHandler 确认操作
|
||||
@param cancelHandler 取消操作
|
||||
*/
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
|
||||
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
config:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler;
|
||||
|
||||
/**
|
||||
显示 alert 弹窗
|
||||
@discussion 显示四个内容:标题,提示内容,取消按钮,确认按钮
|
||||
@param config 完善的视图配置,为您变态的需求保驾护航
|
||||
@param cancelHandler 取消操作
|
||||
@param confirmHandler 确认操作
|
||||
*/
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
#pragma mark Action Sheet
|
||||
/**
|
||||
显示 action sheet 弹窗,自带贴心的取消按钮😊
|
||||
|
||||
@param items 配置列表
|
||||
*/
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items;
|
||||
|
||||
/**
|
||||
显示 action sheet 弹窗
|
||||
|
||||
@param items 配置列表
|
||||
@param showCancelItem 是否显示取消按钮
|
||||
*/
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
showCancelItem:(BOOL)showCancelItem;
|
||||
|
||||
/**
|
||||
显示 action sheet 弹窗
|
||||
|
||||
@param items 配置列表
|
||||
@param cancelHandler 取消按钮回调
|
||||
*/
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
cancelHandler:(TTActionSheetClickAction)cancelHandler;
|
||||
|
||||
#pragma mark Popup
|
||||
/**
|
||||
显示自定义弹窗
|
||||
@param customView 自定义 view
|
||||
@param style 弹窗样式
|
||||
*/
|
||||
+ (void)popupView:(UIView *)customView
|
||||
style:(TTPopupStyle)style;
|
||||
|
||||
/**
|
||||
显示自定义弹窗
|
||||
|
||||
@param config 自定义弹窗配置
|
||||
*/
|
||||
+ (void)popupWithConfig:(TTPopupService *)config;
|
||||
|
||||
#pragma mark Dismiss
|
||||
/**
|
||||
消除当前弹窗
|
||||
*/
|
||||
+ (void)dismiss;
|
||||
|
||||
#pragma mark Query
|
||||
/**
|
||||
当前是否有显示弹窗
|
||||
*/
|
||||
+ (BOOL)hasShowPopup;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupConstants.h"
|
||||
#import "TTAlertConfig.h"
|
||||
#import "TTActionSheetConfig.h"
|
||||
#import "TTPopupService.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class UIView;
|
||||
|
||||
@interface TTPopup : NSObject
|
||||
|
||||
#pragma mark Alert
|
||||
|
||||
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
config:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler;
|
||||
|
||||
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
#pragma mark Action Sheet
|
||||
|
||||
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items;
|
||||
|
||||
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
showCancelItem:(BOOL)showCancelItem;
|
||||
|
||||
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
cancelHandler:(TTActionSheetClickAction)cancelHandler;
|
||||
|
||||
#pragma mark Popup
|
||||
|
||||
|
||||
+ (void)popupView:(UIView *)customView
|
||||
style:(TTPopupStyle)style;
|
||||
|
||||
|
||||
+ (void)popupWithConfig:(TTPopupService *)config;
|
||||
|
||||
#pragma mark Dismiss
|
||||
|
||||
|
||||
+ (void)dismiss;
|
||||
|
||||
#pragma mark Query
|
||||
|
||||
|
||||
+ (BOOL)hasShowPopup;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
126
YuMi/CustomUI/TTPopup/TTPopup.h.backup
Normal file
126
YuMi/CustomUI/TTPopup/TTPopup.h.backup
Normal file
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// TTPopup.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
// 弹窗工具类
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TTPopupConstants.h"
|
||||
#import "TTAlertConfig.h"
|
||||
#import "TTActionSheetConfig.h"
|
||||
#import "TTPopupService.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class UIView;
|
||||
|
||||
@interface TTPopup : NSObject
|
||||
|
||||
#pragma mark Alert
|
||||
/**
|
||||
显示 alert 弹窗
|
||||
|
||||
@discussion 显示四个内容:默认标题‘提示’,提示内容,取消按钮,确认按钮
|
||||
|
||||
@param message 提示内容,不能为空(⊙o⊙)哦
|
||||
@param confirmHandler 确认操作
|
||||
@param cancelHandler 取消操作
|
||||
*/
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
|
||||
/**
|
||||
显示 alert 弹窗
|
||||
|
||||
@discussion 显示四个内容:默认标题‘提示’,提示内容,取消按钮,确认按钮
|
||||
|
||||
@param config 完善的视图配置,为您变态的需求保驾护航
|
||||
@param isShowBorder 是否显示边框
|
||||
@param confirmHandler 确认操作
|
||||
@param cancelHandler 取消操作
|
||||
*/
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
|
||||
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
config:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler;
|
||||
|
||||
/**
|
||||
显示 alert 弹窗
|
||||
@discussion 显示四个内容:标题,提示内容,取消按钮,确认按钮
|
||||
@param config 完善的视图配置,为您变态的需求保驾护航
|
||||
@param cancelHandler 取消操作
|
||||
@param confirmHandler 确认操作
|
||||
*/
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler;
|
||||
|
||||
#pragma mark Action Sheet
|
||||
/**
|
||||
显示 action sheet 弹窗,自带贴心的取消按钮😊
|
||||
|
||||
@param items 配置列表
|
||||
*/
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items;
|
||||
|
||||
/**
|
||||
显示 action sheet 弹窗
|
||||
|
||||
@param items 配置列表
|
||||
@param showCancelItem 是否显示取消按钮
|
||||
*/
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
showCancelItem:(BOOL)showCancelItem;
|
||||
|
||||
/**
|
||||
显示 action sheet 弹窗
|
||||
|
||||
@param items 配置列表
|
||||
@param cancelHandler 取消按钮回调
|
||||
*/
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
cancelHandler:(TTActionSheetClickAction)cancelHandler;
|
||||
|
||||
#pragma mark Popup
|
||||
/**
|
||||
显示自定义弹窗
|
||||
@param customView 自定义 view
|
||||
@param style 弹窗样式
|
||||
*/
|
||||
+ (void)popupView:(UIView *)customView
|
||||
style:(TTPopupStyle)style;
|
||||
|
||||
/**
|
||||
显示自定义弹窗
|
||||
|
||||
@param config 自定义弹窗配置
|
||||
*/
|
||||
+ (void)popupWithConfig:(TTPopupService *)config;
|
||||
|
||||
#pragma mark Dismiss
|
||||
/**
|
||||
消除当前弹窗
|
||||
*/
|
||||
+ (void)dismiss;
|
||||
|
||||
#pragma mark Query
|
||||
/**
|
||||
当前是否有显示弹窗
|
||||
*/
|
||||
+ (BOOL)hasShowPopup;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTPopup.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lvjunhang on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTPopup.h"
|
||||
#import "TTAlertView.h"
|
||||
@@ -59,13 +57,13 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
NSAssert(NO, @" message can not be nil, 弹窗文案不可以为空");
|
||||
return;
|
||||
#else
|
||||
// 防止正式环境 crash
|
||||
|
||||
config.message = @" ";
|
||||
#endif
|
||||
}
|
||||
CGFloat width = [UIScreen mainScreen].bounds.size.width - 40 * 2;
|
||||
CGFloat height = ([self messageSize:config.message width:width].height + 160);
|
||||
// 最小 200, 最大 450
|
||||
|
||||
if (height < kMixHeight) {
|
||||
height = kMixHeight;
|
||||
} else if (height > KScreenHeight - kSafeAreaTopHeight - kSafeAreaBottomHeight) {
|
||||
@@ -77,7 +75,7 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
contentView.cancelAction = cancelHandler;
|
||||
contentView.confirmAction = confirmHandler;
|
||||
if (!contentView.config.disableAutoDismissWhenClickButton) {
|
||||
// 设置弹窗按钮自动消除
|
||||
|
||||
contentView.dismissAction = ^{
|
||||
[TTPopup dismiss];
|
||||
};
|
||||
@@ -115,7 +113,7 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
CGFloat width = [UIScreen mainScreen].bounds.size.width - 40 * 2;
|
||||
CGFloat height = ([self messageSize:config.message width:width].height + 160);
|
||||
|
||||
// 最小 200, 最大 450
|
||||
|
||||
if (height < kMixHeight) {
|
||||
height = kMixHeight;
|
||||
} else if (height > kMaxHeight) {
|
||||
@@ -129,7 +127,7 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
contentView.isConfigBoard = isShowBorder;
|
||||
|
||||
if (!contentView.config.disableAutoDismissWhenClickButton) {
|
||||
// 设置弹窗按钮自动消除
|
||||
|
||||
contentView.dismissAction = ^{
|
||||
[TTPopup dismiss];
|
||||
};
|
||||
@@ -162,14 +160,14 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
CGFloat width = [UIScreen mainScreen].bounds.size.width - kActionSheetViewPadding * 2;
|
||||
CGFloat height = kActionSheetViewCellHeight * items.count + kActionSheetViewBottomPadding;
|
||||
|
||||
// 如果需要显示取消按钮则增加响应的高度
|
||||
|
||||
if (showCancelItem) {
|
||||
// 按钮的高度和间距
|
||||
|
||||
height += kActionSheetViewCancelViewHeight;
|
||||
}
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
// 如果是 iPhone X 系列(刘海屏幕系列) 底部则需要添加 34 的高度
|
||||
|
||||
height += [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;
|
||||
}
|
||||
|
||||
@@ -180,7 +178,7 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
items:items];
|
||||
sheetView.cancelAction = cancelHandler;
|
||||
|
||||
// 设置弹窗按钮自动消除
|
||||
|
||||
sheetView.dismissAction = ^{
|
||||
[TTPopup dismiss];
|
||||
};
|
||||
@@ -227,9 +225,8 @@ static CGFloat const kMaxHeight = 450.f;
|
||||
}
|
||||
|
||||
#pragma mark Query
|
||||
/**
|
||||
当前是否有显示弹窗
|
||||
*/
|
||||
|
||||
|
||||
+ (BOOL)hasShowPopup {
|
||||
return [TTPopupManagerService sharedInstance].currentPopupService != nil;
|
||||
}
|
||||
|
243
YuMi/CustomUI/TTPopup/TTPopup.m.backup
Normal file
243
YuMi/CustomUI/TTPopup/TTPopup.m.backup
Normal file
@@ -0,0 +1,243 @@
|
||||
//
|
||||
// TTPopup.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lvjunhang on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTPopup.h"
|
||||
#import "TTAlertView.h"
|
||||
#import "TTActionSheetView.h"
|
||||
#import "TTPopupService.h"
|
||||
#import "TTPopupManagerService.h"
|
||||
|
||||
static CGFloat const kActionSheetViewPadding = 15.f;
|
||||
static CGFloat const kActionSheetViewCellHeight = 52.f;
|
||||
static CGFloat const kActionSheetViewCancelViewHeight = 67.f;
|
||||
static CGFloat const kActionSheetViewBottomPadding = 15.f;
|
||||
static CGFloat const kMixHeight = 200.f;
|
||||
static CGFloat const kMaxHeight = 450.f;
|
||||
|
||||
@implementation TTPopup
|
||||
|
||||
#pragma mark - Public Methods
|
||||
#pragma mark Alert
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler {
|
||||
|
||||
[self alertWithMessage:message
|
||||
config:nil
|
||||
cancelHandler:cancelHandler
|
||||
confirmHandler:confirmHandler];
|
||||
}
|
||||
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler {
|
||||
|
||||
[self alertWithMessage:nil
|
||||
config:config
|
||||
cancelHandler:cancelHandler
|
||||
confirmHandler:confirmHandler];
|
||||
}
|
||||
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
config:(TTAlertConfig *)config
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler {
|
||||
|
||||
if (!config) {
|
||||
config = [[TTAlertConfig alloc] init];
|
||||
config.title = YMLocalizedString(@"UserDetail_CP_Toast_0");
|
||||
config.message = message;
|
||||
}
|
||||
|
||||
if (config.message.length <= 0 && config.messageAttributed.length <=0 && config.messageAttributedConfig.count <=0) {
|
||||
#if DEBUG
|
||||
NSAssert(NO, @" message can not be nil, 弹窗文案不可以为空");
|
||||
return;
|
||||
#else
|
||||
// 防止正式环境 crash
|
||||
config.message = @" ";
|
||||
#endif
|
||||
}
|
||||
CGFloat width = [UIScreen mainScreen].bounds.size.width - 40 * 2;
|
||||
CGFloat height = ([self messageSize:config.message width:width].height + 160);
|
||||
// 最小 200, 最大 450
|
||||
if (height < kMixHeight) {
|
||||
height = kMixHeight;
|
||||
} else if (height > KScreenHeight - kSafeAreaTopHeight - kSafeAreaBottomHeight) {
|
||||
height = KScreenHeight - kSafeAreaTopHeight - kSafeAreaBottomHeight;
|
||||
}
|
||||
TTAlertView *contentView = [[TTAlertView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
|
||||
contentView.config = config;
|
||||
contentView.isConfigBoard = NO;
|
||||
contentView.cancelAction = cancelHandler;
|
||||
contentView.confirmAction = confirmHandler;
|
||||
if (!contentView.config.disableAutoDismissWhenClickButton) {
|
||||
// 设置弹窗按钮自动消除
|
||||
contentView.dismissAction = ^{
|
||||
[TTPopup dismiss];
|
||||
};
|
||||
}
|
||||
[self popupView:contentView style:TTPopupStyleAlert config:config];
|
||||
}
|
||||
|
||||
+ (void)alertWithConfig:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler {
|
||||
[self alertWithMessage:@""
|
||||
config:config
|
||||
showBorder:isShowBorder
|
||||
cancelHandler:cancelHandler
|
||||
confirmHandler:confirmHandler];
|
||||
}
|
||||
|
||||
+ (void)alertWithMessage:(NSString *)message
|
||||
config:(TTAlertConfig *)config
|
||||
showBorder:(BOOL)isShowBorder
|
||||
cancelHandler:(TTPopupCompletionHandler)cancelHandler
|
||||
confirmHandler:(TTPopupCompletionHandler)confirmHandler {
|
||||
|
||||
if (!config) {
|
||||
config = [[TTAlertConfig alloc] init];
|
||||
config.message = message;
|
||||
}
|
||||
|
||||
if (config.message.length <= 0) {
|
||||
NSAssert(NO, @" message can not be nil, 弹窗文案不可以为空");
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat width = [UIScreen mainScreen].bounds.size.width - 40 * 2;
|
||||
CGFloat height = ([self messageSize:config.message width:width].height + 160);
|
||||
|
||||
// 最小 200, 最大 450
|
||||
if (height < kMixHeight) {
|
||||
height = kMixHeight;
|
||||
} else if (height > kMaxHeight) {
|
||||
height = kMaxHeight;
|
||||
}
|
||||
|
||||
TTAlertView *contentView = [[TTAlertView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
|
||||
contentView.config = config;
|
||||
contentView.cancelAction = cancelHandler;
|
||||
contentView.confirmAction = confirmHandler;
|
||||
contentView.isConfigBoard = isShowBorder;
|
||||
|
||||
if (!contentView.config.disableAutoDismissWhenClickButton) {
|
||||
// 设置弹窗按钮自动消除
|
||||
contentView.dismissAction = ^{
|
||||
[TTPopup dismiss];
|
||||
};
|
||||
}
|
||||
|
||||
[self popupView:contentView style:TTPopupStyleAlert config:config];
|
||||
}
|
||||
|
||||
#pragma mark Action Sheet
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items {
|
||||
|
||||
[TTPopup actionSheetWithItems:items showCancelItem:YES cancelHandler:nil];
|
||||
}
|
||||
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
showCancelItem:(BOOL)showCancelItem {
|
||||
|
||||
[TTPopup actionSheetWithItems:items showCancelItem:showCancelItem cancelHandler:nil];
|
||||
}
|
||||
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items cancelHandler:(TTActionSheetClickAction)cancelHandler {
|
||||
|
||||
[TTPopup actionSheetWithItems:items showCancelItem:YES cancelHandler:cancelHandler];
|
||||
}
|
||||
|
||||
+ (void)actionSheetWithItems:(NSArray<TTActionSheetConfig *> *)items
|
||||
showCancelItem:(BOOL)showCancelItem
|
||||
cancelHandler:(TTActionSheetClickAction)cancelHandler {
|
||||
|
||||
CGFloat width = [UIScreen mainScreen].bounds.size.width - kActionSheetViewPadding * 2;
|
||||
CGFloat height = kActionSheetViewCellHeight * items.count + kActionSheetViewBottomPadding;
|
||||
|
||||
// 如果需要显示取消按钮则增加响应的高度
|
||||
if (showCancelItem) {
|
||||
// 按钮的高度和间距
|
||||
height += kActionSheetViewCancelViewHeight;
|
||||
}
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
// 如果是 iPhone X 系列(刘海屏幕系列) 底部则需要添加 34 的高度
|
||||
height += [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;
|
||||
}
|
||||
|
||||
CGRect rect = CGRectMake(0, 0, width, height);
|
||||
|
||||
TTActionSheetView *sheetView = [[TTActionSheetView alloc] initWithFrame:rect
|
||||
needCancel:showCancelItem
|
||||
items:items];
|
||||
sheetView.cancelAction = cancelHandler;
|
||||
|
||||
// 设置弹窗按钮自动消除
|
||||
sheetView.dismissAction = ^{
|
||||
[TTPopup dismiss];
|
||||
};
|
||||
|
||||
[self popupView:sheetView style:TTPopupStyleActionSheet];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Popup
|
||||
+ (void)popupView:(UIView *)customView
|
||||
style:(TTPopupStyle)style {
|
||||
|
||||
TTPopupService *service = [[TTPopupService alloc] init];
|
||||
service.style = style;
|
||||
service.contentView = customView;
|
||||
|
||||
[self popupWithConfig:service];
|
||||
}
|
||||
|
||||
+ (void)popupView:(UIView *)customView
|
||||
style:(TTPopupStyle)style
|
||||
config:(TTAlertConfig *)config {
|
||||
|
||||
TTPopupService *service = [[TTPopupService alloc] init];
|
||||
service.style = style;
|
||||
service.contentView = customView;
|
||||
service.shouldDismissOnBackgroundTouch = config.shouldDismissOnBackgroundTouch;
|
||||
service.maskBackgroundAlpha = config.maskBackgroundAlpha;
|
||||
[self popupWithConfig:service];
|
||||
}
|
||||
|
||||
|
||||
+ (void)popupWithConfig:(TTPopupService *)config {
|
||||
if (![config.contentView isKindOfClass:UIView.class]) {
|
||||
NSAssert(NO, @"TTPopup customView should inherit from UIView.");
|
||||
return;
|
||||
}
|
||||
[[TTPopupManagerService sharedInstance] addPopupService:config];
|
||||
}
|
||||
|
||||
#pragma mark Dismiss
|
||||
+ (void)dismiss {
|
||||
[[TTPopupManagerService sharedInstance] removePopupService];
|
||||
}
|
||||
|
||||
#pragma mark Query
|
||||
/**
|
||||
当前是否有显示弹窗
|
||||
*/
|
||||
+ (BOOL)hasShowPopup {
|
||||
return [TTPopupManagerService sharedInstance].currentPopupService != nil;
|
||||
}
|
||||
|
||||
#pragma mark - Privite
|
||||
+ (CGSize)messageSize:(NSString *)text width:(CGFloat)width {
|
||||
CGRect stringRect = [text boundingRectWithSize:CGSizeMake(width - 2 * 20, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15.f]} context:nil];
|
||||
return stringRect.size;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,26 +1,24 @@
|
||||
//
|
||||
// TTActionSheetView.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TTActionSheetConfig;
|
||||
|
||||
@interface TTActionSheetView : UIView
|
||||
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler cancelAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler dismissAction;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
needCancel:(BOOL)needCancel
|
||||
items:(NSArray<TTActionSheetConfig *> *)items;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lee on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TTActionSheetConfig;
|
||||
|
||||
@interface TTActionSheetView : UIView
|
||||
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler cancelAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler dismissAction;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
needCancel:(BOOL)needCancel
|
||||
items:(NSArray<TTActionSheetConfig *> *)items;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
26
YuMi/CustomUI/TTPopup/View/TTActionSheetView.h.backup
Normal file
26
YuMi/CustomUI/TTPopup/View/TTActionSheetView.h.backup
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// TTActionSheetView.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TTActionSheetConfig;
|
||||
|
||||
@interface TTActionSheetView : UIView
|
||||
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler cancelAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler dismissAction;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
needCancel:(BOOL)needCancel
|
||||
items:(NSArray<TTActionSheetConfig *> *)items;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTActionSheetView.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lee on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTActionSheetView.h"
|
||||
#import "TTActionSheetConfig.h"
|
||||
@@ -17,13 +15,13 @@ static NSString *const kSheetViewCellConst = @"kSheetViewCellConst";
|
||||
|
||||
@interface TTActionSheetView ()<UITableViewDelegate, UITableViewDataSource>
|
||||
|
||||
/** sheetView 载体 */
|
||||
|
||||
@property (nonatomic, strong) UITableView *tableView;
|
||||
/** 数据源 */
|
||||
|
||||
@property (nonatomic, strong) NSArray<TTActionSheetConfig *> *items;
|
||||
/** 是否需要显示取消按钮 */
|
||||
|
||||
@property (nonatomic, assign) BOOL needCancel;
|
||||
/** 取消按钮 */
|
||||
|
||||
@property (nonatomic, strong) UIButton *cancelButton;
|
||||
|
||||
@end
|
||||
@@ -56,7 +54,7 @@ static NSString *const kSheetViewCellConst = @"kSheetViewCellConst";
|
||||
}];
|
||||
|
||||
if (_needCancel) {
|
||||
// 显示 cancel view
|
||||
|
||||
self.cancelButton.hidden = NO;
|
||||
[self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.trailing.mas_equalTo(self);
|
||||
@@ -111,7 +109,7 @@ static NSString *const kSheetViewCellConst = @"kSheetViewCellConst";
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
// 配置中的事件处理
|
||||
|
||||
TTActionSheetConfig *config = _items[indexPath.row];
|
||||
!config.clickAction ?: config.clickAction();
|
||||
|
||||
|
159
YuMi/CustomUI/TTPopup/View/TTActionSheetView.m.backup
Normal file
159
YuMi/CustomUI/TTPopup/View/TTActionSheetView.m.backup
Normal file
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// TTActionSheetView.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/22.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTActionSheetView.h"
|
||||
#import "TTActionSheetConfig.h"
|
||||
#import "DJDKMIMOMColor.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
static CGFloat const kSheetViewCellHeight = 51.f;
|
||||
static CGFloat const kSheetViewCornerRadius = 14.f;
|
||||
static NSString *const kSheetViewCellConst = @"kSheetViewCellConst";
|
||||
|
||||
@interface TTActionSheetView ()<UITableViewDelegate, UITableViewDataSource>
|
||||
|
||||
/** sheetView 载体 */
|
||||
@property (nonatomic, strong) UITableView *tableView;
|
||||
/** 数据源 */
|
||||
@property (nonatomic, strong) NSArray<TTActionSheetConfig *> *items;
|
||||
/** 是否需要显示取消按钮 */
|
||||
@property (nonatomic, assign) BOOL needCancel;
|
||||
/** 取消按钮 */
|
||||
@property (nonatomic, strong) UIButton *cancelButton;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TTActionSheetView
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark lifeCycle
|
||||
- (instancetype)initWithFrame:(CGRect)frame needCancel:(BOOL)needCancel items:(NSArray<TTActionSheetConfig *> *)items {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
_items = items;
|
||||
_needCancel = needCancel;
|
||||
[self initViews];
|
||||
[self initConstraints];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initViews {
|
||||
[self addSubview:self.tableView];
|
||||
[self addSubview:self.cancelButton];
|
||||
}
|
||||
|
||||
- (void)initConstraints {
|
||||
|
||||
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.trailing.top.mas_equalTo(self);
|
||||
make.height.mas_equalTo(self.items.count * kSheetViewCellHeight);
|
||||
}];
|
||||
|
||||
if (_needCancel) {
|
||||
// 显示 cancel view
|
||||
self.cancelButton.hidden = NO;
|
||||
[self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.trailing.mas_equalTo(self);
|
||||
make.height.mas_equalTo(kSheetViewCellHeight);
|
||||
make.top.mas_equalTo(self.tableView.mas_bottom).offset(15);
|
||||
}];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return self.items.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kSheetViewCellConst];
|
||||
cell.backgroundColor = UIColor.clearColor;
|
||||
cell.textLabel.textAlignment = NSTextAlignmentCenter;
|
||||
cell.textLabel.text = _items[indexPath.row].title;
|
||||
cell.textLabel.textColor = _items[indexPath.row].titleColor;
|
||||
|
||||
if ([_items[indexPath.row] displayMoliCoin]) {
|
||||
NSTextAttachment *coinAttachment = [[NSTextAttachment alloc] init];
|
||||
coinAttachment.image = kImage(@"moli_money_icon");
|
||||
coinAttachment.bounds = CGRectMake(0, -3.5, 20, 20);
|
||||
NSAttributedString *coinAttributedString = [NSAttributedString attributedStringWithAttachment:coinAttachment];
|
||||
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithAttributedString:coinAttributedString];
|
||||
NSAttributedString *titleAttributedString = [[NSAttributedString alloc] initWithString:_items[indexPath.row].title
|
||||
attributes:@{
|
||||
NSForegroundColorAttributeName: _items[indexPath.row].titleColor,
|
||||
NSFontAttributeName: cell.textLabel.font
|
||||
}];
|
||||
[string insertAttributedString:titleAttributedString atIndex:0];
|
||||
cell.textLabel.attributedText = string.copy;
|
||||
|
||||
UIImageView *questionMark = [[UIImageView alloc] initWithImage:kImage(@"question_mark")];
|
||||
[cell.contentView addSubview:questionMark];
|
||||
[questionMark mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerY.mas_equalTo(cell.textLabel);
|
||||
make.trailing.mas_equalTo(-20);
|
||||
make.size.mas_equalTo(CGSizeMake(22, 22));
|
||||
}];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
// 配置中的事件处理
|
||||
TTActionSheetConfig *config = _items[indexPath.row];
|
||||
!config.clickAction ?: config.clickAction();
|
||||
|
||||
!_dismissAction ?: _dismissAction();
|
||||
}
|
||||
|
||||
- (void)onClickCancelButtonAction:(UIButton *)cancelButton {
|
||||
!_cancelAction ?: _cancelAction();
|
||||
!_dismissAction ?: _dismissAction();
|
||||
}
|
||||
|
||||
- (UITableView *)tableView {
|
||||
if (!_tableView) {
|
||||
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||||
_tableView.delegate = self;
|
||||
_tableView.dataSource = self;
|
||||
_tableView.separatorColor = [DJDKMIMOMColor actionSeparatorColor];
|
||||
_tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
|
||||
_tableView.rowHeight = kSheetViewCellHeight;
|
||||
_tableView.tableFooterView = [[UIView alloc] init];
|
||||
_tableView.backgroundColor = [UIColor whiteColor];
|
||||
_tableView.layer.cornerRadius = kSheetViewCornerRadius;
|
||||
_tableView.layer.masksToBounds = YES;
|
||||
_tableView.bounces = NO;
|
||||
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kSheetViewCellConst];
|
||||
}
|
||||
return _tableView;
|
||||
}
|
||||
|
||||
- (UIButton *)cancelButton {
|
||||
if (!_cancelButton) {
|
||||
_cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_cancelButton setTitle:YMLocalizedString(@"TTActionSheetView0") forState:UIControlStateNormal];
|
||||
[_cancelButton setBackgroundColor:UIColor.whiteColor];
|
||||
[_cancelButton setTitleColor:[DJDKMIMOMColor alertMessageColor] forState:UIControlStateNormal];
|
||||
[_cancelButton.titleLabel setFont:[UIFont systemFontOfSize:16]];
|
||||
_cancelButton.layer.cornerRadius = kSheetViewCornerRadius;
|
||||
_cancelButton.layer.masksToBounds = YES;
|
||||
[_cancelButton addTarget:self action:@selector(onClickCancelButtonAction:) forControlEvents:UIControlEventTouchUpInside];
|
||||
_cancelButton.hidden = YES;
|
||||
}
|
||||
return _cancelButton;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,25 +1,23 @@
|
||||
//
|
||||
// TTAlertView.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
@class TTAlertConfig;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertView : UIView
|
||||
@property (nonatomic, strong) TTAlertConfig *config;// 配置
|
||||
@property (nonatomic, assign) BOOL isConfigBoard;// 是否配置边框
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler cancelAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler confirmAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler dismissAction;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
@class TTAlertConfig;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertView : UIView
|
||||
@property (nonatomic, strong) TTAlertConfig *config;
|
||||
@property (nonatomic, assign) BOOL isConfigBoard;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler cancelAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler confirmAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler dismissAction;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
25
YuMi/CustomUI/TTPopup/View/TTAlertView.h.backup
Normal file
25
YuMi/CustomUI/TTPopup/View/TTAlertView.h.backup
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// TTAlertView.h
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TTPopupConstants.h"
|
||||
|
||||
@class TTAlertConfig;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TTAlertView : UIView
|
||||
@property (nonatomic, strong) TTAlertConfig *config;// 配置
|
||||
@property (nonatomic, assign) BOOL isConfigBoard;// 是否配置边框
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler cancelAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler confirmAction;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler dismissAction;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// TTAlertView.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
|
||||
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "TTAlertView.h"
|
||||
#import "TTAlertConfig.h"
|
||||
@@ -17,10 +15,10 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
|
||||
@interface TTAlertView ()
|
||||
|
||||
@property (nonatomic, strong) UILabel *titleLabel; // 标题
|
||||
@property (nonatomic, strong) UILabel *messageLabel; // 内容
|
||||
@property (nonatomic, strong) UIButton *cancelButton; // 取消按钮
|
||||
@property (nonatomic, strong) UIButton *confirmButton; // 确认按钮
|
||||
@property (nonatomic, strong) UILabel *titleLabel;
|
||||
@property (nonatomic, strong) UILabel *messageLabel;
|
||||
@property (nonatomic, strong) UIButton *cancelButton;
|
||||
@property (nonatomic, strong) UIButton *confirmButton;
|
||||
@property (nonatomic, strong) UIStackView *stackView;
|
||||
|
||||
@end
|
||||
@@ -86,27 +84,24 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
}
|
||||
|
||||
#pragma mark - private method
|
||||
/**
|
||||
设置 messageLabel 需要显示的富文本效果
|
||||
@param config 弹窗配置
|
||||
@return 富文本内容
|
||||
*/
|
||||
|
||||
|
||||
- (NSMutableAttributedString *)messageAttributeString:(TTAlertConfig *)config {
|
||||
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:config.message];
|
||||
if (config.messageLineSpacing > 0) { // 行间距
|
||||
if (config.messageLineSpacing > 0) {
|
||||
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
||||
paragraphStyle.lineSpacing = config.messageLineSpacing;
|
||||
paragraphStyle.alignment = config.messageTextAlignment;
|
||||
[attString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, config.message.length)];
|
||||
}
|
||||
|
||||
// 富文本显示效果
|
||||
|
||||
[config.messageAttributedConfig enumerateObjectsUsingBlock:^(TTAlertMessageAttributedConfig * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// 遍历数组,添加展示富文本效果
|
||||
|
||||
if ([obj isKindOfClass:[TTAlertMessageAttributedConfig class]]) {
|
||||
if (obj.text && obj.text.length > 0) {
|
||||
NSRange range = [config.message rangeOfString:obj.text];
|
||||
// 如果外部指定了 range 。就不用查找出的 range
|
||||
|
||||
if (obj.range.length != 0) {
|
||||
if (obj.range.location + obj.range.length > config.message.length) {
|
||||
NSAssert(NO, @"obj.range out of bounds");
|
||||
@@ -114,10 +109,10 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
}
|
||||
range = obj.range;
|
||||
}
|
||||
if (obj.font) { // 字体
|
||||
if (obj.font) {
|
||||
[attString addAttribute:NSFontAttributeName value:obj.font range:range];
|
||||
}
|
||||
if (obj.color) { // 颜色
|
||||
if (obj.color) {
|
||||
[attString addAttribute:NSForegroundColorAttributeName value:obj.color range:range];
|
||||
}
|
||||
}
|
||||
@@ -130,14 +125,14 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
|
||||
- (void)setConfig:(TTAlertConfig *)config {
|
||||
_config = config;
|
||||
// cornerRadius
|
||||
|
||||
if (config.cornerRadius > 0) {
|
||||
self.layer.cornerRadius = config.cornerRadius;
|
||||
self.layer.masksToBounds = YES;
|
||||
}
|
||||
//背景
|
||||
|
||||
self.backgroundColor = config.backgroundColor;
|
||||
// title
|
||||
|
||||
_titleLabel.text = config.title;
|
||||
_titleLabel.textColor = config.titleColor;
|
||||
_titleLabel.font = config.titleFont;
|
||||
@@ -145,7 +140,7 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
_cancelButton.hidden = config.actionStyle == TTAlertActionConfirmStyle;
|
||||
_confirmButton.hidden = config.actionStyle == TTAlertActionCancelStyle;
|
||||
|
||||
// cancel button
|
||||
|
||||
[_cancelButton setTitle:config.cancelButtonConfig.title forState:UIControlStateNormal];
|
||||
[_cancelButton setTitleColor:config.cancelButtonConfig.titleColor forState:UIControlStateNormal];
|
||||
[_cancelButton.titleLabel setFont:config.cancelButtonConfig.font];
|
||||
@@ -156,7 +151,7 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
_cancelButton.layer.masksToBounds = YES;
|
||||
}
|
||||
|
||||
// confirm button
|
||||
|
||||
[_confirmButton setTitle:config.confirmButtonConfig.title forState:UIControlStateNormal];
|
||||
[_confirmButton setTitleColor:config.confirmButtonConfig.titleColor forState:UIControlStateNormal];
|
||||
[_confirmButton.titleLabel setFont:config.confirmButtonConfig.font];
|
||||
@@ -167,7 +162,7 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
_confirmButton.layer.masksToBounds = YES;
|
||||
}
|
||||
|
||||
// message
|
||||
|
||||
_messageLabel.font = config.messageFont;
|
||||
_messageLabel.textColor = config.messageColor;
|
||||
|
||||
@@ -191,13 +186,13 @@ static CGFloat const kBtnHeight = 38.f;
|
||||
- (void)setIsConfigBoard:(BOOL)isConfigBoard {
|
||||
_isConfigBoard = isConfigBoard;
|
||||
if (isConfigBoard) {
|
||||
//需要边框
|
||||
|
||||
_cancelButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_cancelButton.layer.borderWidth = 2.f;
|
||||
_confirmButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_confirmButton.layer.borderWidth = 2.f;
|
||||
}else {
|
||||
//不需要边框
|
||||
|
||||
_cancelButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_cancelButton.layer.borderWidth = 0;
|
||||
_confirmButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
|
255
YuMi/CustomUI/TTPopup/View/TTAlertView.m.backup
Normal file
255
YuMi/CustomUI/TTPopup/View/TTAlertView.m.backup
Normal file
@@ -0,0 +1,255 @@
|
||||
//
|
||||
// TTAlertView.m
|
||||
// YM_TTChatViewKit
|
||||
//
|
||||
// Created by lee on 2019/5/20.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TTAlertView.h"
|
||||
#import "TTAlertConfig.h"
|
||||
#import "DJDKMIMOMColor.h"
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
static CGFloat const kMargin = 25.f;
|
||||
static CGFloat const kPadding = 20.f;
|
||||
static CGFloat const kBtnHeight = 38.f;
|
||||
|
||||
@interface TTAlertView ()
|
||||
|
||||
@property (nonatomic, strong) UILabel *titleLabel; // 标题
|
||||
@property (nonatomic, strong) UILabel *messageLabel; // 内容
|
||||
@property (nonatomic, strong) UIButton *cancelButton; // 取消按钮
|
||||
@property (nonatomic, strong) UIButton *confirmButton; // 确认按钮
|
||||
@property (nonatomic, strong) UIStackView *stackView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TTAlertView
|
||||
|
||||
#pragma mark - lifeCyle
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self initViews];
|
||||
[self initConstraints];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initViews {
|
||||
[self addSubview:self.titleLabel];
|
||||
[self addSubview:self.messageLabel];
|
||||
[self addSubview:self.stackView];
|
||||
[self.stackView addSubview:self.cancelButton];
|
||||
[self.stackView addSubview:self.confirmButton];
|
||||
}
|
||||
|
||||
- (void)initConstraints {
|
||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(kPadding);
|
||||
make.leading.trailing.mas_equalTo(self).inset(kPadding);
|
||||
}];
|
||||
|
||||
[self.messageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(kMargin);
|
||||
make.leading.trailing.mas_equalTo(self).inset(kPadding);
|
||||
make.bottom.mas_equalTo(self).offset(-kBtnHeight * 2);
|
||||
}];
|
||||
|
||||
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.mas_equalTo(-kPadding);
|
||||
make.centerX.mas_equalTo(self);
|
||||
}];
|
||||
|
||||
[self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(kBtnHeight);
|
||||
make.width.mas_equalTo(self.mas_width).multipliedBy(0.4);
|
||||
}];
|
||||
|
||||
[self.confirmButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(kBtnHeight);
|
||||
make.width.mas_equalTo(self.mas_width).multipliedBy(0.4);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Button Events
|
||||
- (void)onClickConfirmButtonAction:(UIButton *)confirmButton {
|
||||
!_confirmAction ?: _confirmAction();
|
||||
!_dismissAction ?: _dismissAction();
|
||||
}
|
||||
|
||||
- (void)onClickCancelButtonAction:(UIButton *)cancelButton {
|
||||
!_cancelAction ?: _cancelAction();
|
||||
!_dismissAction ?: _dismissAction();
|
||||
}
|
||||
|
||||
#pragma mark - private method
|
||||
/**
|
||||
设置 messageLabel 需要显示的富文本效果
|
||||
@param config 弹窗配置
|
||||
@return 富文本内容
|
||||
*/
|
||||
- (NSMutableAttributedString *)messageAttributeString:(TTAlertConfig *)config {
|
||||
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:config.message];
|
||||
if (config.messageLineSpacing > 0) { // 行间距
|
||||
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
||||
paragraphStyle.lineSpacing = config.messageLineSpacing;
|
||||
paragraphStyle.alignment = config.messageTextAlignment;
|
||||
[attString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, config.message.length)];
|
||||
}
|
||||
|
||||
// 富文本显示效果
|
||||
[config.messageAttributedConfig enumerateObjectsUsingBlock:^(TTAlertMessageAttributedConfig * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// 遍历数组,添加展示富文本效果
|
||||
if ([obj isKindOfClass:[TTAlertMessageAttributedConfig class]]) {
|
||||
if (obj.text && obj.text.length > 0) {
|
||||
NSRange range = [config.message rangeOfString:obj.text];
|
||||
// 如果外部指定了 range 。就不用查找出的 range
|
||||
if (obj.range.length != 0) {
|
||||
if (obj.range.location + obj.range.length > config.message.length) {
|
||||
NSAssert(NO, @"obj.range out of bounds");
|
||||
return;
|
||||
}
|
||||
range = obj.range;
|
||||
}
|
||||
if (obj.font) { // 字体
|
||||
[attString addAttribute:NSFontAttributeName value:obj.font range:range];
|
||||
}
|
||||
if (obj.color) { // 颜色
|
||||
[attString addAttribute:NSForegroundColorAttributeName value:obj.color range:range];
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
return attString;
|
||||
}
|
||||
|
||||
#pragma mark - getter && setter
|
||||
|
||||
- (void)setConfig:(TTAlertConfig *)config {
|
||||
_config = config;
|
||||
// cornerRadius
|
||||
if (config.cornerRadius > 0) {
|
||||
self.layer.cornerRadius = config.cornerRadius;
|
||||
self.layer.masksToBounds = YES;
|
||||
}
|
||||
//背景
|
||||
self.backgroundColor = config.backgroundColor;
|
||||
// title
|
||||
_titleLabel.text = config.title;
|
||||
_titleLabel.textColor = config.titleColor;
|
||||
_titleLabel.font = config.titleFont;
|
||||
|
||||
_cancelButton.hidden = config.actionStyle == TTAlertActionConfirmStyle;
|
||||
_confirmButton.hidden = config.actionStyle == TTAlertActionCancelStyle;
|
||||
|
||||
// cancel button
|
||||
[_cancelButton setTitle:config.cancelButtonConfig.title forState:UIControlStateNormal];
|
||||
[_cancelButton setTitleColor:config.cancelButtonConfig.titleColor forState:UIControlStateNormal];
|
||||
[_cancelButton.titleLabel setFont:config.cancelButtonConfig.font];
|
||||
[_cancelButton setBackgroundColor:config.cancelButtonConfig.backgroundColor];
|
||||
[_cancelButton setBackgroundImage:config.cancelButtonConfig.backgroundImage forState:UIControlStateNormal];
|
||||
if (config.cancelButtonConfig.cornerRadius > 0) {
|
||||
_cancelButton.layer.cornerRadius = config.cancelButtonConfig.cornerRadius;
|
||||
_cancelButton.layer.masksToBounds = YES;
|
||||
}
|
||||
|
||||
// confirm button
|
||||
[_confirmButton setTitle:config.confirmButtonConfig.title forState:UIControlStateNormal];
|
||||
[_confirmButton setTitleColor:config.confirmButtonConfig.titleColor forState:UIControlStateNormal];
|
||||
[_confirmButton.titleLabel setFont:config.confirmButtonConfig.font];
|
||||
[_confirmButton setBackgroundColor:config.confirmButtonConfig.backgroundColor];
|
||||
[_confirmButton setBackgroundImage:config.confirmButtonConfig.backgroundImage forState:UIControlStateNormal];
|
||||
if (config.confirmButtonConfig.cornerRadius > 0) {
|
||||
_confirmButton.layer.cornerRadius = config.confirmButtonConfig.cornerRadius;
|
||||
_confirmButton.layer.masksToBounds = YES;
|
||||
}
|
||||
|
||||
// message
|
||||
_messageLabel.font = config.messageFont;
|
||||
_messageLabel.textColor = config.messageColor;
|
||||
|
||||
if (config.messageAttributedConfig.count > 0) {
|
||||
_messageLabel.attributedText = [self messageAttributeString:config];
|
||||
_messageLabel.textAlignment = NSTextAlignmentCenter;
|
||||
} else if(config.messageAttributed.length > 0) {
|
||||
_messageLabel.attributedText = config.messageAttributed;
|
||||
_messageLabel.textAlignment = NSTextAlignmentCenter;
|
||||
} else {
|
||||
_messageLabel.text = config.message;
|
||||
_messageLabel.textAlignment = config.messageTextAlignment;
|
||||
}
|
||||
|
||||
_cancelButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_cancelButton.layer.borderWidth = 2.f;
|
||||
_confirmButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_confirmButton.layer.borderWidth = 2.f;
|
||||
}
|
||||
|
||||
- (void)setIsConfigBoard:(BOOL)isConfigBoard {
|
||||
_isConfigBoard = isConfigBoard;
|
||||
if (isConfigBoard) {
|
||||
//需要边框
|
||||
_cancelButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_cancelButton.layer.borderWidth = 2.f;
|
||||
_confirmButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_confirmButton.layer.borderWidth = 2.f;
|
||||
}else {
|
||||
//不需要边框
|
||||
_cancelButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_cancelButton.layer.borderWidth = 0;
|
||||
_confirmButton.layer.borderColor = [DJDKMIMOMColor dividerColor].CGColor;
|
||||
_confirmButton.layer.borderWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [[UILabel alloc] init];
|
||||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_titleLabel.numberOfLines = 0;
|
||||
}
|
||||
return _titleLabel ;
|
||||
}
|
||||
|
||||
- (UILabel *)messageLabel {
|
||||
if (!_messageLabel) {
|
||||
_messageLabel = [[UILabel alloc] init];
|
||||
_messageLabel.numberOfLines = 0;
|
||||
_messageLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_messageLabel.minimumScaleFactor = 0.7;
|
||||
_messageLabel.adjustsFontSizeToFitWidth = YES;
|
||||
}
|
||||
return _messageLabel;
|
||||
}
|
||||
|
||||
- (UIButton *)cancelButton {
|
||||
if (!_cancelButton) {
|
||||
_cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_cancelButton addTarget:self action:@selector(onClickCancelButtonAction:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _cancelButton;
|
||||
}
|
||||
|
||||
- (UIButton *)confirmButton {
|
||||
if (!_confirmButton) {
|
||||
_confirmButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_confirmButton addTarget:self action:@selector(onClickConfirmButtonAction:) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _confirmButton;
|
||||
}
|
||||
|
||||
- (UIStackView *)stackView {
|
||||
if (!_stackView) {
|
||||
_stackView = [[UIStackView alloc] initWithArrangedSubviews:@[self.cancelButton, self.confirmButton]];
|
||||
_stackView.distribution = UIStackViewDistributionFillEqually;
|
||||
_stackView.alignment = UIStackViewAlignmentCenter;
|
||||
_stackView.spacing = 16;
|
||||
}
|
||||
return _stackView;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,17 +1,13 @@
|
||||
//
|
||||
// TTNewAlertView.h
|
||||
// xplan-ios
|
||||
//
|
||||
|
||||
|
||||
// Created by duoban on 2023/1/9.
|
||||
//
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
|
||||
|
||||
@interface TTNewAlertView : UIView
|
||||
@property (nonatomic,copy) NSString *message;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler confirmHandle;
|
||||
|
20
YuMi/CustomUI/TTPopup/View/TTNewAlertView.h.backup
Normal file
20
YuMi/CustomUI/TTPopup/View/TTNewAlertView.h.backup
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// TTNewAlertView.h
|
||||
// xplan-ios
|
||||
//
|
||||
// Created by duoban on 2023/1/9.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
|
||||
|
||||
@interface TTNewAlertView : UIView
|
||||
@property (nonatomic,copy) NSString *message;
|
||||
@property (nonatomic, copy) TTPopupCompletionHandler confirmHandle;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// TTNewAlertView.m
|
||||
// xplan-ios
|
||||
//
|
||||
|
||||
|
||||
// Created by duoban on 2023/1/9.
|
||||
//
|
||||
|
||||
|
||||
#import "TTNewAlertView.h"
|
||||
@interface TTNewAlertView()
|
||||
@@ -58,7 +56,6 @@
|
||||
}];
|
||||
|
||||
|
||||
|
||||
}
|
||||
-(void)setMessage:(NSString *)message{
|
||||
_message = message;
|
||||
@@ -86,7 +83,7 @@
|
||||
}
|
||||
- (UILabel *)messageView{
|
||||
if (!_messageView){
|
||||
_messageView = [UILabel labelInitWithText:@"" font:kFontRegular(15) textColor:[DJDKMIMOMColor inputTextColor]];
|
||||
_messageView = [[UILabel alloc] init];
|
||||
_messageView.textAlignment = NSTextAlignmentCenter;
|
||||
_messageView.numberOfLines = 0;
|
||||
}
|
||||
|
118
YuMi/CustomUI/TTPopup/View/TTNewAlertView.m.backup
Normal file
118
YuMi/CustomUI/TTPopup/View/TTNewAlertView.m.backup
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// TTNewAlertView.m
|
||||
// xplan-ios
|
||||
//
|
||||
// Created by duoban on 2023/1/9.
|
||||
//
|
||||
|
||||
#import "TTNewAlertView.h"
|
||||
@interface TTNewAlertView()
|
||||
@property (nonatomic,strong) UIView *bgView;
|
||||
@property (nonatomic,strong) UILabel *messageView;
|
||||
@property (nonatomic,strong) UIButton *confirmBtn;
|
||||
@property (nonatomic,strong) UIButton *cancelBtn;
|
||||
@end
|
||||
@implementation TTNewAlertView
|
||||
|
||||
-(instancetype)initWithFrame:(CGRect)frame{
|
||||
self = [super initWithFrame:frame];
|
||||
if(self){
|
||||
[self initSubViews];
|
||||
[self initSubViewConstraints];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Private Method
|
||||
- (void)initSubViews {
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
[self addSubview:self.bgView];
|
||||
[self.bgView addSubview:self.messageView];
|
||||
[self.bgView addSubview:self.confirmBtn];
|
||||
[self.bgView addSubview:self.cancelBtn];
|
||||
}
|
||||
- (void)initSubViewConstraints {
|
||||
[self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_equalTo(kGetScaleWidth(310));
|
||||
make.height.mas_equalTo(kGetScaleWidth(149));
|
||||
make.center.equalTo(self);
|
||||
}];
|
||||
|
||||
|
||||
[self.confirmBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(kGetScaleWidth(110));
|
||||
make.height.mas_equalTo(kGetScaleWidth(37));
|
||||
make.leading.mas_equalTo(kGetScaleWidth(31));
|
||||
make.bottom.mas_equalTo(-kGetScaleWidth(31));
|
||||
}];
|
||||
|
||||
[self.cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.centerY.equalTo(self.confirmBtn);
|
||||
make.trailing.mas_equalTo(-kGetScaleWidth(31));
|
||||
}];
|
||||
|
||||
[self.messageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(kGetScaleWidth(25));
|
||||
make.centerX.equalTo(self);
|
||||
make.leading.trailing.equalTo(self).inset(kGetScaleWidth(10));
|
||||
}];
|
||||
|
||||
|
||||
|
||||
}
|
||||
-(void)setMessage:(NSString *)message{
|
||||
_message = message;
|
||||
_messageView.text = message;
|
||||
}
|
||||
-(void)confirmAction{
|
||||
[TTPopup dismiss];
|
||||
if(self.confirmHandle){
|
||||
self.confirmHandle();
|
||||
}
|
||||
}
|
||||
-(void)cancelAction{
|
||||
[TTPopup dismiss];
|
||||
}
|
||||
|
||||
#pragma mark -懒加载
|
||||
|
||||
- (UIView *)bgView{
|
||||
if (!_bgView){
|
||||
_bgView = [UIView new];
|
||||
_bgView.backgroundColor = [UIColor whiteColor];
|
||||
[_bgView setCornerWithLeftTopCorner:kGetScaleWidth(12) rightTopCorner:kGetScaleWidth(12) bottomLeftCorner:kGetScaleWidth(12) bottomRightCorner:kGetScaleWidth(12) size:CGSizeMake(kGetScaleWidth(310), kGetScaleWidth(149))];
|
||||
}
|
||||
return _bgView;
|
||||
}
|
||||
- (UILabel *)messageView{
|
||||
if (!_messageView){
|
||||
_messageView = [UILabel labelInitWithText:@"" font:kFontRegular(15) textColor:[DJDKMIMOMColor inputTextColor]];
|
||||
_messageView.textAlignment = NSTextAlignmentCenter;
|
||||
_messageView.numberOfLines = 0;
|
||||
}
|
||||
return _messageView;
|
||||
}
|
||||
-(UIButton *)confirmBtn{
|
||||
if (!_confirmBtn){
|
||||
_confirmBtn = [UIButton new];
|
||||
[_confirmBtn setTitle:YMLocalizedString(@"TTAlertConfig0") forState:UIControlStateNormal];
|
||||
_confirmBtn.backgroundColor = UIColorFromRGB(0xE6E6F0);
|
||||
_confirmBtn.layer.cornerRadius = kGetScaleWidth(37)/2;
|
||||
_confirmBtn.layer.masksToBounds = YES;
|
||||
[_confirmBtn addTarget:self action:@selector(confirmAction) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _confirmBtn;
|
||||
}
|
||||
-(UIButton *)cancelBtn{
|
||||
if (!_cancelBtn){
|
||||
_cancelBtn = [UIButton new];
|
||||
[_cancelBtn setTitle:YMLocalizedString(@"XPShareView7") forState:UIControlStateNormal];
|
||||
UIImage *image = [UIImage gradientColorImageFromColors:@[[DJDKMIMOMColor confirmButtonGradientStartColor],[DJDKMIMOMColor confirmButtonGradientMiddleColor],[DJDKMIMOMColor confirmButtonGradientEndColor]] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(kGetScaleWidth(110), kGetScaleWidth(37))];
|
||||
_cancelBtn.backgroundColor = [UIColor colorWithPatternImage:image];
|
||||
_cancelBtn.layer.cornerRadius = kGetScaleWidth(37)/2;
|
||||
_cancelBtn.layer.masksToBounds = YES;
|
||||
[_cancelBtn addTarget:self action:@selector(cancelAction) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _cancelBtn;
|
||||
}
|
||||
@end
|
@@ -1,65 +1,21 @@
|
||||
//
|
||||
// UIImage+Utils.h
|
||||
// YYMobileFramework
|
||||
//
|
||||
// Created by wuwei on 14/6/20.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, GradientType) {
|
||||
GradientTypeTopToBottom = 0,//从上到小
|
||||
GradientTypeLeftToRight = 1,//从左到右
|
||||
GradientTypeUpleftToLowright = 2,//左上到右下
|
||||
GradientTypeUprightToLowleft = 3,//右上到左下
|
||||
};
|
||||
|
||||
@interface UIImage (Utils)
|
||||
|
||||
- (UIImage *)grayscaleImage;
|
||||
|
||||
- (UIImage *)imageBlendInGray;
|
||||
|
||||
- (UIImage *)imageWithBlendMode:(CGBlendMode)blendMode;
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color;
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size;
|
||||
|
||||
+ (UIImage *)fixOrientation:(UIImage *)aImage;
|
||||
|
||||
- (UIImage *)imageWithColor:(UIColor *)color;
|
||||
|
||||
- (UIImage *)setCornerWithRadius:(CGFloat)radius andSize:(CGSize)size;
|
||||
|
||||
//异步生成纯色圆角图片
|
||||
- (void)imageWithSize:(CGSize)size radius:(CGFloat)radius backColor:(UIColor *)backColor completion:(void(^)(UIImage *image))completion;
|
||||
/**
|
||||
返回指定大小,颜色,渐变模式的渐变色图片
|
||||
*/
|
||||
+ (UIImage *)gradientColorImageFromColors:(NSArray<UIColor *>*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize;
|
||||
|
||||
+ (UIImage *)waterImageWithImage:(UIImage *)image waterImage:(UIImage *)waterImage waterImageRect:(CGRect)rect;
|
||||
|
||||
+ (CGSize)sizeWithImageOriginSize:(CGSize)originSize
|
||||
minSize:(CGSize)imageMinSize
|
||||
maxSize:(CGSize)imageMaxSize;
|
||||
|
||||
///裁剪图片
|
||||
- (UIImage *)cutImage:(CGSize)newSize;
|
||||
|
||||
- (UIImage *)cropRightAndBottomPixels:(NSUInteger)pixels;
|
||||
|
||||
-(UIImage *)compressWithMaxLength:(NSUInteger)maxLength;
|
||||
- (UIImage *)roundedImageWithCornerRadius:(CGFloat)cornerRadius size:(CGSize)size;
|
||||
+(UIImage *)getImageFromView:(UIView *)view;
|
||||
+ (NSString *)getImageTypeWithImageData: (NSData *)data;
|
||||
+(UIImage *)getLanguageImage:(NSString *)image;
|
||||
+(NSString *)getLanguageText:(NSString *)image;
|
||||
|
||||
- (UIImage *)resizeTo:(CGSize)size;
|
||||
|
||||
- (UIImage *)imageByApplyingAlpha:(CGFloat)alpha;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Created by wuwei on 14/6/20.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, GradientType) {
|
||||
GradientTypeTopToBottom = 0,
|
||||
GradientTypeLeftToRight = 1,
|
||||
GradientTypeUpleftToLowright = 2,
|
||||
GradientTypeUprightToLowleft = 3,
|
||||
};
|
||||
|
||||
@interface UIImage (Utils)
|
||||
|
||||
+ (UIImage *)gradientColorImageFromColors:(NSArray<UIColor *>*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize;
|
||||
+ (NSString *)getImageTypeWithImageData: (NSData *)data;
|
||||
|
||||
@end
|
||||
|
65
YuMi/CustomUI/UIImage/UIImage+Utils.h.backup
Normal file
65
YuMi/CustomUI/UIImage/UIImage+Utils.h.backup
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// UIImage+Utils.h
|
||||
// YYMobileFramework
|
||||
//
|
||||
// Created by wuwei on 14/6/20.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, GradientType) {
|
||||
GradientTypeTopToBottom = 0,//从上到小
|
||||
GradientTypeLeftToRight = 1,//从左到右
|
||||
GradientTypeUpleftToLowright = 2,//左上到右下
|
||||
GradientTypeUprightToLowleft = 3,//右上到左下
|
||||
};
|
||||
|
||||
@interface UIImage (Utils)
|
||||
|
||||
- (UIImage *)grayscaleImage;
|
||||
|
||||
- (UIImage *)imageBlendInGray;
|
||||
|
||||
- (UIImage *)imageWithBlendMode:(CGBlendMode)blendMode;
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color;
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size;
|
||||
|
||||
+ (UIImage *)fixOrientation:(UIImage *)aImage;
|
||||
|
||||
- (UIImage *)imageWithColor:(UIColor *)color;
|
||||
|
||||
- (UIImage *)setCornerWithRadius:(CGFloat)radius andSize:(CGSize)size;
|
||||
|
||||
//异步生成纯色圆角图片
|
||||
- (void)imageWithSize:(CGSize)size radius:(CGFloat)radius backColor:(UIColor *)backColor completion:(void(^)(UIImage *image))completion;
|
||||
/**
|
||||
返回指定大小,颜色,渐变模式的渐变色图片
|
||||
*/
|
||||
+ (UIImage *)gradientColorImageFromColors:(NSArray<UIColor *>*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize;
|
||||
|
||||
+ (UIImage *)waterImageWithImage:(UIImage *)image waterImage:(UIImage *)waterImage waterImageRect:(CGRect)rect;
|
||||
|
||||
+ (CGSize)sizeWithImageOriginSize:(CGSize)originSize
|
||||
minSize:(CGSize)imageMinSize
|
||||
maxSize:(CGSize)imageMaxSize;
|
||||
|
||||
///裁剪图片
|
||||
- (UIImage *)cutImage:(CGSize)newSize;
|
||||
|
||||
- (UIImage *)cropRightAndBottomPixels:(NSUInteger)pixels;
|
||||
|
||||
-(UIImage *)compressWithMaxLength:(NSUInteger)maxLength;
|
||||
- (UIImage *)roundedImageWithCornerRadius:(CGFloat)cornerRadius size:(CGSize)size;
|
||||
+(UIImage *)getImageFromView:(UIView *)view;
|
||||
+ (NSString *)getImageTypeWithImageData: (NSData *)data;
|
||||
+(UIImage *)getLanguageImage:(NSString *)image;
|
||||
+(NSString *)getLanguageText:(NSString *)image;
|
||||
|
||||
- (UIImage *)resizeTo:(CGSize)size;
|
||||
|
||||
- (UIImage *)imageByApplyingAlpha:(CGFloat)alpha;
|
||||
|
||||
@end
|
@@ -1,487 +1,13 @@
|
||||
//
|
||||
// UIImage+Utils.m
|
||||
// YYMobileFramework
|
||||
//
|
||||
|
||||
|
||||
// Created by wuwei on 14/6/20.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "UIImage+Utils.h"
|
||||
#import <ImageIO/ImageIO.h>
|
||||
|
||||
@implementation UIImage (Utils)
|
||||
- (UIImage *)grayscaleImage
|
||||
{
|
||||
CGFloat width = self.size.width;
|
||||
CGFloat height = self.size.height;
|
||||
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
|
||||
CGContextRef context = CGBitmapContextCreate(nil,
|
||||
width,
|
||||
height,
|
||||
8,
|
||||
0,
|
||||
colorSpace,
|
||||
kCGImageAlphaNone);
|
||||
// kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
|
||||
|
||||
|
||||
if (context == NULL) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGContextDrawImage(context, CGRectMake(0, 0, width, height), self.CGImage);
|
||||
CGImageRef imageRef = CGBitmapContextCreateImage(context);
|
||||
UIImage *grayscaleImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
CGContextRelease(context);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return grayscaleImage;
|
||||
}
|
||||
|
||||
|
||||
- (UIImage *)imageBlendInGray {
|
||||
|
||||
UIGraphicsBeginImageContext(self.size);
|
||||
CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextFillRect(context, bounds);
|
||||
[self drawInRect:bounds blendMode:kCGBlendModeLuminosity alpha:1.0f];
|
||||
[self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
|
||||
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return newImg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (UIImage *)imageWithBlendMode:(CGBlendMode)blendMode {
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
|
||||
CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
|
||||
UIRectFill(bounds);
|
||||
|
||||
[self drawInRect:bounds blendMode:blendMode alpha:1.0f];
|
||||
|
||||
if (blendMode != kCGBlendModeDestinationIn) {
|
||||
[self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
|
||||
}
|
||||
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return newImg;
|
||||
}
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color
|
||||
{
|
||||
return [self imageWithColor:color size:CGSizeMake(1, 1)];
|
||||
}
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size {
|
||||
if (!color || size.width <= 0 || size.height <= 0) return nil;
|
||||
CGRect rect = CGRectMake(0.0f, 0.0f, size.width + 1, size.height);
|
||||
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSetFillColorWithColor(context, color.CGColor);
|
||||
CGContextFillRect(context, rect);
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (UIImage *)fixOrientation:(UIImage *)aImage {
|
||||
|
||||
// No-op if the orientation is already correct
|
||||
if (aImage.imageOrientation == UIImageOrientationUp)
|
||||
return aImage;
|
||||
|
||||
// We need to calculate the proper transformation to make the image upright.
|
||||
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
|
||||
switch (aImage.imageOrientation) {
|
||||
case UIImageOrientationDown:
|
||||
case UIImageOrientationDownMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
|
||||
transform = CGAffineTransformRotate(transform, M_PI);
|
||||
break;
|
||||
|
||||
case UIImageOrientationLeft:
|
||||
case UIImageOrientationLeftMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
||||
transform = CGAffineTransformRotate(transform, M_PI_2);
|
||||
break;
|
||||
|
||||
case UIImageOrientationRight:
|
||||
case UIImageOrientationRightMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
|
||||
transform = CGAffineTransformRotate(transform, -M_PI_2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (aImage.imageOrientation) {
|
||||
case UIImageOrientationUpMirrored:
|
||||
case UIImageOrientationDownMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
||||
transform = CGAffineTransformScale(transform, -1, 1);
|
||||
break;
|
||||
|
||||
case UIImageOrientationLeftMirrored:
|
||||
case UIImageOrientationRightMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
|
||||
transform = CGAffineTransformScale(transform, -1, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Now we draw the underlying CGImage into a new context, applying the transform
|
||||
// calculated above.
|
||||
CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
|
||||
CGImageGetBitsPerComponent(aImage.CGImage), 0,
|
||||
CGImageGetColorSpace(aImage.CGImage),
|
||||
CGImageGetBitmapInfo(aImage.CGImage));
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
switch (aImage.imageOrientation) {
|
||||
case UIImageOrientationLeft:
|
||||
case UIImageOrientationLeftMirrored:
|
||||
case UIImageOrientationRight:
|
||||
case UIImageOrientationRightMirrored:
|
||||
// Grr...
|
||||
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
|
||||
break;
|
||||
|
||||
default:
|
||||
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
|
||||
break;
|
||||
}
|
||||
|
||||
// And now we just create a new UIImage from the drawing context
|
||||
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
|
||||
UIImage *img = [UIImage imageWithCGImage:cgimg];
|
||||
CGContextRelease(ctx);
|
||||
CGImageRelease(cgimg);
|
||||
return img;
|
||||
}
|
||||
|
||||
- (UIImage *)imageWithColor:(UIColor *)color {
|
||||
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
UIGraphicsBeginImageContext(rect.size);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGContextSetFillColorWithColor(context, [color CGColor]);
|
||||
CGContextFillRect(context, rect);
|
||||
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return image;
|
||||
|
||||
}
|
||||
|
||||
//异步生成纯色圆角图片
|
||||
- (void)imageWithSize:(CGSize)size radius:(CGFloat)radius backColor:(UIColor *)backColor completion:(void(^)(UIImage *image))completion {
|
||||
// 异步绘制裁切
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
// 利用绘图建立上下文
|
||||
UIGraphicsBeginImageContextWithOptions(size, true, 0);
|
||||
CGRect rect = CGRectMake(0, 0, size.width, size.height);
|
||||
// 填充颜色
|
||||
[backColor setFill];
|
||||
UIRectFill(rect);
|
||||
// // 贝塞尔裁切
|
||||
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
|
||||
// [path addClip];
|
||||
// [self drawInRect:rect];
|
||||
|
||||
// 获取结果
|
||||
UIImage *resultImage = [UIGraphicsGetImageFromCurrentImageContext() circularImage];
|
||||
// 关闭上下文
|
||||
UIGraphicsEndImageContext();
|
||||
// 主队列回调
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(resultImage);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
- (UIImage *)circularImage {
|
||||
// 1. 开启图形上下文
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0);
|
||||
|
||||
// 2. 描述路径
|
||||
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.size.width, self.size.height) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(self.size.width, self.size.height)];
|
||||
// UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
|
||||
|
||||
// 3. 添加裁减区域
|
||||
[path addClip];
|
||||
|
||||
// 4. 绘制图片
|
||||
[self drawAtPoint:CGPointZero];
|
||||
|
||||
// 5. 从上下文获取图片
|
||||
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// 6. 关闭上下文
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
// 7. 设置图片
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (UIImage *)gradientColorImageFromColors:(NSArray<UIColor *> *)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize{
|
||||
|
||||
NSMutableArray *ar = [NSMutableArray array];
|
||||
for(UIColor *c in colors) {
|
||||
[ar addObject:(id)c.CGColor];
|
||||
}
|
||||
UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
|
||||
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
|
||||
CGPoint start;
|
||||
CGPoint end;
|
||||
switch (gradientType) {
|
||||
case GradientTypeTopToBottom:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
case GradientTypeLeftToRight:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, 0.0);
|
||||
break;
|
||||
case GradientTypeUpleftToLowright:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, imgSize.height);
|
||||
break;
|
||||
case GradientTypeUprightToLowleft:
|
||||
start = CGPointMake(imgSize.width, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
CGGradientRelease(gradient);
|
||||
CGContextRestoreGState(context);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
- (UIImage *)setCornerWithRadius:(CGFloat)radius andSize:(CGSize)size {
|
||||
//开启图形上下文
|
||||
UIGraphicsBeginImageContext(size);
|
||||
//绘制圆角矩形
|
||||
CGRect rect = CGRectMake(0, 0, size.width, size.height);
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)];
|
||||
//将Path添加到上下文中
|
||||
CGContextAddPath(UIGraphicsGetCurrentContext(), path.CGPath);
|
||||
//裁剪上下文
|
||||
CGContextClip(UIGraphicsGetCurrentContext());
|
||||
//将图片绘制到上下文中
|
||||
[self drawInRect:rect];
|
||||
//设置绘制模式
|
||||
CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathStroke);
|
||||
//获取图片
|
||||
UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
|
||||
//关闭上下文
|
||||
UIGraphicsEndImageContext();
|
||||
//返回裁剪好的图片
|
||||
return output;
|
||||
}
|
||||
|
||||
// 给图片添加图片水印
|
||||
+ (UIImage *)waterImageWithImage:(UIImage *)image waterImage:(UIImage *)waterImage waterImageRect:(CGRect)rect
|
||||
{
|
||||
//1.获取图片
|
||||
//2.开启上下文
|
||||
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
|
||||
//3.绘制背景图片
|
||||
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
|
||||
//绘制水印图片到当前上下文
|
||||
[waterImage drawInRect:rect];
|
||||
//4.从上下文中获取新图片
|
||||
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
//5.关闭图形上下文
|
||||
UIGraphicsEndImageContext();
|
||||
//返回图片
|
||||
return newImage;
|
||||
}
|
||||
|
||||
+ (CGSize)sizeWithImageOriginSize:(CGSize)originSize
|
||||
minSize:(CGSize)imageMinSize
|
||||
maxSize:(CGSize)imageMaxSiz {
|
||||
CGSize size;
|
||||
NSInteger imageWidth = originSize.width ,imageHeight = originSize.height;
|
||||
NSInteger imageMinWidth = imageMinSize.width, imageMinHeight = imageMinSize.height;
|
||||
NSInteger imageMaxWidth = imageMaxSiz.width, imageMaxHeight = imageMaxSiz.height;
|
||||
if (imageWidth > imageHeight) //宽图
|
||||
{
|
||||
size.height = imageMinHeight; //高度取最小高度
|
||||
size.width = imageWidth * imageMinHeight / imageHeight;
|
||||
if (size.width > imageMaxWidth)
|
||||
{
|
||||
size.width = imageMaxWidth;
|
||||
}
|
||||
}
|
||||
else if(imageWidth < imageHeight)//高图
|
||||
{
|
||||
size.width = imageMinWidth;
|
||||
size.height = imageHeight *imageMinWidth / imageWidth;
|
||||
if (size.height > imageMaxHeight){
|
||||
size.height = imageMaxHeight;
|
||||
}
|
||||
}
|
||||
else//方图
|
||||
{
|
||||
if (imageWidth > imageMaxWidth){
|
||||
size.width = imageMaxWidth;
|
||||
size.height = imageMaxHeight;
|
||||
}else if(imageWidth > imageMinWidth){
|
||||
size.width = imageWidth;
|
||||
size.height = imageHeight;
|
||||
}else{
|
||||
size.width = imageMinWidth;
|
||||
size.height = imageMinHeight;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
- (UIImage *)cutImage:(CGSize)newSize{
|
||||
|
||||
CGFloat scale = newSize.height / self.size.height;
|
||||
UIImage *scaleImage = [self originImage:self scaleToSize:CGSizeMake(self.size.width*scale, self.size.height*scale)];
|
||||
//裁剪暂时有问题
|
||||
return scaleImage;
|
||||
}
|
||||
|
||||
- (UIImage *)resizeTo:(CGSize)size {
|
||||
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size];
|
||||
return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context) {
|
||||
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
}];
|
||||
}
|
||||
|
||||
- (UIImage *)cropRightAndBottomPixels:(NSUInteger)pixels {
|
||||
// 获取原图像的大小
|
||||
CGSize originalSize = self.size;
|
||||
|
||||
// 计算新的裁剪后的图像大小
|
||||
CGSize newSize = CGSizeMake(originalSize.width - pixels, originalSize.height - pixels);
|
||||
|
||||
// 开始图像上下文
|
||||
UIGraphicsBeginImageContextWithOptions(newSize, NO, self.scale);
|
||||
|
||||
// 绘制裁剪后的图像到上下文
|
||||
[self drawAtPoint:CGPointZero];
|
||||
|
||||
// 获取裁剪后的图像
|
||||
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// 结束图像上下文
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return croppedImage;
|
||||
}
|
||||
|
||||
- (UIImage*) originImage:(UIImage *)image scaleToSize:(CGSize)size {
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
|
||||
|
||||
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
|
||||
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return scaledImage;
|
||||
}
|
||||
|
||||
|
||||
-(UIImage *)compressWithMaxLength:(NSUInteger)maxLength{
|
||||
// Compress by quality
|
||||
CGFloat compression = 1;
|
||||
NSData *data = UIImageJPEGRepresentation(self, compression);
|
||||
if (data.length < maxLength) return self;
|
||||
|
||||
CGFloat max = 1;
|
||||
CGFloat min = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
compression = (max + min) / 2;
|
||||
data = UIImageJPEGRepresentation(self, compression);
|
||||
//NSLog(@"Compression = %.1f", compression);
|
||||
//NSLog(@"In compressing quality loop, image size = %ld KB", data.length / 1024);
|
||||
if (data.length < maxLength * 0.9) {
|
||||
min = compression;
|
||||
} else if (data.length > maxLength) {
|
||||
max = compression;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//NSLog(@"After compressing quality, image size = %ld KB", data.length / 1024);
|
||||
if (data.length < maxLength) return self;
|
||||
UIImage *resultImage = [UIImage imageWithData:data];
|
||||
// Compress by size
|
||||
NSUInteger lastDataLength = 0;
|
||||
while (data.length > maxLength && data.length != lastDataLength) {
|
||||
lastDataLength = data.length;
|
||||
CGFloat ratio = (CGFloat)maxLength / data.length;
|
||||
//NSLog(@"Ratio = %.1f", ratio);
|
||||
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
|
||||
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
|
||||
UIGraphicsBeginImageContext(size);
|
||||
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
resultImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
data = UIImageJPEGRepresentation(resultImage, compression);
|
||||
//NSLog(@"In compressing size loop, image size = %ld KB", data.length / 1024);
|
||||
}
|
||||
if (data) {
|
||||
return [UIImage imageWithData:data];;
|
||||
} else {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
- (UIImage *)roundedImageWithCornerRadius:(CGFloat)cornerRadius size:(CGSize)size{
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, 1);
|
||||
UIBezierPath *clippingPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:cornerRadius];
|
||||
[clippingPath addClip];
|
||||
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return roundedImage;
|
||||
}
|
||||
+(UIImage *)getImageFromView:(UIView *)view {
|
||||
// 1. 创建一个新的图像上下文,大小与view的bounds相匹配
|
||||
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
|
||||
|
||||
// 2. 获取当前图像上下文
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
// 3. 将view的层级渲染到上下文中
|
||||
[view.layer renderInContext:context];
|
||||
|
||||
// 4. 从上下文中获取生成的图片
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// 5. 结束图像上下文
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
// 6. 返回生成的图片
|
||||
return image;
|
||||
}
|
||||
+ (NSString *)getImageTypeWithImageData:(NSData *)data {
|
||||
|
||||
uint8_t c;
|
||||
@@ -530,63 +56,49 @@
|
||||
|
||||
return nil;
|
||||
}
|
||||
+(UIImage *)getLanguageImage:(NSString *)image{
|
||||
NSString *curImage = image;
|
||||
NSString *language = [NSBundle getLanguageText];
|
||||
|
||||
if (isMSZH()) {
|
||||
// 不處理
|
||||
} else if (isMSTR()) {
|
||||
image = [NSString stringWithFormat:@"%@_tr", image];
|
||||
} else if (isMSRTL()) {
|
||||
image = [NSString stringWithFormat:@"%@_ar", image];
|
||||
} else {
|
||||
image = [NSString stringWithFormat:@"%@_en", image];
|
||||
+ (UIImage *)gradientColorImageFromColors:(NSArray<UIColor *> *)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize{
|
||||
|
||||
NSMutableArray *ar = [NSMutableArray array];
|
||||
for(UIColor *c in colors) {
|
||||
[ar addObject:(id)c.CGColor];
|
||||
}
|
||||
|
||||
// 尝试获取带语言后缀的图片
|
||||
UIImage *getImage = kImage(image);
|
||||
|
||||
// 若图片不存在,尝试使用英语图片作为默认
|
||||
if (getImage == nil) {
|
||||
NSString *defaultImageName = [NSString stringWithFormat:@"%@_en", curImage];
|
||||
getImage = kImage(defaultImageName) ?: kImage(curImage);
|
||||
UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
|
||||
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
|
||||
CGPoint start;
|
||||
CGPoint end;
|
||||
switch (gradientType) {
|
||||
case GradientTypeTopToBottom:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
case GradientTypeLeftToRight:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, 0.0);
|
||||
break;
|
||||
case GradientTypeUpleftToLowright:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, imgSize.height);
|
||||
break;
|
||||
case GradientTypeUprightToLowleft:
|
||||
start = CGPointMake(imgSize.width, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return getImage;
|
||||
}
|
||||
+(NSString *)getLanguageText:(NSString *)image{
|
||||
NSString *curImage = image;
|
||||
NSString *language = [NSBundle getLanguageText];
|
||||
if ([language isEqualToString:@"en"]){
|
||||
image = [NSString stringWithFormat:@"%@_en",image];
|
||||
} else if ([language isEqualToString:@"ar"]){
|
||||
image = [NSString stringWithFormat:@"%@_ar",image];
|
||||
} else if ([language isEqualToString:@"tr"]) { // 土耳其语默认使用英语内容
|
||||
image = [NSString stringWithFormat:@"%@_en",image];
|
||||
}
|
||||
if (kImage(image) == nil){
|
||||
return curImage;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
- (UIImage *)imageByApplyingAlpha:(CGFloat)alpha {
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
|
||||
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
||||
CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
|
||||
|
||||
CGContextScaleCTM(ctx, 1, -1);
|
||||
CGContextTranslateCTM(ctx, 0, -area.size.height);
|
||||
|
||||
CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
|
||||
CGContextSetAlpha(ctx, alpha);
|
||||
CGContextDrawImage(ctx, area, self.CGImage);
|
||||
|
||||
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
CGGradientRelease(gradient);
|
||||
CGContextRestoreGState(context);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return newImage;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
592
YuMi/CustomUI/UIImage/UIImage+Utils.m.backup
Normal file
592
YuMi/CustomUI/UIImage/UIImage+Utils.m.backup
Normal file
@@ -0,0 +1,592 @@
|
||||
//
|
||||
// UIImage+Utils.m
|
||||
// YYMobileFramework
|
||||
//
|
||||
// Created by wuwei on 14/6/20.
|
||||
// Copyright (c) 2014年 YY Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIImage+Utils.h"
|
||||
#import <ImageIO/ImageIO.h>
|
||||
|
||||
@implementation UIImage (Utils)
|
||||
- (UIImage *)grayscaleImage
|
||||
{
|
||||
CGFloat width = self.size.width;
|
||||
CGFloat height = self.size.height;
|
||||
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
|
||||
|
||||
CGContextRef context = CGBitmapContextCreate(nil,
|
||||
width,
|
||||
height,
|
||||
8,
|
||||
0,
|
||||
colorSpace,
|
||||
kCGImageAlphaNone);
|
||||
// kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
|
||||
|
||||
|
||||
if (context == NULL) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGContextDrawImage(context, CGRectMake(0, 0, width, height), self.CGImage);
|
||||
CGImageRef imageRef = CGBitmapContextCreateImage(context);
|
||||
UIImage *grayscaleImage = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
CGContextRelease(context);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return grayscaleImage;
|
||||
}
|
||||
|
||||
|
||||
- (UIImage *)imageBlendInGray {
|
||||
|
||||
UIGraphicsBeginImageContext(self.size);
|
||||
CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextFillRect(context, bounds);
|
||||
[self drawInRect:bounds blendMode:kCGBlendModeLuminosity alpha:1.0f];
|
||||
[self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
|
||||
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return newImg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (UIImage *)imageWithBlendMode:(CGBlendMode)blendMode {
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
|
||||
CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
|
||||
UIRectFill(bounds);
|
||||
|
||||
[self drawInRect:bounds blendMode:blendMode alpha:1.0f];
|
||||
|
||||
if (blendMode != kCGBlendModeDestinationIn) {
|
||||
[self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
|
||||
}
|
||||
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return newImg;
|
||||
}
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color
|
||||
{
|
||||
return [self imageWithColor:color size:CGSizeMake(1, 1)];
|
||||
}
|
||||
|
||||
+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size {
|
||||
if (!color || size.width <= 0 || size.height <= 0) return nil;
|
||||
CGRect rect = CGRectMake(0.0f, 0.0f, size.width + 1, size.height);
|
||||
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSetFillColorWithColor(context, color.CGColor);
|
||||
CGContextFillRect(context, rect);
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (UIImage *)fixOrientation:(UIImage *)aImage {
|
||||
|
||||
// No-op if the orientation is already correct
|
||||
if (aImage.imageOrientation == UIImageOrientationUp)
|
||||
return aImage;
|
||||
|
||||
// We need to calculate the proper transformation to make the image upright.
|
||||
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
|
||||
CGAffineTransform transform = CGAffineTransformIdentity;
|
||||
|
||||
switch (aImage.imageOrientation) {
|
||||
case UIImageOrientationDown:
|
||||
case UIImageOrientationDownMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
|
||||
transform = CGAffineTransformRotate(transform, M_PI);
|
||||
break;
|
||||
|
||||
case UIImageOrientationLeft:
|
||||
case UIImageOrientationLeftMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
||||
transform = CGAffineTransformRotate(transform, M_PI_2);
|
||||
break;
|
||||
|
||||
case UIImageOrientationRight:
|
||||
case UIImageOrientationRightMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
|
||||
transform = CGAffineTransformRotate(transform, -M_PI_2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (aImage.imageOrientation) {
|
||||
case UIImageOrientationUpMirrored:
|
||||
case UIImageOrientationDownMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
|
||||
transform = CGAffineTransformScale(transform, -1, 1);
|
||||
break;
|
||||
|
||||
case UIImageOrientationLeftMirrored:
|
||||
case UIImageOrientationRightMirrored:
|
||||
transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
|
||||
transform = CGAffineTransformScale(transform, -1, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Now we draw the underlying CGImage into a new context, applying the transform
|
||||
// calculated above.
|
||||
CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
|
||||
CGImageGetBitsPerComponent(aImage.CGImage), 0,
|
||||
CGImageGetColorSpace(aImage.CGImage),
|
||||
CGImageGetBitmapInfo(aImage.CGImage));
|
||||
CGContextConcatCTM(ctx, transform);
|
||||
switch (aImage.imageOrientation) {
|
||||
case UIImageOrientationLeft:
|
||||
case UIImageOrientationLeftMirrored:
|
||||
case UIImageOrientationRight:
|
||||
case UIImageOrientationRightMirrored:
|
||||
// Grr...
|
||||
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
|
||||
break;
|
||||
|
||||
default:
|
||||
CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
|
||||
break;
|
||||
}
|
||||
|
||||
// And now we just create a new UIImage from the drawing context
|
||||
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
|
||||
UIImage *img = [UIImage imageWithCGImage:cgimg];
|
||||
CGContextRelease(ctx);
|
||||
CGImageRelease(cgimg);
|
||||
return img;
|
||||
}
|
||||
|
||||
- (UIImage *)imageWithColor:(UIColor *)color {
|
||||
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
UIGraphicsBeginImageContext(rect.size);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
CGContextSetFillColorWithColor(context, [color CGColor]);
|
||||
CGContextFillRect(context, rect);
|
||||
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return image;
|
||||
|
||||
}
|
||||
|
||||
//异步生成纯色圆角图片
|
||||
- (void)imageWithSize:(CGSize)size radius:(CGFloat)radius backColor:(UIColor *)backColor completion:(void(^)(UIImage *image))completion {
|
||||
// 异步绘制裁切
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
// 利用绘图建立上下文
|
||||
UIGraphicsBeginImageContextWithOptions(size, true, 0);
|
||||
CGRect rect = CGRectMake(0, 0, size.width, size.height);
|
||||
// 填充颜色
|
||||
[backColor setFill];
|
||||
UIRectFill(rect);
|
||||
// // 贝塞尔裁切
|
||||
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
|
||||
// [path addClip];
|
||||
// [self drawInRect:rect];
|
||||
|
||||
// 获取结果
|
||||
UIImage *resultImage = [UIGraphicsGetImageFromCurrentImageContext() circularImage];
|
||||
// 关闭上下文
|
||||
UIGraphicsEndImageContext();
|
||||
// 主队列回调
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completion(resultImage);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
- (UIImage *)circularImage {
|
||||
// 1. 开启图形上下文
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0);
|
||||
|
||||
// 2. 描述路径
|
||||
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.size.width, self.size.height) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(self.size.width, self.size.height)];
|
||||
// UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
|
||||
|
||||
// 3. 添加裁减区域
|
||||
[path addClip];
|
||||
|
||||
// 4. 绘制图片
|
||||
[self drawAtPoint:CGPointZero];
|
||||
|
||||
// 5. 从上下文获取图片
|
||||
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// 6. 关闭上下文
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
// 7. 设置图片
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (UIImage *)gradientColorImageFromColors:(NSArray<UIColor *> *)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize{
|
||||
|
||||
NSMutableArray *ar = [NSMutableArray array];
|
||||
for(UIColor *c in colors) {
|
||||
[ar addObject:(id)c.CGColor];
|
||||
}
|
||||
UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
|
||||
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);
|
||||
CGPoint start;
|
||||
CGPoint end;
|
||||
switch (gradientType) {
|
||||
case GradientTypeTopToBottom:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
case GradientTypeLeftToRight:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, 0.0);
|
||||
break;
|
||||
case GradientTypeUpleftToLowright:
|
||||
start = CGPointMake(0.0, 0.0);
|
||||
end = CGPointMake(imgSize.width, imgSize.height);
|
||||
break;
|
||||
case GradientTypeUprightToLowleft:
|
||||
start = CGPointMake(imgSize.width, 0.0);
|
||||
end = CGPointMake(0.0, imgSize.height);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
CGGradientRelease(gradient);
|
||||
CGContextRestoreGState(context);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
- (UIImage *)setCornerWithRadius:(CGFloat)radius andSize:(CGSize)size {
|
||||
//开启图形上下文
|
||||
UIGraphicsBeginImageContext(size);
|
||||
//绘制圆角矩形
|
||||
CGRect rect = CGRectMake(0, 0, size.width, size.height);
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(radius, radius)];
|
||||
//将Path添加到上下文中
|
||||
CGContextAddPath(UIGraphicsGetCurrentContext(), path.CGPath);
|
||||
//裁剪上下文
|
||||
CGContextClip(UIGraphicsGetCurrentContext());
|
||||
//将图片绘制到上下文中
|
||||
[self drawInRect:rect];
|
||||
//设置绘制模式
|
||||
CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathStroke);
|
||||
//获取图片
|
||||
UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
|
||||
//关闭上下文
|
||||
UIGraphicsEndImageContext();
|
||||
//返回裁剪好的图片
|
||||
return output;
|
||||
}
|
||||
|
||||
// 给图片添加图片水印
|
||||
+ (UIImage *)waterImageWithImage:(UIImage *)image waterImage:(UIImage *)waterImage waterImageRect:(CGRect)rect
|
||||
{
|
||||
//1.获取图片
|
||||
//2.开启上下文
|
||||
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
|
||||
//3.绘制背景图片
|
||||
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
|
||||
//绘制水印图片到当前上下文
|
||||
[waterImage drawInRect:rect];
|
||||
//4.从上下文中获取新图片
|
||||
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
//5.关闭图形上下文
|
||||
UIGraphicsEndImageContext();
|
||||
//返回图片
|
||||
return newImage;
|
||||
}
|
||||
|
||||
+ (CGSize)sizeWithImageOriginSize:(CGSize)originSize
|
||||
minSize:(CGSize)imageMinSize
|
||||
maxSize:(CGSize)imageMaxSiz {
|
||||
CGSize size;
|
||||
NSInteger imageWidth = originSize.width ,imageHeight = originSize.height;
|
||||
NSInteger imageMinWidth = imageMinSize.width, imageMinHeight = imageMinSize.height;
|
||||
NSInteger imageMaxWidth = imageMaxSiz.width, imageMaxHeight = imageMaxSiz.height;
|
||||
if (imageWidth > imageHeight) //宽图
|
||||
{
|
||||
size.height = imageMinHeight; //高度取最小高度
|
||||
size.width = imageWidth * imageMinHeight / imageHeight;
|
||||
if (size.width > imageMaxWidth)
|
||||
{
|
||||
size.width = imageMaxWidth;
|
||||
}
|
||||
}
|
||||
else if(imageWidth < imageHeight)//高图
|
||||
{
|
||||
size.width = imageMinWidth;
|
||||
size.height = imageHeight *imageMinWidth / imageWidth;
|
||||
if (size.height > imageMaxHeight){
|
||||
size.height = imageMaxHeight;
|
||||
}
|
||||
}
|
||||
else//方图
|
||||
{
|
||||
if (imageWidth > imageMaxWidth){
|
||||
size.width = imageMaxWidth;
|
||||
size.height = imageMaxHeight;
|
||||
}else if(imageWidth > imageMinWidth){
|
||||
size.width = imageWidth;
|
||||
size.height = imageHeight;
|
||||
}else{
|
||||
size.width = imageMinWidth;
|
||||
size.height = imageMinHeight;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
- (UIImage *)cutImage:(CGSize)newSize{
|
||||
|
||||
CGFloat scale = newSize.height / self.size.height;
|
||||
UIImage *scaleImage = [self originImage:self scaleToSize:CGSizeMake(self.size.width*scale, self.size.height*scale)];
|
||||
//裁剪暂时有问题
|
||||
return scaleImage;
|
||||
}
|
||||
|
||||
- (UIImage *)resizeTo:(CGSize)size {
|
||||
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size];
|
||||
return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull context) {
|
||||
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
}];
|
||||
}
|
||||
|
||||
- (UIImage *)cropRightAndBottomPixels:(NSUInteger)pixels {
|
||||
// 获取原图像的大小
|
||||
CGSize originalSize = self.size;
|
||||
|
||||
// 计算新的裁剪后的图像大小
|
||||
CGSize newSize = CGSizeMake(originalSize.width - pixels, originalSize.height - pixels);
|
||||
|
||||
// 开始图像上下文
|
||||
UIGraphicsBeginImageContextWithOptions(newSize, NO, self.scale);
|
||||
|
||||
// 绘制裁剪后的图像到上下文
|
||||
[self drawAtPoint:CGPointZero];
|
||||
|
||||
// 获取裁剪后的图像
|
||||
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// 结束图像上下文
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return croppedImage;
|
||||
}
|
||||
|
||||
- (UIImage*) originImage:(UIImage *)image scaleToSize:(CGSize)size {
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
|
||||
|
||||
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
|
||||
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return scaledImage;
|
||||
}
|
||||
|
||||
|
||||
-(UIImage *)compressWithMaxLength:(NSUInteger)maxLength{
|
||||
// Compress by quality
|
||||
CGFloat compression = 1;
|
||||
NSData *data = UIImageJPEGRepresentation(self, compression);
|
||||
if (data.length < maxLength) return self;
|
||||
|
||||
CGFloat max = 1;
|
||||
CGFloat min = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
compression = (max + min) / 2;
|
||||
data = UIImageJPEGRepresentation(self, compression);
|
||||
//NSLog(@"Compression = %.1f", compression);
|
||||
//NSLog(@"In compressing quality loop, image size = %ld KB", data.length / 1024);
|
||||
if (data.length < maxLength * 0.9) {
|
||||
min = compression;
|
||||
} else if (data.length > maxLength) {
|
||||
max = compression;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//NSLog(@"After compressing quality, image size = %ld KB", data.length / 1024);
|
||||
if (data.length < maxLength) return self;
|
||||
UIImage *resultImage = [UIImage imageWithData:data];
|
||||
// Compress by size
|
||||
NSUInteger lastDataLength = 0;
|
||||
while (data.length > maxLength && data.length != lastDataLength) {
|
||||
lastDataLength = data.length;
|
||||
CGFloat ratio = (CGFloat)maxLength / data.length;
|
||||
//NSLog(@"Ratio = %.1f", ratio);
|
||||
CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)),
|
||||
(NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank
|
||||
UIGraphicsBeginImageContext(size);
|
||||
[resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
resultImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
data = UIImageJPEGRepresentation(resultImage, compression);
|
||||
//NSLog(@"In compressing size loop, image size = %ld KB", data.length / 1024);
|
||||
}
|
||||
if (data) {
|
||||
return [UIImage imageWithData:data];;
|
||||
} else {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
- (UIImage *)roundedImageWithCornerRadius:(CGFloat)cornerRadius size:(CGSize)size{
|
||||
UIGraphicsBeginImageContextWithOptions(size, NO, 1);
|
||||
UIBezierPath *clippingPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width, size.height) cornerRadius:cornerRadius];
|
||||
[clippingPath addClip];
|
||||
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
|
||||
UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return roundedImage;
|
||||
}
|
||||
+(UIImage *)getImageFromView:(UIView *)view {
|
||||
// 1. 创建一个新的图像上下文,大小与view的bounds相匹配
|
||||
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
|
||||
|
||||
// 2. 获取当前图像上下文
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
// 3. 将view的层级渲染到上下文中
|
||||
[view.layer renderInContext:context];
|
||||
|
||||
// 4. 从上下文中获取生成的图片
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
|
||||
// 5. 结束图像上下文
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
// 6. 返回生成的图片
|
||||
return image;
|
||||
}
|
||||
+ (NSString *)getImageTypeWithImageData:(NSData *)data {
|
||||
|
||||
uint8_t c;
|
||||
|
||||
[data getBytes:&c length:1];
|
||||
|
||||
switch (c) {
|
||||
|
||||
case 0xFF:
|
||||
|
||||
return @"jpeg";
|
||||
|
||||
case 0x89:
|
||||
|
||||
return @"png";
|
||||
|
||||
case 0x47:
|
||||
|
||||
return @"gif";
|
||||
|
||||
case 0x49:
|
||||
|
||||
case 0x4D:
|
||||
|
||||
return @"tiff";
|
||||
|
||||
case 0x52:
|
||||
|
||||
if ([data length] < 12) {
|
||||
|
||||
return nil;
|
||||
|
||||
}
|
||||
|
||||
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
|
||||
|
||||
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
|
||||
|
||||
return @"webp";
|
||||
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
+(UIImage *)getLanguageImage:(NSString *)image{
|
||||
NSString *curImage = image;
|
||||
NSString *language = [NSBundle getLanguageText];
|
||||
|
||||
if (isMSZH()) {
|
||||
// 不處理
|
||||
} else if (isMSTR()) {
|
||||
image = [NSString stringWithFormat:@"%@_tr", image];
|
||||
} else if (isMSRTL()) {
|
||||
image = [NSString stringWithFormat:@"%@_ar", image];
|
||||
} else {
|
||||
image = [NSString stringWithFormat:@"%@_en", image];
|
||||
}
|
||||
|
||||
// 尝试获取带语言后缀的图片
|
||||
UIImage *getImage = kImage(image);
|
||||
|
||||
// 若图片不存在,尝试使用英语图片作为默认
|
||||
if (getImage == nil) {
|
||||
NSString *defaultImageName = [NSString stringWithFormat:@"%@_en", curImage];
|
||||
getImage = kImage(defaultImageName) ?: kImage(curImage);
|
||||
}
|
||||
|
||||
return getImage;
|
||||
}
|
||||
+(NSString *)getLanguageText:(NSString *)image{
|
||||
NSString *curImage = image;
|
||||
NSString *language = [NSBundle getLanguageText];
|
||||
if ([language isEqualToString:@"en"]){
|
||||
image = [NSString stringWithFormat:@"%@_en",image];
|
||||
} else if ([language isEqualToString:@"ar"]){
|
||||
image = [NSString stringWithFormat:@"%@_ar",image];
|
||||
} else if ([language isEqualToString:@"tr"]) { // 土耳其语默认使用英语内容
|
||||
image = [NSString stringWithFormat:@"%@_en",image];
|
||||
}
|
||||
if (kImage(image) == nil){
|
||||
return curImage;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
- (UIImage *)imageByApplyingAlpha:(CGFloat)alpha {
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
|
||||
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
||||
CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
|
||||
|
||||
CGContextScaleCTM(ctx, 1, -1);
|
||||
CGContextTranslateCTM(ctx, 0, -area.size.height);
|
||||
|
||||
CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
|
||||
CGContextSetAlpha(ctx, alpha);
|
||||
CGContextDrawImage(ctx, area, self.CGImage);
|
||||
|
||||
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// NetImageConfig.h
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by zu on 2021/11/25.
|
||||
//
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "UIImageConstant.h"
|
||||
|
22
YuMi/CustomUI/UIImageView/NetImageConfig.h.backup
Normal file
22
YuMi/CustomUI/UIImageView/NetImageConfig.h.backup
Normal file
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// NetImageConfig.h
|
||||
// YUMI
|
||||
//
|
||||
// Created by zu on 2021/11/25.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "UIImageConstant.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface NetImageConfig : NSObject
|
||||
|
||||
@property (nonatomic, assign) BOOL autoLoad;
|
||||
@property (nonatomic, assign) ImageType imageType;
|
||||
@property (nonatomic, assign) CGFloat radius;
|
||||
@property (nonatomic, strong) UIImage * placeHolder;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// NetImageConfig.m
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by zu on 2021/11/25.
|
||||
//
|
||||
|
||||
|
||||
#import "NetImageConfig.h"
|
||||
|
||||
|
21
YuMi/CustomUI/UIImageView/NetImageConfig.m.backup
Normal file
21
YuMi/CustomUI/UIImageView/NetImageConfig.m.backup
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// NetImageConfig.m
|
||||
// YUMI
|
||||
//
|
||||
// Created by zu on 2021/11/25.
|
||||
//
|
||||
|
||||
#import "NetImageConfig.h"
|
||||
|
||||
@implementation NetImageConfig
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_autoLoad = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// NetImageView.h
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by zu on 2021/11/2.
|
||||
//
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "UIImageConstant.h"
|
||||
@@ -24,7 +22,7 @@ typedef NS_ENUM(NSInteger, NetImageState){
|
||||
|
||||
@property (nonatomic, assign, readonly) NetImageState state;
|
||||
@property (nonatomic, copy) NSString* imageUrl;
|
||||
@property (nonatomic, assign) NSInteger backgroundLightType; // 0: non; 1: gold; 2: gray; 3: purple
|
||||
@property (nonatomic, assign) NSInteger backgroundLightType;
|
||||
|
||||
- (instancetype)initWithUrl:(NSString * _Nonnull)imageUrl;
|
||||
- (instancetype)initWithConfig:(NetImageConfig * _Nullable)config;
|
||||
|
45
YuMi/CustomUI/UIImageView/NetImageView.h.backup
Normal file
45
YuMi/CustomUI/UIImageView/NetImageView.h.backup
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// NetImageView.h
|
||||
// YUMI
|
||||
//
|
||||
// Created by zu on 2021/11/2.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "UIImageConstant.h"
|
||||
#import "NetImageConfig.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void(^LoadCompletion)(UIImage *_Nullable image, NSURL * url);
|
||||
typedef void(^LoadFail)(NSError *error);
|
||||
|
||||
typedef NS_ENUM(NSInteger, NetImageState){
|
||||
NetImageStateUnload = 1,
|
||||
NetImageStateLoading,
|
||||
NetImageStateLoaded,
|
||||
};
|
||||
|
||||
@interface NetImageView : UIImageView
|
||||
|
||||
@property (nonatomic, assign, readonly) NetImageState state;
|
||||
@property (nonatomic, copy) NSString* imageUrl;
|
||||
@property (nonatomic, assign) NSInteger backgroundLightType; // 0: non; 1: gold; 2: gray; 3: purple
|
||||
|
||||
- (instancetype)initWithUrl:(NSString * _Nonnull)imageUrl;
|
||||
- (instancetype)initWithConfig:(NetImageConfig * _Nullable)config;
|
||||
- (instancetype)initWithUrl:(NSString * _Nonnull)imageUrl config:(NetImageConfig * _Nullable)config;
|
||||
|
||||
- (UIImage *)lightImage:(NSInteger)type;
|
||||
|
||||
- (void)loadImage:(LoadCompletion _Nullable)completion;
|
||||
- (void)loadImageWithUrl:(NSString * _Nonnull)imageUrl completion:(LoadCompletion _Nullable)completion;
|
||||
- (void)loadImageWithUrl:(NSString * _Nonnull)imageUrl completion:(LoadCompletion _Nullable)completion fail:(LoadFail _Nullable)fail;
|
||||
|
||||
- (void)updateConfigPlaceHolder:(UIImage *)image;
|
||||
|
||||
- (void)cancelLoadImage;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// NetImageView.m
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by zu on 2021/11/2.
|
||||
//
|
||||
|
||||
|
||||
#import "NetImageView.h"
|
||||
#import <UIImageView+WebCache.h>
|
||||
|
151
YuMi/CustomUI/UIImageView/NetImageView.m.backup
Normal file
151
YuMi/CustomUI/UIImageView/NetImageView.m.backup
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// NetImageView.m
|
||||
// YUMI
|
||||
//
|
||||
// Created by zu on 2021/11/2.
|
||||
//
|
||||
|
||||
#import "NetImageView.h"
|
||||
#import <UIImageView+WebCache.h>
|
||||
#import <SDImageCache.h>
|
||||
|
||||
@interface NetImageView()
|
||||
|
||||
@property (nonatomic, assign, readwrite) NetImageState state;
|
||||
@property (nonatomic, copy) NSString * innerConfigUrl;
|
||||
@property (nonatomic, strong) NetImageConfig * config;
|
||||
@property (nonatomic, strong) UIImageView *lightImageView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NetImageView
|
||||
|
||||
- (instancetype)initWithUrl:(NSString *)url {
|
||||
return [self initWithUrl:url config:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithConfig:(NetImageConfig *)config {
|
||||
return [self initWithUrl:@"" config:config];
|
||||
}
|
||||
|
||||
- (instancetype)initWithUrl:(NSString *)url config:(NetImageConfig *)config {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_state = NetImageStateUnload;
|
||||
_config = config;
|
||||
if (_config.autoLoad) {
|
||||
[self setImageUrl:url];
|
||||
} else {
|
||||
[self initImageUrl:url];
|
||||
}
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)cancelLoadImage {
|
||||
[self sd_cancelCurrentImageLoad];
|
||||
}
|
||||
|
||||
- (void)initImageUrl:(NSString *)imageUrl {
|
||||
_imageUrl = imageUrl;
|
||||
_innerConfigUrl = [UIImageConstant configUrl:_imageUrl type:self.config.imageType radius:self.config.radius];
|
||||
}
|
||||
|
||||
- (void)setBackgroundLightType:(NSInteger)backgroundLightType {
|
||||
_backgroundLightType = backgroundLightType;
|
||||
if (!_lightImageView) {
|
||||
_lightImageView = [[UIImageView alloc] init];
|
||||
[self insertSubview:_lightImageView atIndex:0];
|
||||
[_lightImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.mas_equalTo(self);
|
||||
}];
|
||||
}
|
||||
switch (_backgroundLightType) {
|
||||
case 1:
|
||||
_lightImageView.image = [UIImage imageNamed:@"room_pk_result_avatar_bg_yellow"];
|
||||
break;
|
||||
case 2:
|
||||
_lightImageView.image = [UIImage imageNamed:@"room_pk_result_avatar_bg_gray"];
|
||||
break;
|
||||
case 3:
|
||||
_lightImageView.image = [UIImage imageNamed:@"room_pk_result_avatar_bg_purple"];
|
||||
break;
|
||||
default:
|
||||
_lightImageView.image = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage *)lightImage:(NSInteger)type {
|
||||
switch (type) {
|
||||
case 1:
|
||||
return [UIImage imageNamed:@"room_pk_result_avatar_bg_yellow"];
|
||||
case 2:
|
||||
return [UIImage imageNamed:@"room_pk_result_avatar_bg_gray"];
|
||||
case 3:
|
||||
return [UIImage imageNamed:@"room_pk_result_avatar_bg_purple"];
|
||||
default:
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setImageUrl:(NSString *)imageUrl {
|
||||
[self initImageUrl:imageUrl];
|
||||
[self loadImage:nil fail:nil];
|
||||
}
|
||||
|
||||
- (void)loadImage:(LoadCompletion)completion {
|
||||
[self loadImage:completion fail:nil];
|
||||
}
|
||||
|
||||
- (void)loadImageWithUrl:(NSString *)imageUrl completion:(LoadCompletion)completion {
|
||||
[self initImageUrl:imageUrl];
|
||||
[self loadImage:completion fail:nil];
|
||||
}
|
||||
|
||||
- (void)loadImageWithUrl:(NSString * _Nonnull)imageUrl completion:(LoadCompletion _Nullable)completion fail:(LoadFail _Nullable)fail{
|
||||
[self initImageUrl:imageUrl];
|
||||
[self loadImage:completion fail:fail];
|
||||
}
|
||||
|
||||
- (void)loadImage:(LoadCompletion _Nullable)completion fail:(LoadFail _Nullable)fail{
|
||||
self.state = NetImageStateLoading;
|
||||
@kWeakify(self);
|
||||
[self sd_setImageWithURL:[NSURL URLWithString:self.innerConfigUrl]
|
||||
placeholderImage:self.config.placeHolder
|
||||
options:SDWebImageRetryFailed | SDWebImageQueryMemoryData | SDWebImageQueryDiskDataSync
|
||||
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
||||
@kStrongify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (error) {
|
||||
self.state = NetImageStateUnload;
|
||||
if (fail){
|
||||
fail(error);
|
||||
}
|
||||
} else {
|
||||
self.image = image;
|
||||
self.state = NetImageStateLoaded;
|
||||
if (completion) {
|
||||
completion(image, imageURL);
|
||||
};
|
||||
}
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (NetImageConfig *)config {
|
||||
if (!_config) {
|
||||
_config = [[NetImageConfig alloc] init];
|
||||
}
|
||||
return _config;
|
||||
}
|
||||
|
||||
- (void)updateConfigPlaceHolder:(UIImage *)image {
|
||||
self.config.placeHolder = image;
|
||||
if (self.state == NetImageStateUnload) {
|
||||
self.image = image;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// UIImageViewConstant.h
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by YUMI on 2021/9/17.
|
||||
// 存放一些 加载图片 需要做的裁剪的key
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -13,35 +11,33 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
#pragma mark - 图片相关的
|
||||
UIKIT_EXTERN NSString * const kImageTypeRoomFace; //房间表情
|
||||
UIKIT_EXTERN NSString * const kImageTypeRoomGift; //房间礼物
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserIcon; //用户头像60x60
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserLibaryDetail;//用户相册大图nil
|
||||
UIKIT_EXTERN NSString * const kImageTypeCornerAvatar;//圆角图形,会先把图形裁剪成正方形,并且转换为png
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserInfoAlbum;//用户信息里面相册
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserCardLevel;///用户资料卡中 等级以高度20等比例缩放
|
||||
UIKIT_EXTERN NSString * const kImageTypeMonentsPhoto;///动态中的图片
|
||||
UIKIT_EXTERN NSString * const kImageTypeRoomFace;
|
||||
UIKIT_EXTERN NSString * const kImageTypeRoomGift;
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserIcon;
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserLibaryDetail;
|
||||
UIKIT_EXTERN NSString * const kImageTypeCornerAvatar;
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserInfoAlbum;
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserCardLevel;
|
||||
UIKIT_EXTERN NSString * const kImageTypeMonentsPhoto;
|
||||
typedef NS_ENUM(NSUInteger, ImageType){
|
||||
ImageTypeRoomFace = 1, //房间表情
|
||||
ImageTypeRoomGift, //房间礼物
|
||||
ImageTypeUserIcon, //用户头像60x60
|
||||
ImageTypeUserLibaryDetail, //用户相册大图
|
||||
ImageTypeCornerAvatar, //圆角图形,会先把图形裁剪成正方形,并且转换为png
|
||||
ImageTypeUserInfoAlbum, ///用户信息里面相册
|
||||
ImageTypeUserCardLevel, /// 用户资料卡中 等级以高度20等比例缩放
|
||||
ImageTypeMonentsPhoto, ///动态中的图片
|
||||
ImageTypeRoomFace = 1,
|
||||
ImageTypeRoomGift,
|
||||
ImageTypeUserIcon,
|
||||
ImageTypeUserLibaryDetail,
|
||||
ImageTypeCornerAvatar,
|
||||
ImageTypeUserInfoAlbum,
|
||||
ImageTypeUserCardLevel,
|
||||
ImageTypeMonentsPhoto,
|
||||
};
|
||||
|
||||
///展位图
|
||||
|
||||
/// 头像的默认占位图
|
||||
+ (UIImage *)defaultAvatarPlaceholder;
|
||||
///空白头像缺省图
|
||||
|
||||
+ (UIImage *)defaultEmptyAvatarPlaceholder;
|
||||
/// 空白图的占位图
|
||||
|
||||
+ (UIImage *)defaultEmptyPlaceholder;
|
||||
+ (UIImage *)defaultEmptyPlaceholder_UFO;
|
||||
/// banner的占位图
|
||||
|
||||
+ (UIImage *)defaultBannerPlaceholder;
|
||||
|
||||
+ (NSString*)configUrl:(NSString*)url type:(ImageType)type;
|
||||
|
53
YuMi/CustomUI/UIImageView/UIImageConstant.h.backup
Normal file
53
YuMi/CustomUI/UIImageView/UIImageConstant.h.backup
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// UIImageViewConstant.h
|
||||
// YUMI
|
||||
//
|
||||
// Created by YUMI on 2021/9/17.
|
||||
// 存放一些 加载图片 需要做的裁剪的key
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIImageConstant : NSObject
|
||||
|
||||
|
||||
#pragma mark - 图片相关的
|
||||
UIKIT_EXTERN NSString * const kImageTypeRoomFace; //房间表情
|
||||
UIKIT_EXTERN NSString * const kImageTypeRoomGift; //房间礼物
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserIcon; //用户头像60x60
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserLibaryDetail;//用户相册大图nil
|
||||
UIKIT_EXTERN NSString * const kImageTypeCornerAvatar;//圆角图形,会先把图形裁剪成正方形,并且转换为png
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserInfoAlbum;//用户信息里面相册
|
||||
UIKIT_EXTERN NSString * const kImageTypeUserCardLevel;///用户资料卡中 等级以高度20等比例缩放
|
||||
UIKIT_EXTERN NSString * const kImageTypeMonentsPhoto;///动态中的图片
|
||||
typedef NS_ENUM(NSUInteger, ImageType){
|
||||
ImageTypeRoomFace = 1, //房间表情
|
||||
ImageTypeRoomGift, //房间礼物
|
||||
ImageTypeUserIcon, //用户头像60x60
|
||||
ImageTypeUserLibaryDetail, //用户相册大图
|
||||
ImageTypeCornerAvatar, //圆角图形,会先把图形裁剪成正方形,并且转换为png
|
||||
ImageTypeUserInfoAlbum, ///用户信息里面相册
|
||||
ImageTypeUserCardLevel, /// 用户资料卡中 等级以高度20等比例缩放
|
||||
ImageTypeMonentsPhoto, ///动态中的图片
|
||||
};
|
||||
|
||||
///展位图
|
||||
|
||||
/// 头像的默认占位图
|
||||
+ (UIImage *)defaultAvatarPlaceholder;
|
||||
///空白头像缺省图
|
||||
+ (UIImage *)defaultEmptyAvatarPlaceholder;
|
||||
/// 空白图的占位图
|
||||
+ (UIImage *)defaultEmptyPlaceholder;
|
||||
+ (UIImage *)defaultEmptyPlaceholder_UFO;
|
||||
/// banner的占位图
|
||||
+ (UIImage *)defaultBannerPlaceholder;
|
||||
|
||||
+ (NSString*)configUrl:(NSString*)url type:(ImageType)type;
|
||||
+ (NSString*)configUrl:(NSString*)url radius:(CGFloat)radius;
|
||||
+ (NSString*)configUrl:(NSString*)url type:(ImageType)type radius:(CGFloat)radius;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,45 +1,43 @@
|
||||
//
|
||||
// UIImageViewConstant.m
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by YUMI on 2021/9/17.
|
||||
//
|
||||
|
||||
|
||||
#import "UIImageConstant.h"
|
||||
|
||||
@implementation UIImageConstant
|
||||
|
||||
/// 房间表情
|
||||
|
||||
NSString * const kImageTypeRoomFace = @"";
|
||||
/// 房间礼物
|
||||
|
||||
NSString * const kImageTypeRoomGift = @"";
|
||||
/// 用户头像150x150
|
||||
|
||||
NSString * const kImageTypeUserIcon = @"imageMogr2/auto-orient/thumbnail/150x150";
|
||||
/// 用户相册大图
|
||||
|
||||
NSString * const kImageTypeUserLibaryDetail = @"imageMogr2/auto-orient/thumbnail/300x300";
|
||||
NSString * const kImageTypeCornerAvatar = @"imageMogr2/auto-orient/thumbnail/300x300/format/png";
|
||||
/// 用户信息里面相册
|
||||
|
||||
NSString * const kImageTypeUserInfoAlbum = @"imageMogr2/auto-orient/blur/375x375";
|
||||
/// 用户信息里面相册
|
||||
|
||||
NSString * const kImageTypeUserCardLevel = @"imageMogr2/thumbnail/x40";
|
||||
/// 动态中的图片 400 * 400
|
||||
|
||||
NSString * const kImageTypeMonentsPhoto = @"imageMogr2/auto-orient/thumbnail/400x400";
|
||||
|
||||
/// 头像的默认占位图
|
||||
|
||||
+ (UIImage *)defaultAvatarPlaceholder {
|
||||
return [UIImage imageNamed:@"common_avatar"];
|
||||
}
|
||||
|
||||
///空白头像缺省图
|
||||
|
||||
+ (UIImage *)defaultEmptyAvatarPlaceholder {
|
||||
return [UIImage imageNamed:@"common_avatar"];
|
||||
}
|
||||
|
||||
/// 空白图的占位图
|
||||
|
||||
+ (UIImage *)defaultEmptyPlaceholder {
|
||||
return [UIImage imageNamed:@"common_empty"];
|
||||
}
|
||||
/// banner的占位图
|
||||
|
||||
+ (UIImage *)defaultBannerPlaceholder {
|
||||
return [UIImage imageNamed:@"common_banner"];
|
||||
}
|
||||
@@ -107,10 +105,10 @@ NSString * const kImageTypeMonentsPhoto = @"imageMogr2/auto-orient/thumbnail/400
|
||||
}
|
||||
|
||||
NSString *percentEscapeString(NSString *string) {
|
||||
// 创建一个包含所有不需要百分比编码的字符集
|
||||
|
||||
NSMutableCharacterSet *allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
||||
|
||||
// 手动删除你想要百分比编码的字符, 其余的非字符将会变成带 % 的转义符
|
||||
|
||||
[allowedCharacterSet removeCharactersInString:@"|"];
|
||||
|
||||
return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
|
||||
|
119
YuMi/CustomUI/UIImageView/UIImageConstant.m.backup
Normal file
119
YuMi/CustomUI/UIImageView/UIImageConstant.m.backup
Normal file
@@ -0,0 +1,119 @@
|
||||
//
|
||||
// UIImageViewConstant.m
|
||||
// YUMI
|
||||
//
|
||||
// Created by YUMI on 2021/9/17.
|
||||
//
|
||||
|
||||
#import "UIImageConstant.h"
|
||||
|
||||
@implementation UIImageConstant
|
||||
|
||||
/// 房间表情
|
||||
NSString * const kImageTypeRoomFace = @"";
|
||||
/// 房间礼物
|
||||
NSString * const kImageTypeRoomGift = @"";
|
||||
/// 用户头像150x150
|
||||
NSString * const kImageTypeUserIcon = @"imageMogr2/auto-orient/thumbnail/150x150";
|
||||
/// 用户相册大图
|
||||
NSString * const kImageTypeUserLibaryDetail = @"imageMogr2/auto-orient/thumbnail/300x300";
|
||||
NSString * const kImageTypeCornerAvatar = @"imageMogr2/auto-orient/thumbnail/300x300/format/png";
|
||||
/// 用户信息里面相册
|
||||
NSString * const kImageTypeUserInfoAlbum = @"imageMogr2/auto-orient/blur/375x375";
|
||||
/// 用户信息里面相册
|
||||
NSString * const kImageTypeUserCardLevel = @"imageMogr2/thumbnail/x40";
|
||||
/// 动态中的图片 400 * 400
|
||||
NSString * const kImageTypeMonentsPhoto = @"imageMogr2/auto-orient/thumbnail/400x400";
|
||||
|
||||
/// 头像的默认占位图
|
||||
+ (UIImage *)defaultAvatarPlaceholder {
|
||||
return [UIImage imageNamed:@"common_avatar"];
|
||||
}
|
||||
|
||||
///空白头像缺省图
|
||||
+ (UIImage *)defaultEmptyAvatarPlaceholder {
|
||||
return [UIImage imageNamed:@"common_avatar"];
|
||||
}
|
||||
|
||||
/// 空白图的占位图
|
||||
+ (UIImage *)defaultEmptyPlaceholder {
|
||||
return [UIImage imageNamed:@"common_empty"];
|
||||
}
|
||||
/// banner的占位图
|
||||
+ (UIImage *)defaultBannerPlaceholder {
|
||||
return [UIImage imageNamed:@"common_banner"];
|
||||
}
|
||||
|
||||
+ (UIImage *)defaultEmptyPlaceholder_UFO {
|
||||
return [UIImage imageNamed:@"common_empty_UFO"];
|
||||
}
|
||||
|
||||
|
||||
+ (NSString *)configUrl:(NSString *)url type:(ImageType)type {
|
||||
return [self configUrl:url type:type radius:0];
|
||||
}
|
||||
|
||||
+ (NSString *)configUrl:(NSString *)url radius:(CGFloat)radius {
|
||||
return [self configUrl:url type:-1 radius:radius];
|
||||
}
|
||||
|
||||
+ (NSString *)configUrl:(NSString *)url type:(ImageType)type radius:(CGFloat)radius {
|
||||
if (!url || url.length <= 0) return nil;
|
||||
NSMutableString *urlString = [NSMutableString stringWithString:url];
|
||||
NSString *configUrl = nil;
|
||||
switch (type) {
|
||||
case ImageTypeUserIcon:
|
||||
configUrl = kImageTypeUserIcon;
|
||||
break;
|
||||
case ImageTypeCornerAvatar:
|
||||
configUrl = kImageTypeCornerAvatar;
|
||||
break;
|
||||
case ImageTypeRoomFace:
|
||||
configUrl = kImageTypeRoomFace;
|
||||
break;
|
||||
case ImageTypeUserLibaryDetail:
|
||||
configUrl = kImageTypeUserLibaryDetail;
|
||||
break;
|
||||
case ImageTypeRoomGift:
|
||||
configUrl = kImageTypeRoomGift;
|
||||
break;
|
||||
case ImageTypeUserInfoAlbum:
|
||||
configUrl = kImageTypeUserInfoAlbum;
|
||||
break;
|
||||
case ImageTypeUserCardLevel:
|
||||
configUrl = kImageTypeUserCardLevel;
|
||||
break;
|
||||
case ImageTypeMonentsPhoto:
|
||||
configUrl = kImageTypeMonentsPhoto;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (configUrl) {
|
||||
if ([url containsString:@"?"]) {
|
||||
[urlString appendString:@"|"];
|
||||
}else{
|
||||
[urlString appendString:@"?"];
|
||||
}
|
||||
[urlString appendString:configUrl];
|
||||
}
|
||||
|
||||
if (radius > 0) {
|
||||
[urlString appendString:[NSString stringWithFormat:@"|roundPic/radius/%f", radius]];
|
||||
}
|
||||
|
||||
return percentEscapeString(urlString);
|
||||
}
|
||||
|
||||
NSString *percentEscapeString(NSString *string) {
|
||||
// 创建一个包含所有不需要百分比编码的字符集
|
||||
NSMutableCharacterSet *allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
|
||||
|
||||
// 手动删除你想要百分比编码的字符, 其余的非字符将会变成带 % 的转义符
|
||||
[allowedCharacterSet removeCharactersInString:@"|"];
|
||||
|
||||
return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
|
||||
}
|
||||
|
||||
@end
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// UIView+Corner.h
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by YUMI on 2022/6/15.
|
||||
//
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -16,44 +14,15 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
bottomRightCorner:(CGFloat)bottemRight
|
||||
size:(CGSize)size;
|
||||
|
||||
///**
|
||||
// * 设置视图的圆角半径,边框宽度和颜色
|
||||
// *
|
||||
// * @param radius 圆角半径
|
||||
// * @param corners 圆角位置 (可以组合使用 UIRectCornerTopLeft、UIRectCornerTopRight、UIRectCornerBottomLeft、UIRectCornerBottomRight)
|
||||
// * @param borderWidth 边框宽度
|
||||
// * @param borderColor 边框颜色
|
||||
// */
|
||||
//- (void)setCornerRadius:(CGFloat)radius
|
||||
// corners:(UIRectCorner)corners
|
||||
// borderWidth:(CGFloat)borderWidth
|
||||
// borderColor:(UIColor *)borderColor;
|
||||
|
||||
/**
|
||||
* 直接设置视图的圆角半径,应用到所有角
|
||||
*
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
- (void)setCornerRadius:(CGFloat)radius;
|
||||
|
||||
/**
|
||||
* 直接设置视图的圆角半径和指定角
|
||||
*
|
||||
* @param radius 圆角半径
|
||||
* @param corners 指定需要圆角的位置 (UIRectCornerTopLeft, UIRectCornerTopRight, etc.)
|
||||
*/
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius corners:(UIRectCorner)corners;
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius cornerMask:(CACornerMask)cornerMask;
|
||||
|
||||
/**
|
||||
* 设置视图的指定圆角、圆角半径、边框宽度和边框颜色
|
||||
*
|
||||
* @param radius 圆角半径
|
||||
* @param corners 需要圆角的角位置 (可以组合,例如 `kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner`)
|
||||
* @param borderWidth 边框宽度
|
||||
* @param borderColor 边框颜色
|
||||
*/
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius
|
||||
corners:(CACornerMask)corners
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
|
67
YuMi/CustomUI/UIViewCorner/UIView+Corner.h.backup
Normal file
67
YuMi/CustomUI/UIViewCorner/UIView+Corner.h.backup
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// UIView+Corner.h
|
||||
// YUMI
|
||||
//
|
||||
// Created by YUMI on 2022/6/15.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIView (Corner)
|
||||
- (void)setCornerWithLeftTopCorner:(CGFloat)leftTop
|
||||
rightTopCorner:(CGFloat)rigtTop
|
||||
bottomLeftCorner:(CGFloat)bottemLeft
|
||||
bottomRightCorner:(CGFloat)bottemRight
|
||||
size:(CGSize)size;
|
||||
|
||||
///**
|
||||
// * 设置视图的圆角半径,边框宽度和颜色
|
||||
// *
|
||||
// * @param radius 圆角半径
|
||||
// * @param corners 圆角位置 (可以组合使用 UIRectCornerTopLeft、UIRectCornerTopRight、UIRectCornerBottomLeft、UIRectCornerBottomRight)
|
||||
// * @param borderWidth 边框宽度
|
||||
// * @param borderColor 边框颜色
|
||||
// */
|
||||
//- (void)setCornerRadius:(CGFloat)radius
|
||||
// corners:(UIRectCorner)corners
|
||||
// borderWidth:(CGFloat)borderWidth
|
||||
// borderColor:(UIColor *)borderColor;
|
||||
|
||||
/**
|
||||
* 直接设置视图的圆角半径,应用到所有角
|
||||
*
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
- (void)setCornerRadius:(CGFloat)radius;
|
||||
|
||||
/**
|
||||
* 直接设置视图的圆角半径和指定角
|
||||
*
|
||||
* @param radius 圆角半径
|
||||
* @param corners 指定需要圆角的位置 (UIRectCornerTopLeft, UIRectCornerTopRight, etc.)
|
||||
*/
|
||||
- (void)setCornerRadius:(CGFloat)radius corners:(UIRectCorner)corners;
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius cornerMask:(CACornerMask)cornerMask;
|
||||
|
||||
/**
|
||||
* 设置视图的指定圆角、圆角半径、边框宽度和边框颜色
|
||||
*
|
||||
* @param radius 圆角半径
|
||||
* @param corners 需要圆角的角位置 (可以组合,例如 `kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner`)
|
||||
* @param borderWidth 边框宽度
|
||||
* @param borderColor 边框颜色
|
||||
*/
|
||||
- (void)setCornerRadius:(CGFloat)radius
|
||||
corners:(CACornerMask)corners
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor;
|
||||
|
||||
- (void)setAllCornerRadius:(CGFloat)radius
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// UIView+Corner.m
|
||||
// YUMI
|
||||
//
|
||||
|
||||
|
||||
// Created by YUMI on 2022/6/15.
|
||||
//
|
||||
|
||||
|
||||
#import "UIView+Corner.h"
|
||||
|
||||
@@ -21,18 +19,18 @@
|
||||
maskPath.lineWidth = 1.0;
|
||||
maskPath.lineCapStyle = kCGLineCapRound;
|
||||
maskPath.lineJoinStyle = kCGLineJoinRound;
|
||||
[maskPath moveToPoint:CGPointMake(bottemRight, height)]; //左下角
|
||||
[maskPath moveToPoint:CGPointMake(bottemRight, height)];
|
||||
[maskPath addLineToPoint:CGPointMake(width - bottemRight, height)];
|
||||
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(width, height- bottemRight) controlPoint:CGPointMake(width, height)]; //右下角的圆弧
|
||||
[maskPath addLineToPoint:CGPointMake(width, rigtTop)]; //右边直线
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(width, height- bottemRight) controlPoint:CGPointMake(width, height)];
|
||||
[maskPath addLineToPoint:CGPointMake(width, rigtTop)];
|
||||
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(width - rigtTop, 0) controlPoint:CGPointMake(width, 0)]; //右上角圆弧
|
||||
[maskPath addLineToPoint:CGPointMake(leftTop, 0)]; //顶部直线
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(width - rigtTop, 0) controlPoint:CGPointMake(width, 0)];
|
||||
[maskPath addLineToPoint:CGPointMake(leftTop, 0)];
|
||||
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(0, leftTop) controlPoint:CGPointMake(0, 0)]; //左上角圆弧
|
||||
[maskPath addLineToPoint:CGPointMake(0, height - bottemLeft)]; //左边直线
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(bottemLeft, height) controlPoint:CGPointMake(0, height)]; //左下角圆弧
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(0, leftTop) controlPoint:CGPointMake(0, 0)];
|
||||
[maskPath addLineToPoint:CGPointMake(0, height - bottemLeft)];
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(bottemLeft, height) controlPoint:CGPointMake(0, height)];
|
||||
|
||||
CAShapeLayer *maskLayer = [CAShapeLayer layer];
|
||||
maskLayer.frame = CGRectMake(0, 0, size.width, size.height);
|
||||
@@ -40,43 +38,17 @@
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
//- (void)setCornerRadius:(CGFloat)radius
|
||||
// corners:(UIRectCorner)corners
|
||||
// borderWidth:(CGFloat)borderWidth
|
||||
// borderColor:(UIColor *)borderColor {
|
||||
//
|
||||
// // 创建 UIBezierPath 并应用圆角
|
||||
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
|
||||
// byRoundingCorners:corners
|
||||
// cornerRadii:CGSizeMake(radius, radius)];
|
||||
//
|
||||
// // 创建 CAShapeLayer 并设置 path
|
||||
// CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
||||
// maskLayer.path = path.CGPath;
|
||||
// self.layer.mask = maskLayer;
|
||||
//
|
||||
// // 设置边框
|
||||
// if (borderWidth > 0 && borderColor) {
|
||||
// CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
|
||||
// borderLayer.path = path.CGPath;
|
||||
// borderLayer.lineWidth = borderWidth;
|
||||
// borderLayer.strokeColor = borderColor.CGColor;
|
||||
// borderLayer.fillColor = UIColor.clearColor.CGColor;
|
||||
// borderLayer.frame = self.bounds;
|
||||
// [self.layer addSublayer:borderLayer];
|
||||
// }
|
||||
//}
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius {
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.masksToBounds = YES; // 确保视图内容不会超出边界
|
||||
self.layer.masksToBounds = YES;
|
||||
}
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius corners:(UIRectCorner)corners {
|
||||
if (corners == UIRectCornerAllCorners) {
|
||||
[self setCornerRadius:radius];
|
||||
} else {
|
||||
// 如果是部分圆角,使用 `CAShapeLayer` 和 `UIBezierPath`,但仅在必要时使用
|
||||
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
|
||||
byRoundingCorners:corners
|
||||
cornerRadii:CGSizeMake(radius, radius)];
|
||||
@@ -98,12 +70,12 @@
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor {
|
||||
|
||||
// 设置指定角的圆角
|
||||
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.maskedCorners = corners;
|
||||
self.layer.masksToBounds = YES; // 确保内容不会超出边界
|
||||
self.layer.masksToBounds = YES;
|
||||
|
||||
// 设置边框
|
||||
|
||||
self.layer.borderWidth = borderWidth;
|
||||
self.layer.borderColor = borderColor.CGColor;
|
||||
}
|
||||
@@ -111,12 +83,12 @@
|
||||
- (void)setAllCornerRadius:(CGFloat)radius
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor {
|
||||
// 设置指定角的圆角
|
||||
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.maskedCorners = UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight;
|
||||
self.layer.masksToBounds = YES; // 确保内容不会超出边界
|
||||
self.layer.masksToBounds = YES;
|
||||
|
||||
// 设置边框
|
||||
|
||||
self.layer.borderWidth = borderWidth;
|
||||
self.layer.borderColor = borderColor.CGColor;
|
||||
}
|
||||
|
125
YuMi/CustomUI/UIViewCorner/UIView+Corner.m.backup
Normal file
125
YuMi/CustomUI/UIViewCorner/UIView+Corner.m.backup
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// UIView+Corner.m
|
||||
// YUMI
|
||||
//
|
||||
// Created by YUMI on 2022/6/15.
|
||||
//
|
||||
|
||||
#import "UIView+Corner.h"
|
||||
|
||||
@implementation UIView (Corner)
|
||||
|
||||
- (void)setCornerWithLeftTopCorner:(CGFloat)leftTop
|
||||
rightTopCorner:(CGFloat)rigtTop
|
||||
bottomLeftCorner:(CGFloat)bottemLeft
|
||||
bottomRightCorner:(CGFloat)bottemRight
|
||||
size:(CGSize)size {
|
||||
|
||||
CGFloat width = size.width;
|
||||
CGFloat height = size.height;
|
||||
UIBezierPath *maskPath = [UIBezierPath bezierPath];
|
||||
maskPath.lineWidth = 1.0;
|
||||
maskPath.lineCapStyle = kCGLineCapRound;
|
||||
maskPath.lineJoinStyle = kCGLineJoinRound;
|
||||
[maskPath moveToPoint:CGPointMake(bottemRight, height)]; //左下角
|
||||
[maskPath addLineToPoint:CGPointMake(width - bottemRight, height)];
|
||||
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(width, height- bottemRight) controlPoint:CGPointMake(width, height)]; //右下角的圆弧
|
||||
[maskPath addLineToPoint:CGPointMake(width, rigtTop)]; //右边直线
|
||||
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(width - rigtTop, 0) controlPoint:CGPointMake(width, 0)]; //右上角圆弧
|
||||
[maskPath addLineToPoint:CGPointMake(leftTop, 0)]; //顶部直线
|
||||
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(0, leftTop) controlPoint:CGPointMake(0, 0)]; //左上角圆弧
|
||||
[maskPath addLineToPoint:CGPointMake(0, height - bottemLeft)]; //左边直线
|
||||
[maskPath addQuadCurveToPoint:CGPointMake(bottemLeft, height) controlPoint:CGPointMake(0, height)]; //左下角圆弧
|
||||
|
||||
CAShapeLayer *maskLayer = [CAShapeLayer layer];
|
||||
maskLayer.frame = CGRectMake(0, 0, size.width, size.height);
|
||||
maskLayer.path = maskPath.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
//- (void)setCornerRadius:(CGFloat)radius
|
||||
// corners:(UIRectCorner)corners
|
||||
// borderWidth:(CGFloat)borderWidth
|
||||
// borderColor:(UIColor *)borderColor {
|
||||
//
|
||||
// // 创建 UIBezierPath 并应用圆角
|
||||
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
|
||||
// byRoundingCorners:corners
|
||||
// cornerRadii:CGSizeMake(radius, radius)];
|
||||
//
|
||||
// // 创建 CAShapeLayer 并设置 path
|
||||
// CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
||||
// maskLayer.path = path.CGPath;
|
||||
// self.layer.mask = maskLayer;
|
||||
//
|
||||
// // 设置边框
|
||||
// if (borderWidth > 0 && borderColor) {
|
||||
// CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
|
||||
// borderLayer.path = path.CGPath;
|
||||
// borderLayer.lineWidth = borderWidth;
|
||||
// borderLayer.strokeColor = borderColor.CGColor;
|
||||
// borderLayer.fillColor = UIColor.clearColor.CGColor;
|
||||
// borderLayer.frame = self.bounds;
|
||||
// [self.layer addSublayer:borderLayer];
|
||||
// }
|
||||
//}
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius {
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.masksToBounds = YES; // 确保视图内容不会超出边界
|
||||
}
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius corners:(UIRectCorner)corners {
|
||||
if (corners == UIRectCornerAllCorners) {
|
||||
[self setCornerRadius:radius];
|
||||
} else {
|
||||
// 如果是部分圆角,使用 `CAShapeLayer` 和 `UIBezierPath`,但仅在必要时使用
|
||||
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
|
||||
byRoundingCorners:corners
|
||||
cornerRadii:CGSizeMake(radius, radius)];
|
||||
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
||||
maskLayer.path = path.CGPath;
|
||||
self.layer.mask = maskLayer;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius cornerMask:(CACornerMask)cornerMask {
|
||||
self.layer.maskedCorners = cornerMask;
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.masksToBounds = YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)setCornerRadius:(CGFloat)radius
|
||||
corners:(CACornerMask)corners
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor {
|
||||
|
||||
// 设置指定角的圆角
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.maskedCorners = corners;
|
||||
self.layer.masksToBounds = YES; // 确保内容不会超出边界
|
||||
|
||||
// 设置边框
|
||||
self.layer.borderWidth = borderWidth;
|
||||
self.layer.borderColor = borderColor.CGColor;
|
||||
}
|
||||
|
||||
- (void)setAllCornerRadius:(CGFloat)radius
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor {
|
||||
// 设置指定角的圆角
|
||||
self.layer.cornerRadius = radius;
|
||||
self.layer.maskedCorners = UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight;
|
||||
self.layer.masksToBounds = YES; // 确保内容不会超出边界
|
||||
|
||||
// 设置边框
|
||||
self.layer.borderWidth = borderWidth;
|
||||
self.layer.borderColor = borderColor.CGColor;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// UIView+GradientLayer.h
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@@ -11,23 +9,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIView (GradientLayer)
|
||||
|
||||
/// 为视图添加渐变背景
|
||||
/// @param colors 渐变颜色数组 (NSArray<UIColor *> *)
|
||||
/// @param startPoint 渐变起点 (CGPoint)
|
||||
/// @param endPoint 渐变终点 (CGPoint)
|
||||
/// @param cornerRadius 圆角半径 (CGFloat)
|
||||
|
||||
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint
|
||||
cornerRadius:(CGFloat)cornerRadius;
|
||||
|
||||
/// 移除渐变背景
|
||||
|
||||
- (void)removeGradientBackground;
|
||||
|
||||
/// 更新渐变背景
|
||||
/// @param colors 渐变颜色数组 (NSArray<UIColor *> *)
|
||||
/// @param startPoint 渐变起点 (CGPoint)
|
||||
/// @param endPoint 渐变终点 (CGPoint)
|
||||
|
||||
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint;
|
||||
|
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// UIView+GradientLayer.h
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIView (GradientLayer)
|
||||
|
||||
/// 为视图添加渐变背景
|
||||
/// @param colors 渐变颜色数组 (NSArray<UIColor *> *)
|
||||
/// @param startPoint 渐变起点 (CGPoint)
|
||||
/// @param endPoint 渐变终点 (CGPoint)
|
||||
/// @param cornerRadius 圆角半径 (CGFloat)
|
||||
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint
|
||||
cornerRadius:(CGFloat)cornerRadius;
|
||||
|
||||
/// 移除渐变背景
|
||||
- (void)removeGradientBackground;
|
||||
|
||||
/// 更新渐变背景
|
||||
/// @param colors 渐变颜色数组 (NSArray<UIColor *> *)
|
||||
/// @param startPoint 渐变起点 (CGPoint)
|
||||
/// @param endPoint 渐变终点 (CGPoint)
|
||||
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,9 +1,7 @@
|
||||
//
|
||||
// UIView+GradientLayer.m
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
|
||||
#import "UIView+GradientLayer.h"
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
@@ -13,15 +11,15 @@
|
||||
static NSString * const kGradientLayerName = @"GradientLayer";
|
||||
static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
|
||||
// 添加渐变背景
|
||||
|
||||
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint
|
||||
cornerRadius:(CGFloat)cornerRadius {
|
||||
// 确保移除已有的渐变背景和 KVO 监听
|
||||
|
||||
[self removeGradientBackground];
|
||||
|
||||
// 创建渐变图层
|
||||
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.name = kGradientLayerName;
|
||||
gradientLayer.colors = [self cgColorsFromUIColors:colors];
|
||||
@@ -29,16 +27,16 @@ static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
gradientLayer.cornerRadius = cornerRadius;
|
||||
|
||||
// 初次设置 frame
|
||||
|
||||
gradientLayer.frame = self.bounds;
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
|
||||
// 添加 KVO 监听
|
||||
|
||||
[self setupLayoutObserverForGradientLayer:gradientLayer];
|
||||
}
|
||||
|
||||
// 动态更新渐变背景
|
||||
|
||||
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint {
|
||||
@@ -50,22 +48,22 @@ static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除渐变背景和监听
|
||||
|
||||
- (void)removeGradientBackground {
|
||||
// 移除渐变图层
|
||||
|
||||
CAGradientLayer *gradientLayer = [self gradientLayer];
|
||||
if (gradientLayer) {
|
||||
[gradientLayer removeFromSuperlayer];
|
||||
}
|
||||
|
||||
// 移除 KVO 监听
|
||||
|
||||
if ([self hasAddedObserver]) {
|
||||
[self removeObserver:self forKeyPath:@"bounds"];
|
||||
[self setHasAddedObserver:NO];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取渐变图层
|
||||
|
||||
- (CAGradientLayer *)gradientLayer {
|
||||
for (CALayer *layer in self.layer.sublayers) {
|
||||
if ([layer.name isEqualToString:kGradientLayerName] &&
|
||||
@@ -76,7 +74,7 @@ static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// 添加 KVO 监听
|
||||
|
||||
- (void)setupLayoutObserverForGradientLayer:(CAGradientLayer *)gradientLayer {
|
||||
if (![self hasAddedObserver]) {
|
||||
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:(__bridge void *)gradientLayer];
|
||||
@@ -84,20 +82,20 @@ static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
}
|
||||
}
|
||||
|
||||
// KVO 监听回调
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
||||
context:(void *)context {
|
||||
if ([keyPath isEqualToString:@"bounds"]) {
|
||||
CAGradientLayer *gradientLayer = (__bridge CAGradientLayer *)context;
|
||||
gradientLayer.frame = self.bounds; // 更新渐变图层的 frame
|
||||
gradientLayer.frame = self.bounds;
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
// 工具方法:转换颜色数组
|
||||
|
||||
- (NSArray *)cgColorsFromUIColors:(NSArray<UIColor *> *)colors {
|
||||
NSMutableArray *cgColors = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
@@ -106,12 +104,12 @@ static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
return [cgColors copy];
|
||||
}
|
||||
|
||||
// 工具方法:判断是否已注册 KVO
|
||||
|
||||
- (BOOL)hasAddedObserver {
|
||||
return [objc_getAssociatedObject(self, kGradientObserverKey) boolValue];
|
||||
}
|
||||
|
||||
// 工具方法:设置是否已注册 KVO
|
||||
|
||||
- (void)setHasAddedObserver:(BOOL)added {
|
||||
objc_setAssociatedObject(self, kGradientObserverKey, @(added), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
120
YuMi/CustomUI/UIViewGradientLayer/UIView+GradientLayer.m.backup
Normal file
120
YuMi/CustomUI/UIViewGradientLayer/UIView+GradientLayer.m.backup
Normal file
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// UIView+GradientLayer.m
|
||||
// YuMi
|
||||
//
|
||||
// Created by P on 2024/11/18.
|
||||
//
|
||||
|
||||
#import "UIView+GradientLayer.h"
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
@implementation UIView (GradientLayer)
|
||||
|
||||
static NSString * const kGradientLayerName = @"GradientLayer";
|
||||
static void *kGradientObserverKey = &kGradientObserverKey;
|
||||
|
||||
// 添加渐变背景
|
||||
- (void)addGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint
|
||||
cornerRadius:(CGFloat)cornerRadius {
|
||||
// 确保移除已有的渐变背景和 KVO 监听
|
||||
[self removeGradientBackground];
|
||||
|
||||
// 创建渐变图层
|
||||
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
|
||||
gradientLayer.name = kGradientLayerName;
|
||||
gradientLayer.colors = [self cgColorsFromUIColors:colors];
|
||||
gradientLayer.startPoint = startPoint;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
gradientLayer.cornerRadius = cornerRadius;
|
||||
|
||||
// 初次设置 frame
|
||||
gradientLayer.frame = self.bounds;
|
||||
|
||||
[self.layer insertSublayer:gradientLayer atIndex:0];
|
||||
|
||||
// 添加 KVO 监听
|
||||
[self setupLayoutObserverForGradientLayer:gradientLayer];
|
||||
}
|
||||
|
||||
// 动态更新渐变背景
|
||||
- (void)updateGradientBackgroundWithColors:(NSArray<UIColor *> *)colors
|
||||
startPoint:(CGPoint)startPoint
|
||||
endPoint:(CGPoint)endPoint {
|
||||
CAGradientLayer *gradientLayer = [self gradientLayer];
|
||||
if (gradientLayer) {
|
||||
gradientLayer.colors = [self cgColorsFromUIColors:colors];
|
||||
gradientLayer.startPoint = startPoint;
|
||||
gradientLayer.endPoint = endPoint;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除渐变背景和监听
|
||||
- (void)removeGradientBackground {
|
||||
// 移除渐变图层
|
||||
CAGradientLayer *gradientLayer = [self gradientLayer];
|
||||
if (gradientLayer) {
|
||||
[gradientLayer removeFromSuperlayer];
|
||||
}
|
||||
|
||||
// 移除 KVO 监听
|
||||
if ([self hasAddedObserver]) {
|
||||
[self removeObserver:self forKeyPath:@"bounds"];
|
||||
[self setHasAddedObserver:NO];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取渐变图层
|
||||
- (CAGradientLayer *)gradientLayer {
|
||||
for (CALayer *layer in self.layer.sublayers) {
|
||||
if ([layer.name isEqualToString:kGradientLayerName] &&
|
||||
[layer isKindOfClass:[CAGradientLayer class]]) {
|
||||
return (CAGradientLayer *)layer;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// 添加 KVO 监听
|
||||
- (void)setupLayoutObserverForGradientLayer:(CAGradientLayer *)gradientLayer {
|
||||
if (![self hasAddedObserver]) {
|
||||
[self addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew context:(__bridge void *)gradientLayer];
|
||||
[self setHasAddedObserver:YES];
|
||||
}
|
||||
}
|
||||
|
||||
// KVO 监听回调
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
||||
context:(void *)context {
|
||||
if ([keyPath isEqualToString:@"bounds"]) {
|
||||
CAGradientLayer *gradientLayer = (__bridge CAGradientLayer *)context;
|
||||
gradientLayer.frame = self.bounds; // 更新渐变图层的 frame
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
// 工具方法:转换颜色数组
|
||||
- (NSArray *)cgColorsFromUIColors:(NSArray<UIColor *> *)colors {
|
||||
NSMutableArray *cgColors = [NSMutableArray array];
|
||||
for (UIColor *color in colors) {
|
||||
[cgColors addObject:(id)color.CGColor];
|
||||
}
|
||||
return [cgColors copy];
|
||||
}
|
||||
|
||||
// 工具方法:判断是否已注册 KVO
|
||||
- (BOOL)hasAddedObserver {
|
||||
return [objc_getAssociatedObject(self, kGradientObserverKey) boolValue];
|
||||
}
|
||||
|
||||
// 工具方法:设置是否已注册 KVO
|
||||
- (void)setHasAddedObserver:(BOOL)added {
|
||||
objc_setAssociatedObject(self, kGradientObserverKey, @(added), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
|
||||
@end
|
@@ -103,6 +103,6 @@
|
||||
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
|
||||
|
||||
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;
|
||||
///为图片增加毛玻璃,value模糊程度
|
||||
|
||||
+(UIImage *)setBlurImage:(UIImage *)image value:(CGFloat)value;
|
||||
@end
|
||||
|
108
YuMi/CustomUI/VagueImageView/UIImage+ImageEffects.h.backup
Executable file
108
YuMi/CustomUI/VagueImageView/UIImage+ImageEffects.h.backup
Executable file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
File: UIImage+ImageEffects.h
|
||||
Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur.
|
||||
Version: 1.0
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
|
||||
Copyright © 2013 Apple Inc. All rights reserved.
|
||||
WWDC 2013 License
|
||||
|
||||
NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013
|
||||
Session. Please refer to the applicable WWDC 2013 Session for further
|
||||
information.
|
||||
|
||||
IMPORTANT: This Apple software is supplied to you by Apple Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and
|
||||
your use, installation, modification or redistribution of this Apple
|
||||
software constitutes acceptance of these terms. If you do not agree with
|
||||
these terms, please do not use, install, modify or redistribute this
|
||||
Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a non-exclusive license, under
|
||||
Apple's copyrights in this original Apple software (the "Apple
|
||||
Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES
|
||||
NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
|
||||
IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
EA1002
|
||||
5/3/2013
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIImage (ImageEffects)
|
||||
|
||||
- (UIImage *)applyLightEffect;
|
||||
- (UIImage *)applyExtraLightEffect;
|
||||
- (UIImage *)applyDarkEffect;
|
||||
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
|
||||
|
||||
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;
|
||||
///为图片增加毛玻璃,value模糊程度
|
||||
+(UIImage *)setBlurImage:(UIImage *)image value:(CGFloat)value;
|
||||
@end
|
@@ -146,17 +146,17 @@
|
||||
|
||||
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
|
||||
{
|
||||
// Check pre-conditions.
|
||||
|
||||
if (self.size.width < 1 || self.size.height < 1) {
|
||||
// NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
|
||||
|
||||
return nil;
|
||||
}
|
||||
if (!self.CGImage) {
|
||||
// NSLog (@"*** error: image must be backed by a CGImage: %@", self);
|
||||
|
||||
return nil;
|
||||
}
|
||||
if (maskImage && !maskImage.CGImage) {
|
||||
// NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -187,22 +187,12 @@
|
||||
effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);
|
||||
|
||||
if (hasBlur) {
|
||||
// A description of how to compute the box kernel width from the Gaussian
|
||||
// radius (aka standard deviation) appears in the SVG spec:
|
||||
// http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
|
||||
//
|
||||
// For larger values of 's' (s >= 2.0), an approximation can be used: Three
|
||||
// successive box-blurs build a piece-wise quadratic convolution kernel, which
|
||||
// approximates the Gaussian kernel to within roughly 3%.
|
||||
//
|
||||
// let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)
|
||||
//
|
||||
// ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.
|
||||
//
|
||||
|
||||
|
||||
CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
|
||||
NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
|
||||
if (radius % 2 != 1) {
|
||||
radius += 1; // force radius to be odd so that the three box-blur methodology works.
|
||||
radius += 1;
|
||||
}
|
||||
vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
|
||||
vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
|
||||
@@ -240,16 +230,16 @@
|
||||
UIGraphicsEndImageContext();
|
||||
}
|
||||
|
||||
// Set up output context.
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
|
||||
CGContextRef outputContext = UIGraphicsGetCurrentContext();
|
||||
CGContextScaleCTM(outputContext, 1.0, -1.0);
|
||||
CGContextTranslateCTM(outputContext, 0, -self.size.height);
|
||||
|
||||
// Draw base image.
|
||||
|
||||
CGContextDrawImage(outputContext, imageRect, self.CGImage);
|
||||
|
||||
// Draw effect image.
|
||||
|
||||
if (hasBlur) {
|
||||
CGContextSaveGState(outputContext);
|
||||
if (maskImage) {
|
||||
@@ -259,7 +249,7 @@
|
||||
CGContextRestoreGState(outputContext);
|
||||
}
|
||||
|
||||
// Add in color tint.
|
||||
|
||||
if (tintColor) {
|
||||
CGContextSaveGState(outputContext);
|
||||
CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
|
||||
@@ -267,7 +257,7 @@
|
||||
CGContextRestoreGState(outputContext);
|
||||
}
|
||||
|
||||
// Output image is ready.
|
||||
|
||||
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
@@ -277,28 +267,25 @@
|
||||
|
||||
|
||||
CIContext *context = [CIContext contextWithOptions:nil];
|
||||
CIImage * sourceImage = [CIImage imageWithCGImage:image.CGImage];//将图片转换成CIImage
|
||||
CIImage * sourceImage = [CIImage imageWithCGImage:image.CGImage];
|
||||
|
||||
///图片仿射滤镜
|
||||
|
||||
CIFilter * clamp = [CIFilter filterWithName:@"CIAffineClamp"];
|
||||
|
||||
CIFilter * clamp = [CIFilter filterWithName:@"CIAffineClamp"];//设置绘制类型
|
||||
|
||||
[clamp setValue:sourceImage forKey:kCIInputImageKey];//设置要绘制的图片
|
||||
[clamp setValue:sourceImage forKey:kCIInputImageKey];
|
||||
|
||||
CIImage *clampResult = [clamp valueForKey:kCIOutputImageKey];
|
||||
|
||||
///高斯模糊滤镜
|
||||
|
||||
|
||||
CIFilter* gaussianBlur = [CIFilter filterWithName:@"CIGaussianBlur"];
|
||||
|
||||
[gaussianBlur setValue:clampResult forKey:kCIInputImageKey];
|
||||
|
||||
[gaussianBlur setValue:[NSNumber numberWithFloat:value] forKey:@"inputRadius"];//设置模糊值
|
||||
[gaussianBlur setValue:[NSNumber numberWithFloat:value] forKey:@"inputRadius"];
|
||||
|
||||
CIImage * gaussianBlurResult = [gaussianBlur valueForKey:kCIOutputImageKey];
|
||||
|
||||
///转化获取图片
|
||||
|
||||
|
||||
CGImageRef cgImage = [context createCGImage:gaussianBlurResult fromRect:[sourceImage extent]];
|
||||
|
||||
UIImage * resultImage = [UIImage imageWithCGImage:cgImage];
|
||||
|
309
YuMi/CustomUI/VagueImageView/UIImage+ImageEffects.m.backup
Executable file
309
YuMi/CustomUI/VagueImageView/UIImage+ImageEffects.m.backup
Executable file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
File: UIImage+ImageEffects.m
|
||||
Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur.
|
||||
Version: 1.0
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
|
||||
Copyright © 2013 Apple Inc. All rights reserved.
|
||||
WWDC 2013 License
|
||||
|
||||
NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013
|
||||
Session. Please refer to the applicable WWDC 2013 Session for further
|
||||
information.
|
||||
|
||||
IMPORTANT: This Apple software is supplied to you by Apple Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and
|
||||
your use, installation, modification or redistribution of this Apple
|
||||
software constitutes acceptance of these terms. If you do not agree with
|
||||
these terms, please do not use, install, modify or redistribute this
|
||||
Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a non-exclusive license, under
|
||||
Apple's copyrights in this original Apple software (the "Apple
|
||||
Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES
|
||||
NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
|
||||
IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
EA1002
|
||||
5/3/2013
|
||||
*/
|
||||
|
||||
#import "UIImage+ImageEffects.h"
|
||||
|
||||
#import <Accelerate/Accelerate.h>
|
||||
#import <float.h>
|
||||
|
||||
|
||||
@implementation UIImage (ImageEffects)
|
||||
|
||||
|
||||
- (UIImage *)applyLightEffect
|
||||
{
|
||||
UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
|
||||
return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
|
||||
}
|
||||
|
||||
|
||||
- (UIImage *)applyExtraLightEffect
|
||||
{
|
||||
UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];
|
||||
return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
|
||||
}
|
||||
|
||||
|
||||
- (UIImage *)applyDarkEffect
|
||||
{
|
||||
UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];
|
||||
return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
|
||||
}
|
||||
|
||||
|
||||
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor
|
||||
{
|
||||
const CGFloat EffectColorAlpha = 0.6;
|
||||
UIColor *effectColor = tintColor;
|
||||
int componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
|
||||
if (componentCount == 2) {
|
||||
CGFloat b;
|
||||
if ([tintColor getWhite:&b alpha:NULL]) {
|
||||
effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
|
||||
}
|
||||
}
|
||||
else {
|
||||
CGFloat r, g, b;
|
||||
if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) {
|
||||
effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
|
||||
}
|
||||
}
|
||||
return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil];
|
||||
}
|
||||
|
||||
|
||||
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
|
||||
{
|
||||
// Check pre-conditions.
|
||||
if (self.size.width < 1 || self.size.height < 1) {
|
||||
// NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
|
||||
return nil;
|
||||
}
|
||||
if (!self.CGImage) {
|
||||
// NSLog (@"*** error: image must be backed by a CGImage: %@", self);
|
||||
return nil;
|
||||
}
|
||||
if (maskImage && !maskImage.CGImage) {
|
||||
// NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGRect imageRect = { CGPointZero, self.size };
|
||||
UIImage *effectImage = self;
|
||||
|
||||
BOOL hasBlur = blurRadius > __FLT_EPSILON__;
|
||||
BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;
|
||||
if (hasBlur || hasSaturationChange) {
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
|
||||
CGContextRef effectInContext = UIGraphicsGetCurrentContext();
|
||||
CGContextScaleCTM(effectInContext, 1.0, -1.0);
|
||||
CGContextTranslateCTM(effectInContext, 0, -self.size.height);
|
||||
CGContextDrawImage(effectInContext, imageRect, self.CGImage);
|
||||
|
||||
vImage_Buffer effectInBuffer;
|
||||
effectInBuffer.data = CGBitmapContextGetData(effectInContext);
|
||||
effectInBuffer.width = CGBitmapContextGetWidth(effectInContext);
|
||||
effectInBuffer.height = CGBitmapContextGetHeight(effectInContext);
|
||||
effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
|
||||
CGContextRef effectOutContext = UIGraphicsGetCurrentContext();
|
||||
vImage_Buffer effectOutBuffer;
|
||||
effectOutBuffer.data = CGBitmapContextGetData(effectOutContext);
|
||||
effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext);
|
||||
effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext);
|
||||
effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);
|
||||
|
||||
if (hasBlur) {
|
||||
// A description of how to compute the box kernel width from the Gaussian
|
||||
// radius (aka standard deviation) appears in the SVG spec:
|
||||
// http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
|
||||
//
|
||||
// For larger values of 's' (s >= 2.0), an approximation can be used: Three
|
||||
// successive box-blurs build a piece-wise quadratic convolution kernel, which
|
||||
// approximates the Gaussian kernel to within roughly 3%.
|
||||
//
|
||||
// let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)
|
||||
//
|
||||
// ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.
|
||||
//
|
||||
CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
|
||||
NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
|
||||
if (radius % 2 != 1) {
|
||||
radius += 1; // force radius to be odd so that the three box-blur methodology works.
|
||||
}
|
||||
vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
|
||||
vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
|
||||
vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);
|
||||
}
|
||||
BOOL effectImageBuffersAreSwapped = NO;
|
||||
if (hasSaturationChange) {
|
||||
CGFloat s = saturationDeltaFactor;
|
||||
CGFloat floatingPointSaturationMatrix[] = {
|
||||
0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0,
|
||||
0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0,
|
||||
0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0,
|
||||
0, 0, 0, 1,
|
||||
};
|
||||
const int32_t divisor = 256;
|
||||
NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);
|
||||
int16_t saturationMatrix[matrixSize];
|
||||
for (NSUInteger i = 0; i < matrixSize; ++i) {
|
||||
saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);
|
||||
}
|
||||
if (hasBlur) {
|
||||
vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
|
||||
effectImageBuffersAreSwapped = YES;
|
||||
}
|
||||
else {
|
||||
vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
|
||||
}
|
||||
}
|
||||
if (!effectImageBuffersAreSwapped)
|
||||
effectImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
if (effectImageBuffersAreSwapped)
|
||||
effectImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
}
|
||||
|
||||
// Set up output context.
|
||||
UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
|
||||
CGContextRef outputContext = UIGraphicsGetCurrentContext();
|
||||
CGContextScaleCTM(outputContext, 1.0, -1.0);
|
||||
CGContextTranslateCTM(outputContext, 0, -self.size.height);
|
||||
|
||||
// Draw base image.
|
||||
CGContextDrawImage(outputContext, imageRect, self.CGImage);
|
||||
|
||||
// Draw effect image.
|
||||
if (hasBlur) {
|
||||
CGContextSaveGState(outputContext);
|
||||
if (maskImage) {
|
||||
CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
|
||||
}
|
||||
CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
|
||||
CGContextRestoreGState(outputContext);
|
||||
}
|
||||
|
||||
// Add in color tint.
|
||||
if (tintColor) {
|
||||
CGContextSaveGState(outputContext);
|
||||
CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
|
||||
CGContextFillRect(outputContext, imageRect);
|
||||
CGContextRestoreGState(outputContext);
|
||||
}
|
||||
|
||||
// Output image is ready.
|
||||
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
return outputImage;
|
||||
}
|
||||
+(UIImage *)setBlurImage:(UIImage *)image value:(CGFloat)value{
|
||||
|
||||
|
||||
CIContext *context = [CIContext contextWithOptions:nil];
|
||||
CIImage * sourceImage = [CIImage imageWithCGImage:image.CGImage];//将图片转换成CIImage
|
||||
|
||||
///图片仿射滤镜
|
||||
|
||||
CIFilter * clamp = [CIFilter filterWithName:@"CIAffineClamp"];//设置绘制类型
|
||||
|
||||
[clamp setValue:sourceImage forKey:kCIInputImageKey];//设置要绘制的图片
|
||||
|
||||
CIImage *clampResult = [clamp valueForKey:kCIOutputImageKey];
|
||||
|
||||
///高斯模糊滤镜
|
||||
|
||||
CIFilter* gaussianBlur = [CIFilter filterWithName:@"CIGaussianBlur"];
|
||||
|
||||
[gaussianBlur setValue:clampResult forKey:kCIInputImageKey];
|
||||
|
||||
[gaussianBlur setValue:[NSNumber numberWithFloat:value] forKey:@"inputRadius"];//设置模糊值
|
||||
|
||||
CIImage * gaussianBlurResult = [gaussianBlur valueForKey:kCIOutputImageKey];
|
||||
|
||||
///转化获取图片
|
||||
|
||||
CGImageRef cgImage = [context createCGImage:gaussianBlurResult fromRect:[sourceImage extent]];
|
||||
|
||||
UIImage * resultImage = [UIImage imageWithCGImage:cgImage];
|
||||
return resultImage;
|
||||
|
||||
}
|
||||
|
||||
@end
|
@@ -1,31 +1,21 @@
|
||||
//
|
||||
// YMCurrentVCStackManager.h
|
||||
// YMBaseUIKit
|
||||
//
|
||||
// Created by 卫明何 on 2018/8/9.
|
||||
// Copyright © 2018年 YUIMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface XCCurrentVCStackManager : NSObject
|
||||
|
||||
+ (instancetype)shareManager;
|
||||
|
||||
/**
|
||||
当前的导航控制器
|
||||
|
||||
@return 导航控制器
|
||||
*/
|
||||
- (UINavigationController *)currentNavigationController;
|
||||
|
||||
/**
|
||||
当前最顶层控制器
|
||||
|
||||
@return 当前最顶层控制器
|
||||
*/
|
||||
- (UIViewController *)getCurrentVC;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// Created by 卫明何 on 2018/8/9.
|
||||
// Copyright © 2018年 YUIMI. All rights reserved.
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface XCCurrentVCStackManager : NSObject
|
||||
|
||||
+ (instancetype)shareManager;
|
||||
|
||||
|
||||
- (UINavigationController *)currentNavigationController;
|
||||
|
||||
|
||||
- (UIViewController *)getCurrentVC;
|
||||
|
||||
|
||||
@end
|
||||
|
31
YuMi/CustomUI/XCCurrentVCStackManager.h.backup
Normal file
31
YuMi/CustomUI/XCCurrentVCStackManager.h.backup
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// YMCurrentVCStackManager.h
|
||||
// YMBaseUIKit
|
||||
//
|
||||
// Created by 卫明何 on 2018/8/9.
|
||||
// Copyright © 2018年 YUIMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface XCCurrentVCStackManager : NSObject
|
||||
|
||||
+ (instancetype)shareManager;
|
||||
|
||||
/**
|
||||
当前的导航控制器
|
||||
|
||||
@return 导航控制器
|
||||
*/
|
||||
- (UINavigationController *)currentNavigationController;
|
||||
|
||||
/**
|
||||
当前最顶层控制器
|
||||
|
||||
@return 当前最顶层控制器
|
||||
*/
|
||||
- (UIViewController *)getCurrentVC;
|
||||
|
||||
|
||||
@end
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// YMCurrentVCStackManager.m
|
||||
// YMBaseUIKit
|
||||
//
|
||||
|
||||
|
||||
// Created by 卫明何 on 2018/8/9.
|
||||
// Copyright © 2018年 YUIMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "XCCurrentVCStackManager.h"
|
||||
|
||||
@@ -22,7 +20,7 @@ NSString * const kRoomChatPushViewKey = @"kRoomChatPushViewKey";
|
||||
}
|
||||
|
||||
- (UIViewController *)getCurrentVC {
|
||||
///兼容房间内私聊的
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRoomChatPushViewKey object:nil];
|
||||
|
||||
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
|
||||
@@ -33,19 +31,19 @@ NSString * const kRoomChatPushViewKey = @"kRoomChatPushViewKey";
|
||||
- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC {
|
||||
UIViewController *currentVC;
|
||||
if ([rootVC presentedViewController]) {
|
||||
// 视图是被presented出来的
|
||||
|
||||
rootVC = [rootVC presentedViewController];
|
||||
}
|
||||
if ([rootVC isKindOfClass:[UITabBarController class]]) {
|
||||
// 根视图为UITabBarController
|
||||
|
||||
currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
|
||||
|
||||
} else if ([rootVC isKindOfClass:[UINavigationController class]]) {
|
||||
// 根视图为UINavigationController
|
||||
|
||||
currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
|
||||
|
||||
} else {
|
||||
// 根视图为非导航类
|
||||
|
||||
currentVC = rootVC;
|
||||
}
|
||||
return currentVC;
|
||||
@@ -80,7 +78,6 @@ NSString * const kRoomChatPushViewKey = @"kRoomChatPushViewKey";
|
||||
}
|
||||
|
||||
|
||||
//递归
|
||||
- (UINavigationController *)getCurrentNCFrom:(UIViewController *)vc{
|
||||
if ([vc isKindOfClass:NSClassFromString(@"MMDrawerController")]) {
|
||||
vc = (UIViewController *)[vc valueForKey:@"centerViewController"];
|
||||
|
123
YuMi/CustomUI/XCCurrentVCStackManager.m.backup
Normal file
123
YuMi/CustomUI/XCCurrentVCStackManager.m.backup
Normal file
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// YMCurrentVCStackManager.m
|
||||
// YMBaseUIKit
|
||||
//
|
||||
// Created by 卫明何 on 2018/8/9.
|
||||
// Copyright © 2018年 YUIMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XCCurrentVCStackManager.h"
|
||||
|
||||
NSString * const kRoomChatPushViewKey = @"kRoomChatPushViewKey";
|
||||
@implementation XCCurrentVCStackManager
|
||||
|
||||
+ (instancetype)shareManager {
|
||||
static dispatch_once_t onceToken = 0;
|
||||
static id instance;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[self alloc] init];
|
||||
});
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (UIViewController *)getCurrentVC {
|
||||
///兼容房间内私聊的
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRoomChatPushViewKey object:nil];
|
||||
|
||||
UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
|
||||
UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
|
||||
return currentVC;
|
||||
}
|
||||
|
||||
- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC {
|
||||
UIViewController *currentVC;
|
||||
if ([rootVC presentedViewController]) {
|
||||
// 视图是被presented出来的
|
||||
rootVC = [rootVC presentedViewController];
|
||||
}
|
||||
if ([rootVC isKindOfClass:[UITabBarController class]]) {
|
||||
// 根视图为UITabBarController
|
||||
currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
|
||||
|
||||
} else if ([rootVC isKindOfClass:[UINavigationController class]]) {
|
||||
// 根视图为UINavigationController
|
||||
currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
|
||||
|
||||
} else {
|
||||
// 根视图为非导航类
|
||||
currentVC = rootVC;
|
||||
}
|
||||
return currentVC;
|
||||
}
|
||||
|
||||
- (UIViewController *)currentViewController {
|
||||
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
|
||||
UIViewController *vc = keyWindow.rootViewController;
|
||||
while (vc.presentedViewController) {
|
||||
vc = vc.presentedViewController;
|
||||
if ([vc isKindOfClass:[UINavigationController class]]) {
|
||||
vc = [(UINavigationController *)vc visibleViewController];
|
||||
}
|
||||
else if ([vc isKindOfClass:[UITabBarController class]]) {
|
||||
vc = [(UITabBarController *)vc selectedViewController];
|
||||
}
|
||||
}
|
||||
return vc;
|
||||
}
|
||||
|
||||
- (UINavigationController *)currentNavigationController {
|
||||
return [self currentNC];
|
||||
}
|
||||
|
||||
- (UINavigationController *)currentNC{
|
||||
if (![[UIApplication sharedApplication].windows.lastObject isKindOfClass:[UIWindow class]]) {
|
||||
NSAssert(0, @"未获取到导航控制器");
|
||||
return nil;
|
||||
}
|
||||
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
|
||||
return [self getCurrentNCFrom:rootViewController];
|
||||
}
|
||||
|
||||
|
||||
//递归
|
||||
- (UINavigationController *)getCurrentNCFrom:(UIViewController *)vc{
|
||||
if ([vc isKindOfClass:NSClassFromString(@"MMDrawerController")]) {
|
||||
vc = (UIViewController *)[vc valueForKey:@"centerViewController"];
|
||||
}
|
||||
if ([vc isKindOfClass:[UITabBarController class]]) {
|
||||
UINavigationController *nc = ((UITabBarController *)vc).selectedViewController;
|
||||
return [self getCurrentNCFrom:nc];
|
||||
}
|
||||
else if ([vc isKindOfClass:[UINavigationController class]]) {
|
||||
if (((UINavigationController *)vc).presentedViewController) {
|
||||
return [self getCurrentNCFrom:((UINavigationController *)vc).presentedViewController];
|
||||
}
|
||||
return [self getCurrentNCFrom:((UINavigationController *)vc).topViewController];
|
||||
}
|
||||
else if ([vc isKindOfClass:[UIViewController class]]) {
|
||||
if (vc.presentedViewController) {
|
||||
return [self getCurrentNCFrom:vc.presentedViewController];
|
||||
}
|
||||
else {
|
||||
if (!vc.navigationController) {
|
||||
if (vc.presentingViewController) {
|
||||
[vc dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
return [self getCurrentNCFrom:vc.presentingViewController];
|
||||
} else {
|
||||
NSAssert(0, @"未获取到导航控制器");
|
||||
return nil;
|
||||
}
|
||||
} else {
|
||||
return vc.navigationController;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSAssert(0, @"未获取到导航控制器");
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@@ -1,148 +1,76 @@
|
||||
//
|
||||
// YMHUDTool.h
|
||||
// TTPlay
|
||||
//
|
||||
// Created by YM on 2022/5/15.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
showGIFLoading使用注意:
|
||||
1.谁负责showLoading, 谁负责hideHUD
|
||||
2.showLoading是指定了加载在那个View, hideHUD时请指定hide那个view的hud
|
||||
*/
|
||||
|
||||
@interface XNDJTDDLoadingTool : NSObject
|
||||
/**
|
||||
隐藏HUD
|
||||
*/
|
||||
+ (void)hideHUD;
|
||||
|
||||
/**
|
||||
隐藏HUD, 如果view为nil, 则默认隐藏主窗口的HUD
|
||||
|
||||
@param view view
|
||||
*/
|
||||
+ (void)hideHUDInView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+(void)hideOnlyView:(UIView *)view;
|
||||
+(void)showOnlyView:(UIView *)view;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
显示成功message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message;
|
||||
|
||||
/**
|
||||
显示成功message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
显示成功message
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
显示错误message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message;
|
||||
|
||||
/**
|
||||
显示错误message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
显示错误message
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
在窗口上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
*/
|
||||
+ (void)showGIFLoading;
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading
|
||||
|
||||
@param view 显示在哪个view上
|
||||
@param bgColor 背景颜色, 遮盖
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view bgColor:(nullable UIColor *)bgColor enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
加载下一个个播房
|
||||
*/
|
||||
+ (void)showAnchorLoading;
|
||||
|
||||
+ (void)showAnchorLoading:(UIView *)view;
|
||||
|
||||
/**
|
||||
在窗口上显示菊花
|
||||
*/
|
||||
+ (void)showLoading;
|
||||
|
||||
/**
|
||||
在view上显示菊花
|
||||
*/
|
||||
+ (void)showLoadingInView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
在view上显示菊花
|
||||
*/
|
||||
+ (void)showLoadingInView:(nullable UIView *)view enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
在窗口上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message;
|
||||
|
||||
/**
|
||||
在view上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
在view上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view enabled:(BOOL)enabled;
|
||||
+(void)showOnlyView:(UIView *)view enabled:(BOOL)enabled;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
|
||||
// Created by YM on 2022/5/15.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@interface XNDJTDDLoadingTool : NSObject
|
||||
|
||||
|
||||
+ (void)hideHUD;
|
||||
|
||||
|
||||
+ (void)hideHUDInView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+(void)hideOnlyView:(UIView *)view;
|
||||
+(void)showOnlyView:(UIView *)view;
|
||||
|
||||
|
||||
+ (void)showSuccessWithMessage:(NSString *)message;
|
||||
|
||||
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled;
|
||||
|
||||
|
||||
+ (void)showErrorWithMessage:(NSString *)message;
|
||||
|
||||
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled;
|
||||
|
||||
|
||||
+ (void)showGIFLoading;
|
||||
|
||||
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view bgColor:(nullable UIColor *)bgColor enabled:(BOOL)enabled;
|
||||
|
||||
|
||||
+ (void)showAnchorLoading;
|
||||
|
||||
+ (void)showAnchorLoading:(UIView *)view;
|
||||
|
||||
|
||||
+ (void)showLoading;
|
||||
|
||||
|
||||
+ (void)showLoadingInView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+ (void)showLoadingInView:(nullable UIView *)view enabled:(BOOL)enabled;
|
||||
|
||||
|
||||
+ (void)showLoadingWithMessage:(NSString *)message;
|
||||
|
||||
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view enabled:(BOOL)enabled;
|
||||
+(void)showOnlyView:(UIView *)view enabled:(BOOL)enabled;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
148
YuMi/CustomUI/XNDJTDDLoadingTool.h.backup
Normal file
148
YuMi/CustomUI/XNDJTDDLoadingTool.h.backup
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// YMHUDTool.h
|
||||
// TTPlay
|
||||
//
|
||||
// Created by YM on 2022/5/15.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
showGIFLoading使用注意:
|
||||
1.谁负责showLoading, 谁负责hideHUD
|
||||
2.showLoading是指定了加载在那个View, hideHUD时请指定hide那个view的hud
|
||||
*/
|
||||
|
||||
@interface XNDJTDDLoadingTool : NSObject
|
||||
/**
|
||||
隐藏HUD
|
||||
*/
|
||||
+ (void)hideHUD;
|
||||
|
||||
/**
|
||||
隐藏HUD, 如果view为nil, 则默认隐藏主窗口的HUD
|
||||
|
||||
@param view view
|
||||
*/
|
||||
+ (void)hideHUDInView:(nullable UIView *)view;
|
||||
|
||||
|
||||
+(void)hideOnlyView:(UIView *)view;
|
||||
+(void)showOnlyView:(UIView *)view;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
显示成功message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message;
|
||||
|
||||
/**
|
||||
显示成功message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
显示成功message
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
显示错误message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message;
|
||||
|
||||
/**
|
||||
显示错误message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
显示错误message
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
在窗口上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
*/
|
||||
+ (void)showGIFLoading;
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading
|
||||
|
||||
@param view 显示在哪个view上
|
||||
@param bgColor 背景颜色, 遮盖
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view bgColor:(nullable UIColor *)bgColor enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
加载下一个个播房
|
||||
*/
|
||||
+ (void)showAnchorLoading;
|
||||
|
||||
+ (void)showAnchorLoading:(UIView *)view;
|
||||
|
||||
/**
|
||||
在窗口上显示菊花
|
||||
*/
|
||||
+ (void)showLoading;
|
||||
|
||||
/**
|
||||
在view上显示菊花
|
||||
*/
|
||||
+ (void)showLoadingInView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
在view上显示菊花
|
||||
*/
|
||||
+ (void)showLoadingInView:(nullable UIView *)view enabled:(BOOL)enabled;
|
||||
|
||||
/**
|
||||
在窗口上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message;
|
||||
|
||||
/**
|
||||
在view上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view;
|
||||
|
||||
/**
|
||||
在view上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view enabled:(BOOL)enabled;
|
||||
+(void)showOnlyView:(UIView *)view enabled:(BOOL)enabled;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@@ -1,10 +1,8 @@
|
||||
//
|
||||
// YMHUDTool.m
|
||||
// TTPlay
|
||||
//
|
||||
|
||||
|
||||
// Created by YM on 2022/5/15.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
#import "XNDJTDDLoadingTool.h"
|
||||
#import "GCDHelper.h"
|
||||
@@ -13,7 +11,7 @@
|
||||
|
||||
#define kDelayTime 2.5
|
||||
@interface XNDJTDDLoadingTool ()
|
||||
///
|
||||
|
||||
@property (class,nonatomic,copy) NSArray *animationImages;
|
||||
@end
|
||||
|
||||
@@ -21,11 +19,7 @@
|
||||
|
||||
static NSArray * _animationImages = nil;
|
||||
|
||||
/**
|
||||
隐藏HUD, 如果view为nil, 则默认隐藏主窗口的HUD
|
||||
|
||||
@param view view
|
||||
*/
|
||||
|
||||
+ (void)hideHUDInView:(nullable UIView *)view {
|
||||
dispatch_main_sync_safe(^{
|
||||
if (view) {
|
||||
@@ -68,39 +62,22 @@ static NSArray * _animationImages = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
隐藏HUD
|
||||
*/
|
||||
|
||||
+ (void)hideHUD {
|
||||
[self hideHUDInView:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
显示成功message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
|
||||
+ (void)showSuccessWithMessage:(NSString *)message {
|
||||
[self showSuccessWithMessage:message inView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
显示成功message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view {
|
||||
[self showSuccessWithMessage:message inView:view delay:kDelayTime enabled:NO];
|
||||
}
|
||||
|
||||
/**
|
||||
显示成功message
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled {
|
||||
|
||||
if (message.length == 0) { return; }
|
||||
@@ -110,13 +87,13 @@ static NSArray * _animationImages = nil;
|
||||
if (!inView) {
|
||||
inView = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
[self hideHUDInView:view]; // 先隐藏
|
||||
[self hideHUDInView:view];
|
||||
MBProgressHUD *hud = [self normalProgressHUD:view];
|
||||
hud.userInteractionEnabled = enabled;
|
||||
hud.mode = MBProgressHUDModeText;
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.margin = 8;
|
||||
// 方框背景颜色
|
||||
|
||||
hud.bezelView.color = [[UIColor blackColor] colorWithAlphaComponent:0.8];
|
||||
hud.label.text = message;
|
||||
hud.label.numberOfLines = 0;
|
||||
@@ -126,40 +103,24 @@ static NSArray * _animationImages = nil;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
显示错误message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
|
||||
+ (void)showErrorWithMessage:(NSString *)message {
|
||||
[self showErrorWithMessage:message inView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
显示错误message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view {
|
||||
[self showErrorWithMessage:message inView:view delay:kDelayTime enabled:NO];
|
||||
}
|
||||
|
||||
/**
|
||||
显示错误message
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled {
|
||||
if (message.length == 0) { return; }
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
|
||||
[self hideHUDInView:view]; // 先隐藏
|
||||
[self hideHUDInView:view];
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [self normalProgressHUD:view];
|
||||
@@ -167,7 +128,7 @@ static NSArray * _animationImages = nil;
|
||||
hud.mode = MBProgressHUDModeText;
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.margin = 8;
|
||||
// 方框背景颜色
|
||||
|
||||
hud.bezelView.color = [[UIColor blackColor] colorWithAlphaComponent:0.8];
|
||||
hud.label.text = message;
|
||||
hud.label.numberOfLines = 0;
|
||||
@@ -177,52 +138,40 @@ static NSArray * _animationImages = nil;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 在窗口上显示菊花
|
||||
*/
|
||||
|
||||
+ (void)showLoading {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
return;
|
||||
[self showLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花
|
||||
*/
|
||||
|
||||
+ (void)showLoadingInView:(nullable UIView *)view {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
return;
|
||||
[self showLoadingInView:view enabled:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花
|
||||
*/
|
||||
|
||||
+ (void)showLoadingInView:(nullable UIView *)view enabled:(BOOL)enabled {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
return;
|
||||
[self showLoadingWithMessage:@"" inView:view enabled:enabled];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在窗口上显示菊花+文字
|
||||
*/
|
||||
|
||||
+ (void)showLoadingWithMessage:(NSString *)message {
|
||||
|
||||
[self showLoadingWithMessage:message inView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花+文字
|
||||
*/
|
||||
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view {
|
||||
|
||||
[self showLoadingWithMessage:message inView:view enabled:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花+文字
|
||||
*/
|
||||
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view enabled:(BOOL)enabled {
|
||||
|
||||
|
||||
@@ -246,28 +195,17 @@ static NSArray * _animationImages = nil;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
在窗口上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
*/
|
||||
|
||||
+ (void)showGIFLoading {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view {
|
||||
[self showGIFLoadingInView:view bgColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.35] enabled:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading
|
||||
@param view 显示在哪个view上
|
||||
@param bgColor 背景颜色, 遮盖
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view bgColor:(nullable UIColor *)bgColor enabled:(BOOL)enabled {
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
@@ -324,7 +262,6 @@ static NSArray * _animationImages = nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (UIView *)loadingView {
|
||||
UIView *bgView = [UIView new];
|
||||
bgView.backgroundColor = [UIColor clearColor];
|
||||
@@ -334,7 +271,6 @@ static NSArray * _animationImages = nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+(void)hideOnlyView:(UIView *)view{
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
|
391
YuMi/CustomUI/XNDJTDDLoadingTool.m.backup
Normal file
391
YuMi/CustomUI/XNDJTDDLoadingTool.m.backup
Normal file
@@ -0,0 +1,391 @@
|
||||
//
|
||||
// YMHUDTool.m
|
||||
// TTPlay
|
||||
//
|
||||
// Created by YM on 2022/5/15.
|
||||
// Copyright © 2023 YUMI. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XNDJTDDLoadingTool.h"
|
||||
#import "GCDHelper.h"
|
||||
#import <MBProgressHUD/MBProgressHUD.h>
|
||||
#import "MvpViewController.h"
|
||||
|
||||
#define kDelayTime 2.5
|
||||
@interface XNDJTDDLoadingTool ()
|
||||
///
|
||||
@property (class,nonatomic,copy) NSArray *animationImages;
|
||||
@end
|
||||
|
||||
@implementation XNDJTDDLoadingTool
|
||||
|
||||
static NSArray * _animationImages = nil;
|
||||
|
||||
/**
|
||||
隐藏HUD, 如果view为nil, 则默认隐藏主窗口的HUD
|
||||
|
||||
@param view view
|
||||
*/
|
||||
+ (void)hideHUDInView:(nullable UIView *)view {
|
||||
dispatch_main_sync_safe(^{
|
||||
if (view) {
|
||||
MBProgressHUD *hud = [XNDJTDDLoadingTool HUDForView:view];
|
||||
|
||||
if (hud != nil && hud.mode != MBProgressHUDModeText) {
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
[hud hideAnimated:NO];
|
||||
}
|
||||
MBProgressHUD *windowHud = [XNDJTDDLoadingTool HUDForView:kWindow];
|
||||
if (windowHud != nil && windowHud.mode != MBProgressHUDModeText) {
|
||||
windowHud.removeFromSuperViewOnHide = YES;
|
||||
[windowHud hideAnimated:NO];
|
||||
}
|
||||
} else {
|
||||
MBProgressHUD *windowHud = [XNDJTDDLoadingTool HUDForView:kWindow];
|
||||
if (windowHud != nil && windowHud.mode != MBProgressHUDModeText) {
|
||||
windowHud.removeFromSuperViewOnHide = YES;
|
||||
[windowHud hideAnimated:NO];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+ (MBProgressHUD *)HUDForView:(UIView *)view {
|
||||
NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator];
|
||||
for (UIView *subview in subviewsEnum) {
|
||||
if ([subview isKindOfClass:[MBProgressHUD class]]) {
|
||||
MBProgressHUD *hud = (MBProgressHUD *)subview;
|
||||
id hasFinished = [hud valueForKey:@"hasFinished"];
|
||||
if (hasFinished != nil) {
|
||||
if([hasFinished boolValue] == NO){
|
||||
return hud;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
隐藏HUD
|
||||
*/
|
||||
+ (void)hideHUD {
|
||||
[self hideHUDInView:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
显示成功message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message {
|
||||
[self showSuccessWithMessage:message inView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
显示成功message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view {
|
||||
[self showSuccessWithMessage:message inView:view delay:kDelayTime enabled:NO];
|
||||
}
|
||||
|
||||
/**
|
||||
显示成功message
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showSuccessWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled {
|
||||
|
||||
if (message.length == 0) { return; }
|
||||
__block UIView *inView = view;
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
if (!inView) {
|
||||
inView = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
[self hideHUDInView:view]; // 先隐藏
|
||||
MBProgressHUD *hud = [self normalProgressHUD:view];
|
||||
hud.userInteractionEnabled = enabled;
|
||||
hud.mode = MBProgressHUDModeText;
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.margin = 8;
|
||||
// 方框背景颜色
|
||||
hud.bezelView.color = [[UIColor blackColor] colorWithAlphaComponent:0.8];
|
||||
hud.label.text = message;
|
||||
hud.label.numberOfLines = 0;
|
||||
hud.label.textColor = [UIColor whiteColor];
|
||||
hud.label.font = [UIFont systemFontOfSize:14];
|
||||
[hud hideAnimated:YES afterDelay:afterDelay];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
显示错误message, 默认显示在窗口上, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message {
|
||||
[self showErrorWithMessage:message inView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
显示错误message, 2.5s后消失, 默认不拦截点击事件
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view {
|
||||
[self showErrorWithMessage:message inView:view delay:kDelayTime enabled:NO];
|
||||
}
|
||||
|
||||
/**
|
||||
显示错误message
|
||||
|
||||
@param message 文字
|
||||
@param view 显示在哪个view上
|
||||
@param afterDelay 延迟消失时间
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showErrorWithMessage:(NSString *)message inView:(nullable UIView *)view delay:(NSTimeInterval)afterDelay enabled:(BOOL)enabled {
|
||||
if (message.length == 0) { return; }
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
|
||||
[self hideHUDInView:view]; // 先隐藏
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [self normalProgressHUD:view];
|
||||
hud.userInteractionEnabled = enabled;
|
||||
hud.mode = MBProgressHUDModeText;
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.margin = 8;
|
||||
// 方框背景颜色
|
||||
hud.bezelView.color = [[UIColor blackColor] colorWithAlphaComponent:0.8];
|
||||
hud.label.text = message;
|
||||
hud.label.numberOfLines = 0;
|
||||
hud.label.textColor = [UIColor whiteColor];
|
||||
hud.label.font = [UIFont systemFontOfSize:14];
|
||||
[hud hideAnimated:YES afterDelay:afterDelay];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 在窗口上显示菊花
|
||||
*/
|
||||
+ (void)showLoading {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
return;
|
||||
[self showLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花
|
||||
*/
|
||||
+ (void)showLoadingInView:(nullable UIView *)view {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
return;
|
||||
[self showLoadingInView:view enabled:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花
|
||||
*/
|
||||
+ (void)showLoadingInView:(nullable UIView *)view enabled:(BOOL)enabled {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
return;
|
||||
[self showLoadingWithMessage:@"" inView:view enabled:enabled];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在窗口上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message {
|
||||
|
||||
[self showLoadingWithMessage:message inView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view {
|
||||
|
||||
[self showLoadingWithMessage:message inView:view enabled:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
* 在view上显示菊花+文字
|
||||
*/
|
||||
+ (void)showLoadingWithMessage:(NSString *)message inView:(nullable UIView *)view enabled:(BOOL)enabled {
|
||||
|
||||
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
[self hideHUDInView:view];
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.userInteractionEnabled = enabled;
|
||||
hud.bezelView.color = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
if (message.length) {
|
||||
hud.label.text = message;
|
||||
hud.label.numberOfLines = 0;
|
||||
hud.label.textColor = [UIColor blackColor];
|
||||
hud.label.font = [UIFont systemFontOfSize:14];
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
在窗口上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
*/
|
||||
+ (void)showGIFLoading {
|
||||
[self showGIFLoadingInView:[UIApplication sharedApplication].keyWindow];
|
||||
}
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading, 背景默认黑色0.35透明度, 默认拦截点击事件
|
||||
|
||||
@param view 显示在哪个view上
|
||||
*/
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view {
|
||||
[self showGIFLoadingInView:view bgColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.35] enabled:YES];
|
||||
}
|
||||
|
||||
/**
|
||||
在指定的view上显示自定义GIFLoading
|
||||
@param view 显示在哪个view上
|
||||
@param bgColor 背景颜色, 遮盖
|
||||
@param enabled 是否可以拦截事件 no:不拦截 yes:拦截
|
||||
*/
|
||||
+ (void)showGIFLoadingInView:(nullable UIView *)view bgColor:(nullable UIColor *)bgColor enabled:(BOOL)enabled {
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
[self hideHUDInView:view];
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.minSize = CGSizeMake(100, 150);
|
||||
hud.userInteractionEnabled = NO;
|
||||
hud.mode = MBProgressHUDModeCustomView;
|
||||
[hud.bezelView addSubview:[self loadingView]];
|
||||
hud.backgroundColor = bgColor;
|
||||
hud.bezelView.color = [UIColor clearColor];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+ (void)showAnchorLoading {
|
||||
|
||||
UIView *view = [UIApplication sharedApplication].delegate.window;
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.userInteractionEnabled = NO;
|
||||
hud.mode = MBProgressHUDModeCustomView;
|
||||
hud.minSize = CGSizeMake(100, 150);
|
||||
[hud.bezelView addSubview:[self loadingView ]];
|
||||
hud.bezelView.color = [UIColor clearColor];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)showAnchorLoading:(UIView *)view {
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.userInteractionEnabled = NO;
|
||||
hud.mode = MBProgressHUDModeCustomView;
|
||||
hud.minSize = CGSizeMake(100, 150);
|
||||
[hud.bezelView addSubview:[self loadingView ]];
|
||||
hud.bezelView.color = [UIColor clearColor];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - private
|
||||
+ (MBProgressHUD *)normalProgressHUD:(UIView *)view {
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
return hud;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (UIView *)loadingView {
|
||||
UIView *bgView = [UIView new];
|
||||
bgView.backgroundColor = [UIColor clearColor];
|
||||
bgView.frame = CGRectMake(0, 0, 100, 150);
|
||||
|
||||
return bgView;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+(void)hideOnlyView:(UIView *)view{
|
||||
|
||||
dispatch_main_sync_safe(^{
|
||||
if (view) {
|
||||
UIView *getView;
|
||||
if([view isKindOfClass:[MvpViewController class]]){
|
||||
getView = ((MvpViewController *)view).view;
|
||||
}else{
|
||||
getView = view;
|
||||
}
|
||||
MBProgressHUD *hud = [XNDJTDDLoadingTool HUDForView:getView];
|
||||
if (hud != nil && hud.mode != MBProgressHUDModeText) {
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
[hud hideAnimated:NO];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
+(void)showOnlyView:(UIView *)view{
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
[self hideOnlyView:view];
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.minSize = CGSizeMake(100, 150);
|
||||
hud.userInteractionEnabled = NO;
|
||||
hud.mode = MBProgressHUDModeCustomView;
|
||||
[hud.bezelView addSubview:[self loadingView]];
|
||||
hud.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.35];
|
||||
hud.bezelView.color = [UIColor clearColor];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
});
|
||||
}
|
||||
+(void)showOnlyView:(UIView *)view enabled:(BOOL)enabled{
|
||||
if (!view) {
|
||||
view = [UIApplication sharedApplication].keyWindow;
|
||||
}
|
||||
[self hideOnlyView:view];
|
||||
dispatch_main_sync_safe(^{
|
||||
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
|
||||
hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||||
hud.minSize = CGSizeMake(100, 150);
|
||||
hud.userInteractionEnabled = enabled;
|
||||
hud.mode = MBProgressHUDModeCustomView;
|
||||
[hud.bezelView addSubview:[self loadingView]];
|
||||
hud.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.35];
|
||||
hud.bezelView.color = [UIColor clearColor];
|
||||
hud.removeFromSuperViewOnHide = YES;
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
@@ -1,27 +1,17 @@
|
||||
//
|
||||
// EPImageUploader.swift
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
/// 图片批量上传工具(纯 Swift 内部类,直接使用 QCloudCOSXML SDK)
|
||||
/// 不对外暴露,由 EPSDKManager 内部调用
|
||||
|
||||
class EPImageUploader {
|
||||
|
||||
init() {}
|
||||
|
||||
/// 批量上传图片(内部方法)
|
||||
/// - Parameters:
|
||||
/// - images: 要上传的图片数组
|
||||
/// - bucket: QCloud bucket 名称
|
||||
/// - customDomain: 自定义域名
|
||||
/// - progress: 进度回调 (已上传数, 总数)
|
||||
/// - success: 成功回调
|
||||
/// - failure: 失败回调
|
||||
|
||||
func performBatchUpload(
|
||||
_ images: [UIImage],
|
||||
bucket: String,
|
||||
@@ -32,7 +22,7 @@ class EPImageUploader {
|
||||
) {
|
||||
let total = images.count
|
||||
let queue = DispatchQueue(label: "com.yumi.imageupload", attributes: .concurrent)
|
||||
let semaphore = DispatchSemaphore(value: 3) // 最多同时上传 3 张
|
||||
let semaphore = DispatchSemaphore(value: 3)
|
||||
var uploadedCount = 0
|
||||
var resultList: [[String: Any]] = []
|
||||
var hasError = false
|
||||
@@ -42,7 +32,7 @@ class EPImageUploader {
|
||||
queue.async {
|
||||
semaphore.wait()
|
||||
|
||||
// 检查是否已经失败
|
||||
|
||||
lock.lock()
|
||||
if hasError {
|
||||
lock.unlock()
|
||||
@@ -51,7 +41,7 @@ class EPImageUploader {
|
||||
}
|
||||
lock.unlock()
|
||||
|
||||
// 压缩图片
|
||||
|
||||
guard let imageData = image.jpegData(compressionQuality: 0.5) else {
|
||||
lock.lock()
|
||||
hasError = true
|
||||
@@ -63,25 +53,25 @@ class EPImageUploader {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取图片格式
|
||||
|
||||
let format = UIImage.getImageType(withImageData: imageData) ?? "jpeg"
|
||||
|
||||
// 生成文件名
|
||||
|
||||
let uuid = NSString.createUUID()
|
||||
let fileName = "image/\(uuid).\(format)"
|
||||
|
||||
// 直接使用 QCloud SDK 上传
|
||||
|
||||
let request = QCloudCOSXMLUploadObjectRequest<AnyObject>()
|
||||
request.bucket = bucket
|
||||
request.object = fileName
|
||||
request.body = imageData as NSData
|
||||
|
||||
// 监听上传进度(可选)
|
||||
|
||||
request.sendProcessBlock = { bytesSent, totalBytesSent, totalBytesExpectedToSend in
|
||||
// 单个文件的上传进度(当前不使用)
|
||||
|
||||
}
|
||||
|
||||
// 监听上传结果
|
||||
|
||||
request.finishBlock = { [weak self] result, error in
|
||||
guard let self = self else {
|
||||
semaphore.signal()
|
||||
@@ -89,7 +79,7 @@ class EPImageUploader {
|
||||
}
|
||||
|
||||
if let error = error {
|
||||
// 上传失败
|
||||
|
||||
lock.lock()
|
||||
if !hasError {
|
||||
hasError = true
|
||||
@@ -103,12 +93,12 @@ class EPImageUploader {
|
||||
semaphore.signal()
|
||||
}
|
||||
} else if let result = result as? QCloudUploadObjectResult {
|
||||
// 上传成功
|
||||
|
||||
lock.lock()
|
||||
if !hasError {
|
||||
uploadedCount += 1
|
||||
|
||||
// 解析上传 URL(参考 UploadFile.m line 217-223)
|
||||
|
||||
let uploadedURL = self.parseUploadURL(result.location, customDomain: customDomain)
|
||||
|
||||
let imageInfo: [String: Any] = [
|
||||
@@ -122,12 +112,12 @@ class EPImageUploader {
|
||||
let currentUploaded = uploadedCount
|
||||
lock.unlock()
|
||||
|
||||
// 进度回调
|
||||
|
||||
DispatchQueue.main.async {
|
||||
progress(currentUploaded, total)
|
||||
}
|
||||
|
||||
// 全部完成
|
||||
|
||||
if currentUploaded == total {
|
||||
DispatchQueue.main.async {
|
||||
success(resultList)
|
||||
@@ -142,17 +132,13 @@ class EPImageUploader {
|
||||
}
|
||||
}
|
||||
|
||||
// 执行上传
|
||||
|
||||
QCloudCOSTransferMangerService.defaultCOSTransferManager().uploadObject(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 解析上传返回的 URL(参考 UploadFile.m line 217-223)
|
||||
/// - Parameters:
|
||||
/// - location: QCloud 返回的原始 URL
|
||||
/// - customDomain: 自定义域名
|
||||
/// - Returns: 解析后的 URL
|
||||
|
||||
private func parseUploadURL(_ location: String, customDomain: String) -> String {
|
||||
let components = location.components(separatedBy: ".com/")
|
||||
if components.count == 2 {
|
||||
|
163
YuMi/E-P/Common/EPImageUploader.swift.backup
Normal file
163
YuMi/E-P/Common/EPImageUploader.swift.backup
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// EPImageUploader.swift
|
||||
// YuMi
|
||||
//
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
/// 图片批量上传工具(纯 Swift 内部类,直接使用 QCloudCOSXML SDK)
|
||||
/// 不对外暴露,由 EPSDKManager 内部调用
|
||||
class EPImageUploader {
|
||||
|
||||
init() {}
|
||||
|
||||
/// 批量上传图片(内部方法)
|
||||
/// - Parameters:
|
||||
/// - images: 要上传的图片数组
|
||||
/// - bucket: QCloud bucket 名称
|
||||
/// - customDomain: 自定义域名
|
||||
/// - progress: 进度回调 (已上传数, 总数)
|
||||
/// - success: 成功回调
|
||||
/// - failure: 失败回调
|
||||
func performBatchUpload(
|
||||
_ images: [UIImage],
|
||||
bucket: String,
|
||||
customDomain: String,
|
||||
progress: @escaping (Int, Int) -> Void,
|
||||
success: @escaping ([[String: Any]]) -> Void,
|
||||
failure: @escaping (String) -> Void
|
||||
) {
|
||||
let total = images.count
|
||||
let queue = DispatchQueue(label: "com.yumi.imageupload", attributes: .concurrent)
|
||||
let semaphore = DispatchSemaphore(value: 3) // 最多同时上传 3 张
|
||||
var uploadedCount = 0
|
||||
var resultList: [[String: Any]] = []
|
||||
var hasError = false
|
||||
let lock = NSLock()
|
||||
|
||||
for (_, image) in images.enumerated() {
|
||||
queue.async {
|
||||
semaphore.wait()
|
||||
|
||||
// 检查是否已经失败
|
||||
lock.lock()
|
||||
if hasError {
|
||||
lock.unlock()
|
||||
semaphore.signal()
|
||||
return
|
||||
}
|
||||
lock.unlock()
|
||||
|
||||
// 压缩图片
|
||||
guard let imageData = image.jpegData(compressionQuality: 0.5) else {
|
||||
lock.lock()
|
||||
hasError = true
|
||||
lock.unlock()
|
||||
semaphore.signal()
|
||||
DispatchQueue.main.async {
|
||||
failure(YMLocalizedString("error.image_compress_failed"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 获取图片格式
|
||||
let format = UIImage.getImageType(withImageData: imageData) ?? "jpeg"
|
||||
|
||||
// 生成文件名
|
||||
let uuid = NSString.createUUID()
|
||||
let fileName = "image/\(uuid).\(format)"
|
||||
|
||||
// 直接使用 QCloud SDK 上传
|
||||
let request = QCloudCOSXMLUploadObjectRequest<AnyObject>()
|
||||
request.bucket = bucket
|
||||
request.object = fileName
|
||||
request.body = imageData as NSData
|
||||
|
||||
// 监听上传进度(可选)
|
||||
request.sendProcessBlock = { bytesSent, totalBytesSent, totalBytesExpectedToSend in
|
||||
// 单个文件的上传进度(当前不使用)
|
||||
}
|
||||
|
||||
// 监听上传结果
|
||||
request.finishBlock = { [weak self] result, error in
|
||||
guard let self = self else {
|
||||
semaphore.signal()
|
||||
return
|
||||
}
|
||||
|
||||
if let error = error {
|
||||
// 上传失败
|
||||
lock.lock()
|
||||
if !hasError {
|
||||
hasError = true
|
||||
lock.unlock()
|
||||
semaphore.signal()
|
||||
DispatchQueue.main.async {
|
||||
failure(error.localizedDescription)
|
||||
}
|
||||
} else {
|
||||
lock.unlock()
|
||||
semaphore.signal()
|
||||
}
|
||||
} else if let result = result as? QCloudUploadObjectResult {
|
||||
// 上传成功
|
||||
lock.lock()
|
||||
if !hasError {
|
||||
uploadedCount += 1
|
||||
|
||||
// 解析上传 URL(参考 UploadFile.m line 217-223)
|
||||
let uploadedURL = self.parseUploadURL(result.location, customDomain: customDomain)
|
||||
|
||||
let imageInfo: [String: Any] = [
|
||||
"resUrl": uploadedURL,
|
||||
"width": image.size.width,
|
||||
"height": image.size.height,
|
||||
"format": format
|
||||
]
|
||||
resultList.append(imageInfo)
|
||||
|
||||
let currentUploaded = uploadedCount
|
||||
lock.unlock()
|
||||
|
||||
// 进度回调
|
||||
DispatchQueue.main.async {
|
||||
progress(currentUploaded, total)
|
||||
}
|
||||
|
||||
// 全部完成
|
||||
if currentUploaded == total {
|
||||
DispatchQueue.main.async {
|
||||
success(resultList)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lock.unlock()
|
||||
}
|
||||
semaphore.signal()
|
||||
} else {
|
||||
semaphore.signal()
|
||||
}
|
||||
}
|
||||
|
||||
// 执行上传
|
||||
QCloudCOSTransferMangerService.defaultCOSTransferManager().uploadObject(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 解析上传返回的 URL(参考 UploadFile.m line 217-223)
|
||||
/// - Parameters:
|
||||
/// - location: QCloud 返回的原始 URL
|
||||
/// - customDomain: 自定义域名
|
||||
/// - Returns: 解析后的 URL
|
||||
private func parseUploadURL(_ location: String, customDomain: String) -> String {
|
||||
let components = location.components(separatedBy: ".com/")
|
||||
if components.count == 2 {
|
||||
return "\(customDomain)/\(components[1])"
|
||||
}
|
||||
return location
|
||||
}
|
||||
}
|
@@ -1,19 +1,17 @@
|
||||
//
|
||||
// EPProgressHUD.swift
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
/// 带进度的 Loading 组件(基于 MBProgressHUD)
|
||||
|
||||
@objc class EPProgressHUD: NSObject {
|
||||
|
||||
private static var currentHUD: MBProgressHUD?
|
||||
|
||||
/// 获取当前活跃的 window(兼容 iOS 13+)
|
||||
|
||||
private static var keyWindow: UIWindow? {
|
||||
if #available(iOS 13.0, *) {
|
||||
return UIApplication.shared.connectedScenes
|
||||
@@ -25,20 +23,17 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
/// 显示上传进度
|
||||
/// - Parameters:
|
||||
/// - uploaded: 已上传数量
|
||||
/// - total: 总数量
|
||||
|
||||
@objc static func showProgress(_ uploaded: Int, total: Int) {
|
||||
DispatchQueue.main.async {
|
||||
guard let window = keyWindow else { return }
|
||||
|
||||
if let hud = currentHUD {
|
||||
// 更新现有 HUD
|
||||
|
||||
hud.label.text = String(format: YMLocalizedString("upload.progress_format"), uploaded, total)
|
||||
hud.progress = Float(uploaded) / Float(total)
|
||||
} else {
|
||||
// 创建新 HUD
|
||||
|
||||
let hud = MBProgressHUD.showAdded(to: window, animated: true)
|
||||
hud.mode = .determinateHorizontalBar
|
||||
hud.label.text = String(format: YMLocalizedString("upload.progress_format"), uploaded, total)
|
||||
@@ -49,8 +44,7 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
/// 显示错误提示
|
||||
/// - Parameter message: 错误信息
|
||||
|
||||
@objc static func showError(_ message: String) {
|
||||
DispatchQueue.main.async {
|
||||
guard let window = keyWindow else { return }
|
||||
@@ -64,8 +58,7 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
/// 显示成功提示
|
||||
/// - Parameter message: 成功信息
|
||||
|
||||
@objc static func showSuccess(_ message: String) {
|
||||
DispatchQueue.main.async {
|
||||
guard let window = keyWindow else { return }
|
||||
@@ -79,7 +72,7 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
/// 关闭 HUD
|
||||
|
||||
@objc static func dismiss() {
|
||||
DispatchQueue.main.async {
|
||||
guard let hud = currentHUD else { return }
|
||||
|
92
YuMi/E-P/Common/EPProgressHUD.swift.backup
Normal file
92
YuMi/E-P/Common/EPProgressHUD.swift.backup
Normal file
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// EPProgressHUD.swift
|
||||
// YuMi
|
||||
//
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
/// 带进度的 Loading 组件(基于 MBProgressHUD)
|
||||
@objc class EPProgressHUD: NSObject {
|
||||
|
||||
private static var currentHUD: MBProgressHUD?
|
||||
|
||||
/// 获取当前活跃的 window(兼容 iOS 13+)
|
||||
private static var keyWindow: UIWindow? {
|
||||
if #available(iOS 13.0, *) {
|
||||
return UIApplication.shared.connectedScenes
|
||||
.compactMap { $0 as? UIWindowScene }
|
||||
.flatMap { $0.windows }
|
||||
.first { $0.isKeyWindow }
|
||||
} else {
|
||||
return UIApplication.shared.keyWindow
|
||||
}
|
||||
}
|
||||
|
||||
/// 显示上传进度
|
||||
/// - Parameters:
|
||||
/// - uploaded: 已上传数量
|
||||
/// - total: 总数量
|
||||
@objc static func showProgress(_ uploaded: Int, total: Int) {
|
||||
DispatchQueue.main.async {
|
||||
guard let window = keyWindow else { return }
|
||||
|
||||
if let hud = currentHUD {
|
||||
// 更新现有 HUD
|
||||
hud.label.text = String(format: YMLocalizedString("upload.progress_format"), uploaded, total)
|
||||
hud.progress = Float(uploaded) / Float(total)
|
||||
} else {
|
||||
// 创建新 HUD
|
||||
let hud = MBProgressHUD.showAdded(to: window, animated: true)
|
||||
hud.mode = .determinateHorizontalBar
|
||||
hud.label.text = String(format: YMLocalizedString("upload.progress_format"), uploaded, total)
|
||||
hud.progress = Float(uploaded) / Float(total)
|
||||
hud.removeFromSuperViewOnHide = true
|
||||
currentHUD = hud
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 显示错误提示
|
||||
/// - Parameter message: 错误信息
|
||||
@objc static func showError(_ message: String) {
|
||||
DispatchQueue.main.async {
|
||||
guard let window = keyWindow else { return }
|
||||
|
||||
let hud = MBProgressHUD.showAdded(to: window, animated: true)
|
||||
hud.mode = .text
|
||||
hud.label.text = message
|
||||
hud.label.numberOfLines = 0
|
||||
hud.removeFromSuperViewOnHide = true
|
||||
hud.hide(animated: true, afterDelay: 2.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 显示成功提示
|
||||
/// - Parameter message: 成功信息
|
||||
@objc static func showSuccess(_ message: String) {
|
||||
DispatchQueue.main.async {
|
||||
guard let window = keyWindow else { return }
|
||||
|
||||
let hud = MBProgressHUD.showAdded(to: window, animated: true)
|
||||
hud.mode = .text
|
||||
hud.label.text = message
|
||||
hud.label.numberOfLines = 0
|
||||
hud.removeFromSuperViewOnHide = true
|
||||
hud.hide(animated: true, afterDelay: 2.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 关闭 HUD
|
||||
@objc static func dismiss() {
|
||||
DispatchQueue.main.async {
|
||||
guard let hud = currentHUD else { return }
|
||||
|
||||
hud.hide(animated: true)
|
||||
currentHUD = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,11 @@
|
||||
//
|
||||
// EPQCloudConfig.swift
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
|
||||
import Foundation
|
||||
|
||||
/// QCloud 配置数据模型(对应 UploadFileModel)
|
||||
|
||||
struct EPQCloudConfig {
|
||||
let secretId: String
|
||||
let secretKey: String
|
||||
@@ -20,10 +18,9 @@ struct EPQCloudConfig {
|
||||
let appId: String
|
||||
let accelerate: Int
|
||||
|
||||
/// 从 API 返回的 dictionary 初始化
|
||||
/// API: GET tencent/cos/getToken
|
||||
|
||||
init?(dictionary: [String: Any]) {
|
||||
// 必填字段检查
|
||||
|
||||
guard let secretId = dictionary["secretId"] as? String,
|
||||
let secretKey = dictionary["secretKey"] as? String,
|
||||
let sessionToken = dictionary["sessionToken"] as? String,
|
||||
@@ -42,13 +39,13 @@ struct EPQCloudConfig {
|
||||
self.customDomain = customDomain
|
||||
self.appId = appId
|
||||
|
||||
// 可选字段使用默认值
|
||||
|
||||
self.startTime = (dictionary["startTime"] as? Int64) ?? 0
|
||||
self.expireTime = (dictionary["expireTime"] as? Int64) ?? 0
|
||||
self.accelerate = (dictionary["accelerate"] as? Int) ?? 0
|
||||
}
|
||||
|
||||
/// 检查配置是否过期
|
||||
|
||||
var isExpired: Bool {
|
||||
return Date().timeIntervalSince1970 > Double(expireTime)
|
||||
}
|
||||
|
56
YuMi/E-P/Common/EPQCloudConfig.swift.backup
Normal file
56
YuMi/E-P/Common/EPQCloudConfig.swift.backup
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// EPQCloudConfig.swift
|
||||
// YuMi
|
||||
//
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// QCloud 配置数据模型(对应 UploadFileModel)
|
||||
struct EPQCloudConfig {
|
||||
let secretId: String
|
||||
let secretKey: String
|
||||
let sessionToken: String
|
||||
let bucket: String
|
||||
let region: String
|
||||
let customDomain: String
|
||||
let startTime: Int64
|
||||
let expireTime: Int64
|
||||
let appId: String
|
||||
let accelerate: Int
|
||||
|
||||
/// 从 API 返回的 dictionary 初始化
|
||||
/// API: GET tencent/cos/getToken
|
||||
init?(dictionary: [String: Any]) {
|
||||
// 必填字段检查
|
||||
guard let secretId = dictionary["secretId"] as? String,
|
||||
let secretKey = dictionary["secretKey"] as? String,
|
||||
let sessionToken = dictionary["sessionToken"] as? String,
|
||||
let bucket = dictionary["bucket"] as? String,
|
||||
let region = dictionary["region"] as? String,
|
||||
let customDomain = dictionary["customDomain"] as? String,
|
||||
let appId = dictionary["appId"] as? String else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.secretId = secretId
|
||||
self.secretKey = secretKey
|
||||
self.sessionToken = sessionToken
|
||||
self.bucket = bucket
|
||||
self.region = region
|
||||
self.customDomain = customDomain
|
||||
self.appId = appId
|
||||
|
||||
// 可选字段使用默认值
|
||||
self.startTime = (dictionary["startTime"] as? Int64) ?? 0
|
||||
self.expireTime = (dictionary["expireTime"] as? Int64) ?? 0
|
||||
self.accelerate = (dictionary["accelerate"] as? Int) ?? 0
|
||||
}
|
||||
|
||||
/// 检查配置是否过期
|
||||
var isExpired: Bool {
|
||||
return Date().timeIntervalSince1970 > Double(expireTime)
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,11 @@
|
||||
//
|
||||
// EPSDKManager.swift
|
||||
// YuMi
|
||||
//
|
||||
|
||||
|
||||
// Created by AI on 2025-10-11.
|
||||
//
|
||||
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 第三方 SDK 统一管理器(单例)
|
||||
/// 统一入口:对外提供所有 SDK 能力
|
||||
/// 内部管理:QCloud 初始化、配置、上传等
|
||||
|
||||
@objc class EPSDKManager: NSObject, QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate {
|
||||
|
||||
// MARK: - Singleton
|
||||
@@ -18,22 +14,22 @@ import Foundation
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// QCloud 配置缓存
|
||||
|
||||
private var qcloudConfig: EPQCloudConfig?
|
||||
|
||||
// QCloud 初始化状态
|
||||
|
||||
private var isQCloudInitializing = false
|
||||
|
||||
// QCloud 初始化回调队列
|
||||
|
||||
private var qcloudInitCallbacks: [(Bool, String?) -> Void] = []
|
||||
|
||||
// QCloud 凭证队列
|
||||
|
||||
private var credentialFenceQueue: QCloudCredentailFenceQueue?
|
||||
|
||||
// 线程安全锁
|
||||
|
||||
private let lock = NSLock()
|
||||
|
||||
// 内部图片上传器
|
||||
|
||||
private let uploader = EPImageUploader()
|
||||
|
||||
// MARK: - Initialization
|
||||
@@ -44,12 +40,7 @@ import Foundation
|
||||
|
||||
// MARK: - Public API (对外统一入口)
|
||||
|
||||
/// 批量上传图片(统一入口)
|
||||
/// - Parameters:
|
||||
/// - images: 要上传的图片数组
|
||||
/// - progress: 进度回调 (已上传数, 总数)
|
||||
/// - success: 成功回调,返回图片信息数组
|
||||
/// - failure: 失败回调
|
||||
|
||||
@objc func uploadImages(
|
||||
_ images: [UIImage],
|
||||
progress: @escaping (Int, Int) -> Void,
|
||||
@@ -61,7 +52,7 @@ import Foundation
|
||||
return
|
||||
}
|
||||
|
||||
// 确保 QCloud 已就绪
|
||||
|
||||
ensureQCloudReady { [weak self] isReady, errorMsg in
|
||||
guard let self = self, isReady else {
|
||||
DispatchQueue.main.async {
|
||||
@@ -70,7 +61,7 @@ import Foundation
|
||||
return
|
||||
}
|
||||
|
||||
// 委托给内部 uploader 执行
|
||||
|
||||
self.uploader.performBatchUpload(
|
||||
images,
|
||||
bucket: self.qcloudConfig?.bucket ?? "",
|
||||
@@ -82,8 +73,7 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查 QCloud 是否已就绪
|
||||
/// - Returns: true 表示已初始化且未过期
|
||||
|
||||
@objc func isQCloudReady() -> Bool {
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
@@ -96,42 +86,41 @@ import Foundation
|
||||
|
||||
// MARK: - Internal Methods
|
||||
|
||||
/// 确保 QCloud 已就绪(自动初始化)
|
||||
|
||||
private func ensureQCloudReady(completion: @escaping (Bool, String?) -> Void) {
|
||||
if isQCloudReady() {
|
||||
completion(true, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// 未初始化或已过期,重新初始化
|
||||
|
||||
initializeQCloud(completion: completion)
|
||||
}
|
||||
|
||||
/// 初始化 QCloud(获取 Token 并配置 SDK)
|
||||
|
||||
private func initializeQCloud(completion: @escaping (Bool, String?) -> Void) {
|
||||
lock.lock()
|
||||
|
||||
// 如果正在初始化,加入回调队列
|
||||
|
||||
if isQCloudInitializing {
|
||||
qcloudInitCallbacks.append(completion)
|
||||
lock.unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// 如果已初始化且未过期,直接返回
|
||||
|
||||
if let config = qcloudConfig, !config.isExpired {
|
||||
lock.unlock()
|
||||
completion(true, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// 开始初始化
|
||||
|
||||
isQCloudInitializing = true
|
||||
qcloudInitCallbacks.append(completion)
|
||||
lock.unlock()
|
||||
|
||||
// 调用 API 获取 QCloud Token
|
||||
// API: GET tencent/cos/getToken
|
||||
|
||||
Api.getQCloudInfo { [weak self] (data, code, msg) in
|
||||
guard let self = self else { return }
|
||||
|
||||
@@ -141,24 +130,24 @@ import Foundation
|
||||
let dict = data?.data as? [String: Any],
|
||||
let config = EPQCloudConfig(dictionary: dict) {
|
||||
|
||||
// 保存配置
|
||||
|
||||
self.qcloudConfig = config
|
||||
|
||||
// 配置 QCloud SDK
|
||||
|
||||
self.configureQCloudSDK(with: config)
|
||||
|
||||
// 初始化完成
|
||||
|
||||
self.isQCloudInitializing = false
|
||||
let callbacks = self.qcloudInitCallbacks
|
||||
self.qcloudInitCallbacks.removeAll()
|
||||
self.lock.unlock()
|
||||
|
||||
// 短暂延迟确保 SDK 配置完成
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
||||
callbacks.forEach { $0(true, nil) }
|
||||
}
|
||||
} else {
|
||||
// 初始化失败
|
||||
|
||||
self.isQCloudInitializing = false
|
||||
let callbacks = self.qcloudInitCallbacks
|
||||
self.qcloudInitCallbacks.removeAll()
|
||||
@@ -172,7 +161,7 @@ import Foundation
|
||||
}
|
||||
}
|
||||
|
||||
/// 配置 QCloud SDK(参考 UploadFile.m line 42-64)
|
||||
|
||||
private func configureQCloudSDK(with config: EPQCloudConfig) {
|
||||
let configuration = QCloudServiceConfiguration()
|
||||
configuration.appID = config.appId
|
||||
@@ -181,7 +170,7 @@ import Foundation
|
||||
endpoint.regionName = config.region
|
||||
endpoint.useHTTPS = true
|
||||
|
||||
// 全球加速(参考 UploadFile.m line 56-59)
|
||||
|
||||
if config.accelerate == 1 {
|
||||
endpoint.suffix = "cos.accelerate.myqcloud.com"
|
||||
}
|
||||
@@ -189,18 +178,18 @@ import Foundation
|
||||
configuration.endpoint = endpoint
|
||||
configuration.signatureProvider = self
|
||||
|
||||
// 注册 COS 服务
|
||||
|
||||
QCloudCOSXMLService.registerDefaultCOSXML(with: configuration)
|
||||
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(with: configuration)
|
||||
|
||||
// 初始化凭证队列
|
||||
|
||||
credentialFenceQueue = QCloudCredentailFenceQueue()
|
||||
credentialFenceQueue?.delegate = self
|
||||
}
|
||||
|
||||
// MARK: - QCloudSignatureProvider Protocol
|
||||
|
||||
/// 提供签名(参考 UploadFile.m line 67-104)
|
||||
|
||||
func signature(
|
||||
with fields: QCloudSignatureFields,
|
||||
request: QCloudBizHTTPRequest,
|
||||
@@ -228,7 +217,7 @@ import Foundation
|
||||
|
||||
// MARK: - QCloudCredentailFenceQueueDelegate Protocol
|
||||
|
||||
/// 管理凭证(参考 UploadFile.m line 107-133)
|
||||
|
||||
func fenceQueue(
|
||||
_ queue: QCloudCredentailFenceQueue,
|
||||
requestCreatorWithContinue continueBlock: @escaping QCloudCredentailFenceQueueContinue
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user