Migrate UIImage APIs to using UIImageAsset on iOS13 (#82)
* Mark DMTraitCollection.current as deprecated * System built-in support for dark/light mode UIImage
This commit is contained in:
Родитель
55e55946e1
Коммит
1f11a409e0
|
@ -55,6 +55,7 @@
|
|||
8CE066D0239E5586002CE16D /* UIImage+DarkModeKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CC8D8722398E7A30043276A /* UIImage+DarkModeKit.m */; };
|
||||
EA2EA50024A1CBF2001AE312 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA2EA4FE24A1CAD5001AE312 /* SceneDelegate.swift */; };
|
||||
EA7316F1248F5055009AE037 /* UILabelVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7316EF248F5050009AE037 /* UILabelVC.swift */; };
|
||||
EAE6065624A9DA1B001304D1 /* UIImageViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE6065324A9D9E0001304D1 /* UIImageViewVC.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -149,6 +150,7 @@
|
|||
8CDA628B2366DAA9004895B5 /* DMDynamicColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DMDynamicColor.h; sourceTree = "<group>"; };
|
||||
EA2EA4FE24A1CAD5001AE312 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
EA7316EF248F5050009AE037 /* UILabelVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelVC.swift; sourceTree = "<group>"; };
|
||||
EAE6065324A9D9E0001304D1 /* UIImageViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewVC.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -289,6 +291,7 @@
|
|||
8C63F64123A36B0900D93CF4 /* UIButtonVC.swift */,
|
||||
8C63F64423A374CF00D93CF4 /* UIPageControlVC.swift */,
|
||||
EA7316EF248F5050009AE037 /* UILabelVC.swift */,
|
||||
EAE6065324A9D9E0001304D1 /* UIImageViewVC.swift */,
|
||||
8CAFD9DD23715FAB001A63B8 /* Assets.xcassets */,
|
||||
8CAFD9DF23715FAB001A63B8 /* LaunchScreen.storyboard */,
|
||||
8CAFD9E223715FAB001A63B8 /* Info.plist */,
|
||||
|
@ -576,6 +579,7 @@
|
|||
8C7B250C23A22A80002E2558 /* UIActivityIndicatorViewVC.swift in Sources */,
|
||||
8CAFD9D923715FAA001A63B8 /* ViewController.swift in Sources */,
|
||||
8C63F64323A36B2700D93CF4 /* UIButtonVC.swift in Sources */,
|
||||
EAE6065624A9DA1B001304D1 /* UIImageViewVC.swift in Sources */,
|
||||
EA7316F1248F5055009AE037 /* UILabelVC.swift in Sources */,
|
||||
8CAFD9ED2371606D001A63B8 /* NavigationController.swift in Sources */,
|
||||
EA2EA50024A1CBF2001AE312 /* SceneDelegate.swift in Sources */,
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
- (UIColor *)resolvedColor {
|
||||
return [self resolvedColorWithTraitCollection:DMTraitCollection.currentTraitCollection];
|
||||
return [self resolvedColorWithTraitCollection:DMTraitCollection.overrideTraitCollection];
|
||||
}
|
||||
|
||||
- (UIColor *)resolvedColorWithTraitCollection:(DMTraitCollection *)traitCollection {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
}
|
||||
|
||||
- (UIImage *)resolvedImage {
|
||||
if (DMTraitCollection.currentTraitCollection.userInterfaceStyle == DMUserInterfaceStyleDark) {
|
||||
if (DMTraitCollection.overrideTraitCollection.userInterfaceStyle == DMUserInterfaceStyleDark) {
|
||||
return self.darkImage;
|
||||
} else {
|
||||
return self.lightImage;
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef NS_ENUM(NSInteger, DMUserInterfaceStyle) {
|
|||
|
||||
@interface DMTraitCollection : NSObject
|
||||
|
||||
@property (class, nonatomic, readonly) DMTraitCollection *currentTraitCollection;
|
||||
@property (class, nonatomic, readonly) DMTraitCollection *currentTraitCollection API_DEPRECATED("Use overrideTraitCollection instead.", ios(11.0, 11.0));
|
||||
@property (class, nonatomic, readonly) DMTraitCollection *overrideTraitCollection;
|
||||
|
||||
+ (DMTraitCollection *)traitCollectionWithUserInterfaceStyle:(DMUserInterfaceStyle)userInterfaceStyle;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
@implementation DMTraitCollection
|
||||
|
||||
static DMTraitCollection *_overrideTraitCollection = nil; // This is set manually in setCurrentTraitCollection:animated
|
||||
static DMTraitCollection *_overrideTraitCollection = nil; // This is set manually in setOverrideTraitCollection:animated
|
||||
static void (^_userInterfaceStyleChangeHandler)(DMTraitCollection *, BOOL) = nil;
|
||||
static BOOL _isObservingNewWindowAddNotification = NO;
|
||||
|
||||
|
@ -68,8 +68,8 @@ static BOOL _isObservingNewWindowAddNotification = NO;
|
|||
return [DMTraitCollection traitCollectionWithUITraitCollection:UIScreen.mainScreen.traitCollection];
|
||||
}
|
||||
|
||||
+ (void)setOverrideTraitCollection:(DMTraitCollection *)currentTraitCollection animated:(BOOL)animated {
|
||||
_overrideTraitCollection = currentTraitCollection;
|
||||
+ (void)setOverrideTraitCollection:(DMTraitCollection *)overrideTraitCollection animated:(BOOL)animated {
|
||||
_overrideTraitCollection = overrideTraitCollection;
|
||||
[self syncImmediatelyAnimated:animated];
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#import "UIImage+DarkModeKit.h"
|
||||
#import "DMDynamicImage.h"
|
||||
#import "DMTraitCollection.h"
|
||||
|
||||
@import ObjectiveC;
|
||||
|
||||
|
@ -36,6 +37,22 @@
|
|||
}
|
||||
|
||||
+ (UIImage *)dm_imageWithLightImage:(UIImage *)lightImage darkImage:(UIImage *)darkImage {
|
||||
if (@available(iOS 13, *)) {
|
||||
UIImageAsset *imageAsset = [[UIImageAsset alloc] init];
|
||||
|
||||
// Always specify a displayScale otherwise a default of 1.0 is assigned
|
||||
[imageAsset registerImage:lightImage withTraitCollection:[UITraitCollection traitCollectionWithTraitsFromCollections:@[
|
||||
[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight],
|
||||
[UITraitCollection traitCollectionWithDisplayScale:lightImage.scale]
|
||||
]]];
|
||||
[imageAsset registerImage:darkImage withTraitCollection:[UITraitCollection traitCollectionWithTraitsFromCollections:@[
|
||||
[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark],
|
||||
[UITraitCollection traitCollectionWithDisplayScale:darkImage.scale]
|
||||
]]];
|
||||
|
||||
return [imageAsset imageWithTraitCollection:DMTraitCollection.overrideTraitCollection.uiTraitCollection];
|
||||
}
|
||||
|
||||
return (UIImage *)[[DMDynamicImageProxy alloc] initWithLightImage:lightImage darkImage:darkImage];
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ extension UILabel {
|
|||
class_replaceMethod(UILabel.self, selector, imp_implementationWithBlock({ (self: UILabel) -> Void in
|
||||
let oldIMP = unsafeBitCast(imp, to: (@convention(c) (UILabel, Selector) -> Void).self)
|
||||
oldIMP(self, selector)
|
||||
if self.currentUserInterfaceStyle != DMTraitCollection.current.userInterfaceStyle {
|
||||
self.currentUserInterfaceStyle = DMTraitCollection.current.userInterfaceStyle
|
||||
if self.currentUserInterfaceStyle != DMTraitCollection.override.userInterfaceStyle {
|
||||
self.currentUserInterfaceStyle = DMTraitCollection.override.userInterfaceStyle
|
||||
self.dmTraitCollectionDidChange(nil)
|
||||
}
|
||||
} as @convention(block) (UILabel) -> Void), method_getTypeEncoding(method))
|
||||
|
|
|
@ -14,7 +14,7 @@ extension UIScrollView {
|
|||
dm_updateDynamicColors()
|
||||
|
||||
indicatorStyle = {
|
||||
if DMTraitCollection.current.userInterfaceStyle == .dark {
|
||||
if DMTraitCollection.override.userInterfaceStyle == .dark {
|
||||
return .white
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -18,7 +18,7 @@ extension UITextField {
|
|||
}
|
||||
|
||||
keyboardAppearance = {
|
||||
if DMTraitCollection.current.userInterfaceStyle == .dark {
|
||||
if DMTraitCollection.override.userInterfaceStyle == .dark {
|
||||
return .dark
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -14,7 +14,7 @@ extension UITextView {
|
|||
dm_updateDynamicColors()
|
||||
|
||||
keyboardAppearance = {
|
||||
if DMTraitCollection.current.userInterfaceStyle == .dark {
|
||||
if DMTraitCollection.override.userInterfaceStyle == .dark {
|
||||
return .dark
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -18,7 +18,8 @@ final class MainViewController: ViewController {
|
|||
Row(name: "UIActivityIndicatorView", vcType: UIActivityIndicatorViewVC.self),
|
||||
Row(name: "UIButton", vcType: UIButtonVC.self),
|
||||
Row(name: "UILabel", vcType: UILabelVC.self),
|
||||
Row(name: "UIPageControl", vcType: UIPageControlVC.self)
|
||||
Row(name: "UIPageControl", vcType: UIPageControlVC.self),
|
||||
Row(name: "UIImageView", vcType: UIImageViewVC.self),
|
||||
]
|
||||
|
||||
lazy var tableView: UITableView = {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
import FluentDarkModeKit
|
||||
|
||||
private extension UIColor {
|
||||
var demoImage: UIImage {
|
||||
let size = CGSize(width: 50, height: 50)
|
||||
return UIGraphicsImageRenderer(size: size).image { context in
|
||||
setFill()
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class UIImageViewVC: ViewController {
|
||||
let imageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
imageView.image = UIImage(.dm, light: UIColor.red.demoImage, dark: UIColor.green.demoImage)
|
||||
return imageView
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = UIColor(.dm, light: .white, dark: .black)
|
||||
|
||||
view.addSubview(imageView)
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
|
||||
imageView.sizeToFit()
|
||||
imageView.center = view.center
|
||||
}
|
||||
}
|
|
@ -32,9 +32,21 @@ final class DarkModeKitUITests: XCTestCase {
|
|||
_test("UIPageControl")
|
||||
}
|
||||
|
||||
func testUILabel() {
|
||||
_test("UILabel")
|
||||
}
|
||||
|
||||
func testUIImageView() {
|
||||
_test("UIImageView")
|
||||
}
|
||||
|
||||
func _test(_ className: String) {
|
||||
let app = XCUIApplication()
|
||||
let refreshButton = app.navigationBars["FluentDarkModeKitExample.MainView"].buttons["Refresh"]
|
||||
let navigationBarIdentifier = "0" // Current window index is used as navigation bar title
|
||||
let refreshButtonIdentifier = "Refresh"
|
||||
let compareNavigatonBarTitle = "FluentDarkModeKitExample.View"
|
||||
|
||||
let refreshButton = app.navigationBars[navigationBarIdentifier].buttons[refreshButtonIdentifier]
|
||||
refreshButton.tap() // light mode
|
||||
refreshButton.tap() // dark mode
|
||||
|
||||
|
@ -45,14 +57,15 @@ final class DarkModeKitUITests: XCTestCase {
|
|||
|
||||
let screenshot1 = app.screenshot()
|
||||
|
||||
app.navigationBars["FluentDarkModeKitExample.\(className)VC"].buttons["Back"].tap()
|
||||
let backButtonTitle = navigationBarIdentifier
|
||||
app.navigationBars[navigationBarIdentifier].buttons[backButtonTitle].tap()
|
||||
refreshButton.tap() // unspecified
|
||||
refreshButton.tap() // light mode
|
||||
uiviewStaticText.tap()
|
||||
|
||||
let tabBarsQuery = app.tabBars
|
||||
tabBarsQuery.children(matching: .button).element(boundBy: 1).tap()
|
||||
app.navigationBars["FluentDarkModeKitExample.View"].buttons["Refresh"].tap()
|
||||
app.navigationBars[compareNavigatonBarTitle].buttons[refreshButtonIdentifier].tap()
|
||||
tabBarsQuery.children(matching: .button).element(boundBy: 0).tap() // dark mode
|
||||
|
||||
let screenshot2 = app.screenshot()
|
||||
|
|
Загрузка…
Ссылка в новой задаче