本文对应github地址iOS 13 问题解决以及苹果登录,如果由于github调整导致资源找不到或细节更改,请访问github
本文直接搬砖,随便看看就行
iOS 13 (Xcode11编译时)问题解决以及苹果登录
-
KVC修改私有属性可能Crash(不是所有,不是所有,不是所有),需要用别的姿势替代。
如
[textField setValue:color forKeyPath:@"_placeholderLabel.textColor"];
会crash。那么该怎么办呢?下面提供几种姿势
姿势一:采用富文本形式
_textField.attributedPlaceholder = [[NSMutableAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : color}];
姿势二:new方式创建一个新label(太low不建议用)
// 必须new创建,如果alloc-init创建还是crash(两种方式差别自行google,不是BD) UILabel * placeholderLabel = [UILabel new]; placeholderLabel.text = @"666"; placeholderLabel.textColor = [UIColor blueColor]; [_textField setValue: placeholderLabel forKey:@"_placeholderLabel"];//new创建这里并没有crash
姿势三:Runtime
Ivar ivar = class_getInstanceVariable([UITextField class], "_placeholderLabel"); UILabel *placeholderLabel = object_getIvar(_textField, ivar); placeholderLabel.textColor = color;
- (UITextField *)ddy_SearchField { #ifdef __IPHONE_13_0 if (@available(iOS 13.0, *)) { return self.searchTextField; } #endif return [self valueForKey:@"_searchField"]; }
所以修改UISearchBar占位字符可以把上面的结合使用
-
模态弹出时 modalPresentationStyle 改变了默认值
- 在iOS13之前的版本中, UIViewController的UIModalPresentationStyle属性默认是UIModalPresentationFullScreen,而在iOS13中变成了UIModalPresentationPageSheet。
- 我们需要在presentViewController时,设置一下UIModalPresentationStyle,就可以达到旧的效果。
- 如果PageSheet想控制下拉dismiss,modalInPresentation可以控制
UIViewController+DDYPresent.h下载该文件
/// 一个一个改浪费时间,适合版本迭代中逐步替换; /// 直接重写-modalPresentationStyle 侵入性太大,造成系统弹出也被重置,或者某个控制器想改变样式都不能,不太友好 /// 所以用一个类方法控制全局,一个实例方法控制具体某个控制器实例样式。 #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface UIViewController (DDYPresent) /// 自动调整模态弹出样式时要排除的控制器(如果未设置则使用内置) /// @param controllerNameArray 模态弹出的控制器名称数组 + (void)ddy_ExcludeControllerNameArray:(NSArray<NSString *> *)controllerNameArray; /// 是否自动调整模态弹出全屏样式 /// NO:表示不自动调整,保持默认,可能全屏样式也可能其他样式 /// YES:表示调整为全屏样式 /// 如果是排除的控制器数组包含的控制器则默认NO /// 如果不在排除的控制器数组内包含则默认YES @property (nonatomic, assign) BOOL ddy_AutoSetModalPresentationStyleFullScreen; @end NS_ASSUME_NONNULL_END
UIViewController+DDYPresent.m下载该文件
#import "UIViewController+DDYPresent.h" #import <objc/runtime.h> @implementation UIViewController (DDYPresent) static NSArray *excludeControllerNameArray; + (void)changeOriginalSEL:(SEL)orignalSEL swizzledSEL:(SEL)swizzledSEL { Method originalMethod = class_getInstanceMethod([self class], orignalSEL); Method swizzledMethod = class_getInstanceMethod([self class], swizzledSEL); if (class_addMethod([self class], orignalSEL, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { class_replaceMethod([self class], swizzledSEL, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } } + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ SEL originalSEL = @selector(presentViewController:animated:completion:); SEL swizzledSEL = @selector(ddy_PresentViewController:animated:completion:); [self changeOriginalSEL:originalSEL swizzledSEL:swizzledSEL]; }); } - (void)ddy_PresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { if (@available(iOS 13.0, *)) { if (viewControllerToPresent.ddy_AutoSetModalPresentationStyleFullScreen) { viewControllerToPresent.modalPresentationStyle = UIModalPresentationFullScreen; } } [self ddy_PresentViewController:viewControllerToPresent animated:flag completion:completion]; } - (void)setDdy_AutoSetModalPresentationStyleFullScreen:(BOOL)ddy_AutoSetModalPresentationStyleFullScreen { objc_setAssociatedObject(self, @selector(ddy_AutoSetModalPresentationStyleFullScreen), @(ddy_AutoSetModalPresentationStyleFullScreen), OBJC_ASSOCIATION_ASSIGN); } - (BOOL)ddy_AutoSetModalPresentationStyleFullScreen { NSNumber *obj = objc_getAssociatedObject(self, @selector(ddy_AutoSetModalPresentationStyleFullScreen)); return obj ? [obj boolValue] : ![UIViewController ddy_IsExcludeSetModalPresentationStyleFullScreen:NSStringFromClass(self.class)]; } // MARK: - 类方法 // MARK: 全局设置排除的控制器 + (void)ddy_ExcludeControllerNameArray:(NSArray<NSString *> *)controllerNameArray { excludeControllerNameArray = controllerNameArray; } // MARK: 如果没有外部设置则使用内置的排除数组 + (NSArray<NSString *> *)ddy_InnerExcludeControllerNameArray { NSMutableArray *nameArray = [NSMutableArray array]; [nameArray addObject:@"UIImagePickerController"]; [nameArray addObject:@"UIAlertController"]; [nameArray addObject:@"UIActivityViewController"]; [nameArray addObject:@"UIDocumentInteractionController"]; [nameArray addObject:@"SLComposeViewController"]; // #import <Social/Social.h> [nameArray addObject:@"SLComposeServiceViewController"]; // #import <Social/Social.h> [nameArray addObject:@"UIMenuController"]; [nameArray addObject:@"SFSafariViewController"]; // API_AVAILABLE(ios(9.0)) #import <SafariServices/SafariServices.h> [nameArray addObject:@"SKStoreReviewController"]; // API_AVAILABLE(ios(10.3), macos(10.14)) #import <StoreKit/StoreKit.h> [nameArray addObject:@"SKStoreProductViewController"]; // API_AVAILABLE(ios(6.0)) #import <StoreKit/StoreKit.h> return nameArray; } // MARK: 是否是要排除自动设置的控制器 + (BOOL)ddy_IsExcludeSetModalPresentationStyleFullScreen:(NSString *)className { NSArray *nameArray = excludeControllerNameArray ?: [UIViewCont