iOS13正式版推送時間為2019年9月19日(北京時間2019年9月20日),與此同時發(fā)售iPhone 11劲妙,那我們就來說說iOS13的一些新特性吧
一胸遇、暗黑模式(官方叫做:深色模式)
iOS13最大的改變就是加入了暗黑模式(Dark Mode),蘋果要求開發(fā)者跟進(jìn)暗黑模式的開發(fā)!2020年蘋果可能要求開發(fā)者必須是配Dark Mode否則不予上架(可能纷捞、可能、可能)
對比了解一下暗黑模式:
Dark Mode.png
Dark Mode適配.png
暗黑模式 Dark Mode 適配(沒有適配暗黑模式之前被去,先禁用主儡,Info.plist文件中UIUserInterfaceStyle設(shè)置為light)
1.UIColor
UIColor在iOS13系統(tǒng)上擁有了動態(tài)屬性,iOS13之前UIColor只能表示一種顏色惨缆,iOS13以后能夠表示兩種模式下的不同顏色(例如:普通模式Light-白底黑字糜值,暗黑模式Dark-黑底白字)
iOS13系統(tǒng)提供了一些動態(tài)顏色,也可以自定義動態(tài)顏色踪央,下面我們一起看看使用事例臀玄,圖片為效果圖:
a.系統(tǒng)提供的動態(tài)顏色UIColor
[self.view setBackgroundColor:[UIColor systemBackgroundColor]]; // 13系統(tǒng)顏色方法,還有更多
[self.titleLabel setTextColor:[UIColor labelColor]]; // 13系統(tǒng)顏色方法
[self.detailLabel setTextColor:[UIColor placeholderTextColor]]; // 13系統(tǒng)顏色方法
b.自定義動態(tài)顏色UIColor
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
備注:這兩個發(fā)發(fā)要求傳入一個block進(jìn)去畅蹂,當(dāng)系統(tǒng)切換LightMode和DarkMode時會觸發(fā)此回調(diào)健无,并且這個Block會返回一個UITraitCollection類,我們需要使用其屬性userInterfaceStyle來判斷是LightMode還是DarkMode
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
return [UIColor redColor];
}
else {
return [UIColor greenColor];
}
}];
[self.bgView setBackgroundColor:dyColor];
c.iOS13中的CGColor
依然只能表示單一的顏色液斜,但可以利用下面這個方法來判斷的:
獲取當(dāng)前模式(Light or Dark):UITraitCollection.currentTraitCollection.userInterfaceStyle
還有就是對于CALayer等對象如何適配暗黑模式呢累贤?
方法一:resolvedColor
通過當(dāng)前traitCollection得到對應(yīng)UIColor(比如控制器重寫堅(jiān)挺暗黑模式改變方法)叠穆,然后將UIColor轉(zhuǎn)換為CGColor
- (UIColor *)resolvedColorWithTraitCollection:(UITraitCollection *)traitCollection;
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
return [UIColor redColor];
}
else {
return [UIColor greenColor];
}
}];
UIColor *resolvedColor = [dyColor resolvedColorWithTraitCollection:previousTraitCollection];
layer.backgroundColor = resolvedColor.CGColor;
}
方法二:performAsCurrent
使用當(dāng)前trainCollection調(diào)用這個方法- (void)performAsCurrentTraitCollection:(void (^)(void))actions;
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
return [UIColor redColor];
}
else {
return [UIColor greenColor];
}
}];
[self.traitCollection performAsCurrentTraitCollection:^{
layer.backgroundColor = dyColor.CGColor;
}];
}
方法三:最簡單的方法
直接設(shè)置為一個動態(tài)UIColor的CGColor即可
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
UIColor *dyColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) {
if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) {
return [UIColor redColor];
}
else {
return [UIColor greenColor];
}
}];
layer.backgroundColor = dyColor.CGColor;
}
注意:設(shè)置layer顏色都是在traitCollectionDidChange中,意味著如果沒有發(fā)生模式切換臼膏,layer將會沒有顏色硼被,需要設(shè)置一個基本顏色
d.控制器監(jiān)聽暗黑模式:(有時需求會用到,所以在ViewController中重寫下面的方法就好了)
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection; // 注意:參數(shù)為變化前的traitCollection
- (BOOL)hasDifferentColorAppearanceComparedToTraitCollection:(UITraitCollection *)traitCollection; // 判斷兩個UITraitCollection對象是否不同
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
// trait發(fā)生了改變
if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
// 執(zhí)行操作
}
}
e.模式切換時打印log
很方便的一種設(shè)置方式渗磅,操作步驟:
Xcode菜單欄-Product-Scheme-Edit Scheme - Run - Arguments Passed On Launch - 添加命令-UITraitCollectionChangeLoggingEnabled YES

