iOS 13 如期而至,雖然正式版還沒出來,可是適配工做能夠開展起來啦。在適配 iOS 13 過程當中,遇到了以下一些問題。ios
1. UITextField 的私有屬性 _placeholderLabel 被禁止訪問了
遇到的第一個崩潰是修改UITextField
的placeholder
的顏色,歷史遺留代碼以下:app
[_textField setValue:self.placeholderColor forKeyPath:@"_placeholderLabel.textColor"];
收到的錯誤信息⚠️學習
'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug'
那麼這個問題如何處理呢?flex
其實,UITextField
有個attributedPlaceholder
的屬性,咱們能夠自定義這個富文原本達到咱們須要的結果。ui
修改以下:this
NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : self.placeholderColor}]; _textField.attributedPlaceholder = placeholderString;
注意⚠️,iOS 13 經過 KVC 方式修改私有屬性,有 Crush 風險,謹慎使用!code
2. 控制器的 modalPresentationStyle 默認值變了
對於這個變化,有點措手不及,直接修改了模態窗口的交互。 查閱了下 UIModalPresentationStyle
枚舉定義,赫然發現iOS 13
新加了一個枚舉值:orm
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) { UIModalPresentationFullScreen = 0, UIModalPresentationPageSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos), UIModalPresentationFormSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos), UIModalPresentationCurrentContext API_AVAILABLE(ios(3.2)), UIModalPresentationCustom API_AVAILABLE(ios(7.0)), UIModalPresentationOverFullScreen API_AVAILABLE(ios(8.0)), UIModalPresentationOverCurrentContext API_AVAILABLE(ios(8.0)), UIModalPresentationPopover API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(tvos), UIModalPresentationBlurOverFullScreen API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios) API_UNAVAILABLE(watchos), UIModalPresentationNone API_AVAILABLE(ios(7.0)) = -1, UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2, };
是的,就是UIModalPresentationAutomatic
,蘋果竟然直接將modalPresentationStyle
默認值改爲這個,有點不解,難道是怕咱們不知道新加了這個交互?這個也徹底違反了開閉原則吧😒。token
如何修改: 若是你徹底接受蘋果的這個默認效果,那就不須要去修改任何代碼。 若是,你原來就比較細心,已經設置了modalPresentationStyle
的值,那你也不會有這個影響。 對於想要找回原來默認交互的同窗,直接設置以下便可:ip
self.modalPresentationStyle = UIModalPresentationOverFullScreen;
注意:UIModalPresentationOverFullScreen
最低支持iOS 8
,若是你還要支持iOS 8
如下版本,那麼你能夠用UIModalPresentationFullScreen
,這個兩個值的交互略有些細微差異,具體的能夠本身看下效果。
3. MPMoviePlayerController 在iOS 13已經不能用了
在使用到MPMoviePlayerController
的地方,直接拋了異常:
'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
如何修改: 這個沒啥好說的,既然不能再用了,那隻能換掉了。替代方案就是AVKit
裏面的那套播放器。
4. iOS 13 DeviceToken有變化‼️
這個很重要⚠️ 可能大多數使用第三方推送的童鞋都不會注意到這個問題,通常如今的第三方推送都是將DeviceToken
原始數據丟進去,具體的解析都是第三方內部處理,因此,這些第三方解析DeviceToken
的方式正確的話,那就毫無問題。若是大家是經過這種方式來獲取DeviceToken
,那你須要注意了。(這個坑也是多年前埋下的,不少文章介紹的也是下面這個方法,不規範的作法早晚要還的🤣),以下:
NSString *dt = [deviceToken description]; dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""]; dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""]; dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];
這段代碼運行在 iOS 13 上已經沒法獲取到準確的DeviceToken
字符串了,iOS 13 經過[deviceToken description]
獲取到的內容已經變了。
{length = 32, bytes = 0x778a7995 29f32fb6 74ba8167 b6bddb4e ... b4d6b95f 65ac4587 }
能夠看到,跟原來咱們認識的那個已經徹底不同了。其實,形成這樣的問題,主要仍是沒有使用正確的方式來操做,下面是解決辦法:
NSMutableString *deviceTokenString = [NSMutableString string]; const char *bytes = deviceToken.bytes; NSInteger count = deviceToken.length; for (int i = 0; i < count; i++) { [deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF]; }
或者你也可使用極光提供的方法(2019年7月24日更新)
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { if (![deviceToken isKindOfClass:[NSData class]]) return; const unsigned *tokenBytes = [deviceToken bytes]; NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x", ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]), ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]), ntohl(tokenBytes[6]), ntohl(tokenBytes[7])]; NSLog(@"deviceToken:%@",hexToken); }
5.Sign in with Apple (提供第三方登陸的注意啦⚠️)
若是你的應用使用了第三方登陸,那麼你可能也須要加下 「Sign in with Apple」🤪
Sign In with Apple will be available for beta testing this summer. It will be required as an option for users in apps that support third-party sign-in when it is commercially available later this year.
怎麼作呢?網上已經有不少demo了,此處就不展開啦。 附上官方Demo:點我下載
6.即將廢棄的 LaunchImage
從 iOS 8 的時候,蘋果就引入了 LaunchScreen
,咱們能夠設置 LaunchScreen
來做爲啓動頁。固然,如今你還可使用LaunchImage
來設置啓動圖。不過使用LaunchImage
的話,要求咱們必須提供各類屏幕尺寸的啓動圖,來適配各類設備,隨着蘋果設備尺寸愈來愈多,這種方式顯然不夠 Flexible
。而使用 LaunchScreen
的話,狀況會變的很簡單, LaunchScreen
是支持AutoLayout
+SizeClass
的,因此適配各類屏幕都不在話下。 注意啦⚠️,從2020年4月開始,全部使⽤ iOS13 SDK
的 App
將必須提供 LaunchScreen
,LaunchImage
即將退出歷史舞臺。
7. Dark Mode
Apps on iOS 13 are expected to support dark mode Use system colors and materials Create your own dynamic colors and images Leverage flexible infrastructure
收錄:原文地址
對於iOS 13 適配,有問題,想要更好的探討,能夠進入iOS技術羣,一塊兒探討學習