Mac OS
系統發佈了深色模式外觀, 看着挺刺激, 時至今日用着也還挺爽的iPhone11
等新手機的發售, iOS 13
系統也正式發佈了, 伴隨着手機版的深色模式也出如今了大衆視野iOS
程序猿也有事情作了, 原有項目適配iOS13
系統, 適配Dark Mode
深色模式Dark Mode
, 可是DarK
適配卻也迫在眉睫Apps on iOS 13 are expected to support dark mode Use system colors and materials Create your own dynamic colors and images Leverage flexible infrastructurehtml
提供兩種方式設置手機當前外觀模式ios
咱們須要選獲取到當前出於什麼模式, 在根據不一樣的模式進行適配, iOS 13
中新增了獲取當前模式的API
swift
Swiftapi
// 獲取當前模式
let currentMode = UITraitCollection.current.userInterfaceStyle
if (currentMode == .dark) {
print("深色模式")
} else if (currentMode == .light) {
print("淺色模式")
} else {
print("未知模式")
}
open var userInterfaceStyle: UIUserInterfaceStyle { get }
// 全部模式
public enum UIUserInterfaceStyle : Int {
// 未指明的
case unspecified
// 淺色模式
case light
// 深色模式
case dark
}
複製代碼
OC語言bash
if (@available(iOS 13.0, *)) {
UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle;
if (mode == UIUserInterfaceStyleDark) {
NSLog(@"深色模式");
} else if (mode == UIUserInterfaceStyleLight) {
NSLog(@"淺色模式");
} else {
NSLog(@"未知模式");
}
}
// 各類枚舉值
typedef NS_ENUM(NSInteger, UIUserInterfaceStyle) {
UIUserInterfaceStyleUnspecified,
UIUserInterfaceStyleLight,
UIUserInterfaceStyleDark,
} API_AVAILABLE(tvos(10.0)) API_AVAILABLE(ios(12.0)) API_UNAVAILABLE(watchos);
複製代碼
在iOS13
系統中, UIViewController
遵循了兩個協議: UITraitEnvironment
和UIContentContainer
協議微信
在UITraitEnvironment
協議中, 爲咱們提供了一個監聽當前模式變化的方法閉包
@protocol UITraitEnvironment <NSObject>
// 當前模式
@property (nonatomic, readonly) UITraitCollection *traitCollection API_AVAILABLE(ios(8.0));
// 重寫該方法監聽模式的改變
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection API_AVAILABLE(ios(8.0));
@end
複製代碼
public protocol UITraitEnvironment : NSObjectProtocol {
// 當前模式
@available(iOS 8.0, *)
var traitCollection: UITraitCollection { get }
// 重寫該方法監聽模式的改變
@available(iOS 8.0, *)
func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
}
// 使用方法
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
// 每次模式改變的時候, 這裏都會執行
print("模式改變了")
}
複製代碼
iOS13
以前UIColor
只能表示一種顏色,從iOS13
開始UIColor
是一個動態的顏色,在不一樣模式下能夠分別表明不一樣的顏色iOS13
系統提供的動態顏色種類, 使用如下顏色值, 在模式切換時, 則不須要作特殊處理@interface UIColor (UIColorSystemColors)
#pragma mark System colors
@property (class, nonatomic, readonly) UIColor *systemRedColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemGreenColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemBlueColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemOrangeColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemYellowColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemPinkColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemPurpleColor API_AVAILABLE(ios(9.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemTealColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemIndigoColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
// 灰色種類, 在Light模式下, systemGray6Color更趨向於白色
@property (class, nonatomic, readonly) UIColor *systemGrayColor API_AVAILABLE(ios(7.0), tvos(9.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *systemGray2Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray3Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray4Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray5Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray6Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
#pragma mark Foreground colors
@property (class, nonatomic, readonly) UIColor *labelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *secondaryLabelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *tertiaryLabelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *quaternaryLabelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
// 系統連接的前景色
@property (class, nonatomic, readonly) UIColor *linkColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
// 佔位文字的顏色
@property (class, nonatomic, readonly) UIColor *placeholderTextColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
// 邊框或者分割線的顏色
@property (class, nonatomic, readonly) UIColor *separatorColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *opaqueSeparatorColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
#pragma mark Background colors
@property (class, nonatomic, readonly) UIColor *systemBackgroundColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *secondarySystemBackgroundColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *tertiarySystemBackgroundColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGroupedBackgroundColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *secondarySystemGroupedBackgroundColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *tertiarySystemGroupedBackgroundColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
#pragma mark Fill colors
@property (class, nonatomic, readonly) UIColor *systemFillColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *secondarySystemFillColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *tertiarySystemFillColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *quaternarySystemFillColor API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
#pragma mark Other colors
// 這兩個是非動態顏色值
@property(class, nonatomic, readonly) UIColor *lightTextColor API_UNAVAILABLE(tvos); // for a dark background
@property(class, nonatomic, readonly) UIColor *darkTextColor API_UNAVAILABLE(tvos); // for a light background
@property(class, nonatomic, readonly) UIColor *groupTableViewBackgroundColor API_DEPRECATED_WITH_REPLACEMENT("systemGroupedBackgroundColor", ios(2.0, 13.0), tvos(13.0, 13.0));
@property(class, nonatomic, readonly) UIColor *viewFlipsideBackgroundColor API_DEPRECATED("", ios(2.0, 7.0)) API_UNAVAILABLE(tvos);
@property(class, nonatomic, readonly) UIColor *scrollViewTexturedBackgroundColor API_DEPRECATED("", ios(3.2, 7.0)) API_UNAVAILABLE(tvos);
@property(class, nonatomic, readonly) UIColor *underPageBackgroundColor API_DEPRECATED("", ios(5.0, 7.0)) API_UNAVAILABLE(tvos);
@end
複製代碼
@available(iOS 13.0, *)
public init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)
複製代碼
在OC中app
+ (UIColor *)colorWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
- (UIColor *)initWithDynamicProvider:(UIColor * (^)(UITraitCollection *traitCollection))dynamicProvider API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
複製代碼
block
)LightMode
和DarkMode
之間相互切換時就會自動觸發此回調UITraitCollection
, 可根據改對象判斷是那種模式fileprivate func getColor() -> UIColor {
return UIColor { (collection) -> UIColor in
if (collection.userInterfaceStyle == .dark) {
return UIColor.red
}
return UIColor.green
}
}
複製代碼
除了上述兩個方法以外, UIColor
還增長了一個實例方法ide
// 經過當前traitCollection獲得對應UIColor
@available(iOS 13.0, *)
open func resolvedColor(with traitCollection: UITraitCollection) -> UIColor
複製代碼
UIColor
只是設置背景色和文字顏色的類, 能夠動態的設置CGColor
類, 可是在iOS13
中CGColor
並非動態顏色值, 只能表示一種顏色traitCollectionDidChange
, 根據不一樣的模式進行處理override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
// 每次模式改變的時候, 這裏都會執行
if (previousTraitCollection?.userInterfaceStyle == .dark) {
redView.layer.borderColor = UIColor.red.cgColor
} else {
redView.layer.borderColor = UIColor.green.cgColor
}
}
複製代碼
iOS
中, 圖片基本都是放在Assets.xcassets
裏面, 因此圖片的適配, 咱們就相對麻煩一些了Appearances
時, 咱們選擇Any, Dark
就能夠了(只須要適配深色模式和非深色模式)Dark Mode
, 當你切換到Dark Mode
後, 你可能會發現, 有些部分頁面的顏色自動適配了Dark Mode
模式下, 就是黑色的App
強制設置成Light Mode
模式// 設置改屬性, 只會影響當前的視圖, 不會影響前面的controller和後續present的controller
@available(iOS 13.0, *)
open var overrideUserInterfaceStyle: UIUserInterfaceStyle
// 使用示例
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
// 每次模式改變的時候, 這裏都會執行
if (previousTraitCollection?.userInterfaceStyle == .dark) {
// 在Dark模式下, 強制改爲Light模式
overrideUserInterfaceStyle = .light
}
}
複製代碼
Dark
模式window
的overrideUserInterfaceStyle
屬性Xcode11
建立的項目中, window
從AppDelegate
移到SceneDelegate
中, 添加下面這段代碼, 就會作到全局修改顯示模式let scene = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate
scene?.window?.overrideUserInterfaceStyle = .light
複製代碼
在以前的項目中, 能夠在AppDelegate
設置以下代碼字體
window.overrideUserInterfaceStyle = .light
複製代碼
我建立的簡單項目, 上述代碼的確會強制改變當前的模式, 可是狀態欄的顯示不會被修改, 不知道是否是漏了什麼
info.plist
文件中添加User Interface Style
配置, 並設置爲Light
<key>UIUserInterfaceStyle</key>
<string>Light</string>
複製代碼
問題又來了, 即便作了上面的修改, 在React Native
中, 狀態欄的依然是根據不一樣的模式顯示不一樣的顏色, 該如何處理嘞?
在iOS13
中蘋果對於Status Bar
也作了部分修改, 在iOS13
以前
public enum UIStatusBarStyle : Int {
case `default` // 默認文字黑色
@available(iOS 7.0, *)
case lightContent // 文字白色
}
複製代碼
從iOS13
開始UIStatusBarStyle
一共有三種狀態
public enum UIStatusBarStyle : Int {
case `default` // 自動選擇黑色或白色
@available(iOS 7.0, *)
case lightContent // 文字白色
@available(iOS 13.0, *)
case darkContent // 文字黑色
}
複製代碼
在React Native
的代碼中, 設置狀態欄的顏色爲黑色, 代碼以下
<StatusBar barStyle={'dark-content'} />
複製代碼
iOS13
系統的手機中是無效的dark-content
模式, 可是在iOS
原生代碼中dark-content
實際是UIStatusBarStyleDefault
RCTStatusBarManager.m
中RCT_ENUM_CONVERTER(UIStatusBarStyle, (@{
@"default": @(UIStatusBarStyleDefault),
@"light-content": @(UIStatusBarStyleLightContent),
@"dark-content": @(UIStatusBarStyleDefault),
}), UIStatusBarStyleDefault, integerValue);
複製代碼
修改上面代碼便可
@"dark-content": @(@available(iOS 13.0, *) ? UIStatusBarStyleDarkContent : UIStatusBarStyleDefault),
複製代碼
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.
APP
支持三方登錄(Facbook
、Google
、微信、QQ
、支付寶等),就必須支持蘋果登錄,且要放前邊Apple
登陸按鈕的樣式, 建議支持使用Apple
提供的按鈕樣式,已經適配各種設備, 可參考Sign In with Apple即將被廢棄的
LaunchImage
iOS 8
的時候,蘋果就引入了LaunchScreen
,咱們能夠設置LaunchScreen
來做爲啓動頁。LaunchImage
來設置啓動圖, 可是隨着蘋果設備尺寸愈來愈多, 適配顯然相對麻煩一些LaunchScreen
的話,狀況會變的很簡單,LaunchScreen
是支持AutoLayout
和SizeClass
的,因此適配各類屏幕都不在話下。App
將必須提供LaunchScreen
,而LaunchImage
即將退出歷史舞臺
'UIWebView' was deprecated in iOS 12.0: No longer supported; please adopt WKWebView.
從
iOS 13
開始也再也不支持UIWebView
控件了, 儘快替換成WKWebView
吧
@available(iOS, introduced: 2.0, deprecated: 12.0, message: "No longer supported; please adopt WKWebView.")
open class UIWebView : UIView, NSCoding, UIScrollViewDelegate { }
複製代碼
歡迎您掃一掃下面的微信公衆號,訂閱個人博客!