f.強(qiáng)行設(shè)置APP模式
控制器頁面直接設(shè)置 設(shè)置為Dark Mode即可嚷硫,在View或者ViewController中可以設(shè)置,需要注意的是始鱼,當(dāng)我們強(qiáng)行設(shè)置之后仔掸,這個ViewController下的View都是設(shè)置的模式,由這個控制器模態(tài)推出的控制器依然跟隨系統(tǒng)模式医清,如果想一鍵設(shè)置APP下所有的ViewController都是Dark Mode起暮,直接window執(zhí)行overrideUserInterfaceStyle,window.rootViewController強(qiáng)行設(shè)置Dark Mode后模態(tài)推出的控制器依然跟隨系統(tǒng)模式
[self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark];
g.NSAttributedString暗黑模式優(yōu)化
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor labelColor]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案" attributes:dic];// 添加一個NSForegroundColorAttributeName屬性
2.圖片-暗黑模式(在iOS13暗黑模式下自由切換圖片)
開發(fā)時需要放入兩套2x3x圖了---Any Apperarance会烙、Dark Apperarance
詳細(xì)步驟:a.打開Assets.xcassets
b.新建一個Image Set
c.打開右側(cè)工具欄负懦,點(diǎn)擊最后一欄,找到Appearances柏腻,選擇Any,Dark
d.將兩種模式下的圖片拖放進(jìn)去就可以了
以上就是顏色和圖片的Dark Mode適配
效果圖1.png
二纸厉、Status Bar狀態(tài)欄更新
1.iOS13對Status Bar API做了修改
之前有兩種狀態(tài)(UIStatusBarStyleDefault文字黑色、UIStatusBarStyleLightContent文字白色)
iOS13以后有三種狀態(tài)(多出來的一種狀態(tài):UIStatusBarStyleDefault自動選擇黑色或者白色)
三葫盼、UIActivityIndicatorView加載視圖
1.iOS13對UIActivityIndicatorView樣式做了修改
之前有三種樣式:UIActivityIndicatorViewStyleGray灰色残腌、UIActivityIndicatorViewStyleWhite白色、UIActivityIndicatorViewStyleWhiteLarge白色大型
iOS13廢棄了以上三種樣式(用UIActivityIndicatorViewStyleLarge大型贫导、UIActivityIndicatorViewStyleMedium中型替代),通過Color屬性設(shè)置其顏色
五蟆盹、其他
1.iOS將通過LaunchScreen來取代設(shè)置啟動圖
2.iOS MPMoviePlayerController將不能使用
3.控制器的ModalPresentationStyle默認(rèn)值變了孩灯,變?yōu)閁IModalPresentationFullScreen,解決方案就是self.modalPresentationStyle = UIModalPresentationOverFullScreen
4.iOS13禁止使用valueForKey逾滥,setVaule:ForKey的方式獲取和設(shè)置私有屬性峰档,會引起Crash,解決方法就是使用其他方法替換
5.TabBar上設(shè)置的紅點(diǎn)會偏移到左上方寨昙,遍歷UITabBarButton的subViews發(fā)現(xiàn)只有在TabBar選中狀態(tài)下才能取到UITabBarSwappableImageView讥巡,解決方法:在選中狀態(tài)下對tabbar 設(shè)置 [tabBar layoutIfNeeded];
6.UISearchController上的SearchBar顯示異常,高度變?yōu)橹挥?px。解決方法:解決辦法是使用KVO監(jiān)聽frame值變化后設(shè)置去應(yīng)該顯示的高度舔哪。
參考文章:
iOS13 新特性簡介
iOS13 暗黑模式(Dark Mode)適配之OC版
整理總結(jié)iOS 13適配遇到的問題