Add @objc annotation for use in Objective-C only projects (#106)

* Allow FluentDarkModeKit to be used in ObjC

* Update documentation with spacing, objc usage, and warning on iOS 13
This commit is contained in:
Levin Li 2021-05-20 12:57:51 +08:00 коммит произвёл GitHub
Родитель 7a7309d4fd
Коммит 6c1122a7c5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 75 добавлений и 12 удалений

Просмотреть файл

@ -56,17 +56,22 @@ pod "FluentDarkModeKit"
### How to Set Up FluentDarkModeKit ### How to Set Up FluentDarkModeKit
To set up FluentDarkModeKit, you need to call the following methods first. To set up FluentDarkModeKit, you need to call the following methods first. A good place to call it is inside your AppDelegate's `application:didFinishLaunchingWithOptions:`.
```swift ```swift
import FluentDarkModeKit
let configuration = DMEnvironmentConfiguration() let configuration = DMEnvironmentConfiguration()
configuration.themeChangeHandler = { configuration.themeChangeHandler = {
print("theme changed") print("theme changed")
} }
configuration.windowThemeChangeHandler = { window in
if #available(iOS 13.0, *) {
configuration.windowThemeChangeHandler = { window in
print("\(window) theme changed") print("\(window) theme changed")
}
configuration.useImageAsset = false
} }
configuration.useImageAsset = false
DarkModeManager.setup(with: configuration) DarkModeManager.setup(with: configuration)
DarkModeManager.register(with: UIApplication.shared) DarkModeManager.register(with: UIApplication.shared)
@ -97,6 +102,30 @@ It determines whether UIImageAsset is used for dynamic image. iOS 13+. Defaults
Images marked with "Preserve Vector Data" must not to be used when it is set to true. Images marked with "Preserve Vector Data" must not to be used when it is set to true.
**Objective-C**
The equivalent Objective-C code for setting up FluentDarkModeKit is as below.
```objective-c
#import <FluentDarkModeKit/FluentDarkModeKit.h>
#import <FluentDarkModeKit/FluentDarkModeKit-Swift.h>
DMEnvironmentConfiguration *configuration = [[DMEnvironmentConfiguration alloc] init];
configuration.themeChangeHandler = ^{
NSLog(@"theme changed");
};
if (@available(iOS 13.0, *)) {
configuration.windowThemeChangeHandler = ^(UIWindow *window) {
NSLog(@"%@ theme changed", window);
};
configuration.useImageAsset = NO;
}
[DarkModeManager setupWithConfiguration:configuration];
[DarkModeManager registerWithApplication:[UIApplication sharedApplication] syncImmediately:NO animated:NO];
```
### How to Use FluentDarkModeKit ### How to Use FluentDarkModeKit
To use FluentDarkModeKit, provide a pair of colors or images instead of a single value. Simply replace existing colors/images with a pair of light and dark colors/images. To use FluentDarkModeKit, provide a pair of colors or images instead of a single value. Simply replace existing colors/images with a pair of light and dark colors/images.
@ -105,21 +134,36 @@ To use FluentDarkModeKit, provide a pair of colors or images instead of a single
```swift ```swift
extension UIColor { extension UIColor {
init(_ namespace: DMNamespace, light: UIColor, dark: UIColor) init(_ namespace: DMNamespace, light: UIColor, dark: UIColor)
init(_ namespace: DMNamespace, dynamicProvider: @escaping (DMTraitCollection) -> UIColor) init(_ namespace: DMNamespace, dynamicProvider: @escaping (DMTraitCollection) -> UIColor)
} }
let color1 = UIColor(.dm, light: .white, dark: .black) let color1 = UIColor(.dm, light: .white, dark: .black)
let color2 = UIColor(.dm) { traitCollection in let color2 = UIColor(.dm) { traitCollection in
return traitCollection.userInterfaceStyle == .dark ? UIColor.black : UIColor.white return traitCollection.userInterfaceStyle == .dark ? UIColor.black : UIColor.white
} }
``` ```
Objective-C
```objective-c
UIColor *color1 = [UIColor dm_colorWithLightColor:[UIColor whiteColor] darkColor:[UIColor blackColor]];
UIColor *color2 = [UIColor dm_colorWithDynamicProvider:^UIColor * (DMTraitCollection *traitCollection) {
if (traitCollection.userInterfaceStyle == DMUserInterfaceStyleDark) {
return [UIColor blackColor];
}
return [UIColor whiteColor];
}];
```
#### Images #### Images
```swift ```swift
extension UIImage { extension UIImage {
init(_ namespace: DMNamespace, light: UIImage, dark: UIImage) init(_ namespace: DMNamespace, light: UIImage, dark: UIImage)
} }
let lightImage = UIImage(named: "Light")! let lightImage = UIImage(named: "Light")!
@ -127,6 +171,14 @@ let darkImage = UIImage(named: "Dark")!
let image = UIImage(.dm, light: lightImage, dark: darkImage) let image = UIImage(.dm, light: lightImage, dark: darkImage)
``` ```
Objective-C
```objective-c
UIImage *image = [UIImage dm_imageWithLightImage:lightImage darkImage:darkImage];
```
#### Change Theme #### Change Theme
```swift ```swift
@ -134,6 +186,13 @@ DMTraitCollection.setOverride(DMTraitCollection(userInterfaceStyle: .light), ani
DMTraitCollection.setOverride(DMTraitCollection(userInterfaceStyle: .unspecified), animated: true) // Change to "follow system" theme DMTraitCollection.setOverride(DMTraitCollection(userInterfaceStyle: .unspecified), animated: true) // Change to "follow system" theme
``` ```
Objective-C
```objective-c
[DMTraitCollection setOverrideTraitCollection:[DMTraitCollection traitCollectionWithUserInterfaceStyle:DMUserInterfaceStyleLight] animated:YES]; // Change to light theme with animation
[DMTraitCollection setOverrideTraitCollection:[DMTraitCollection traitCollectionWithUserInterfaceStyle:DMUserInterfaceStyleUnspecified] animated:YES]; // Change to "follow system" theme
```
### Others ### Others
For more complex scenarios, FluentDarkModeKit is similar to what Apple does in iOS 13 (some slight differences). It maintains a global `DMTraitCollection` which can be accessed through `DMTraitCollection.current` during custom layout. For more complex scenarios, FluentDarkModeKit is similar to what Apple does in iOS 13 (some slight differences). It maintains a global `DMTraitCollection` which can be accessed through `DMTraitCollection.current` during custom layout.
@ -142,9 +201,13 @@ For more information on cases you should handle during layout, please refer to [
FluentDarkModeKit will notify views or view controllers in the current window when the theme changes by calling the following delegate method. FluentDarkModeKit will notify views or view controllers in the current window when the theme changes by calling the following delegate method.
Note that on iOS 13 and later, certain UIKit classes do not call `UIView`'s implementation of `traitCollectionDidChange(_:)`, thus `dmTraitCollectionDidChange(_:)` will not be invoked.
The (incomprehensive) list includes UIImageView, UILabel, UIDatePicker, UIPickerView, UISplitViewController, and their subclasses. See [issue 104](https://github.com/microsoft/FluentDarkModeKit/issues/104) .
```swift ```swift
protocol DMTraitEnvironment: NSObjectProtocol { protocol DMTraitEnvironment: NSObjectProtocol {
func dmTraitCollectionDidChange(_ previousTraitCollection: DMTraitCollection?) func dmTraitCollectionDidChange(_ previousTraitCollection: DMTraitCollection?)
} }
``` ```

Просмотреть файл

@ -11,16 +11,16 @@ import UIKit
public final class DarkModeManager: NSObject { public final class DarkModeManager: NSObject {
private static var swizzlingConfigured = false private static var swizzlingConfigured = false
public static func setup(with configuration: DMEnvironmentConfiguration) { @objc(setupWithConfiguration:) public static func setup(with configuration: DMEnvironmentConfiguration) {
commonSetup(with: configuration) commonSetup(with: configuration)
} }
public static func register(with application: UIApplication, syncImmediately: Bool = false, animated: Bool = false) { @objc(registerWithApplication:syncImmediately:animated:) public static func register(with application: UIApplication, syncImmediately: Bool = false, animated: Bool = false) {
DMTraitCollection.register(with: application, syncImmediately: syncImmediately, animated: animated) DMTraitCollection.register(with: application, syncImmediately: syncImmediately, animated: animated)
} }
@available(iOSApplicationExtension 11.0, *) @available(iOSApplicationExtension 11.0, *)
public static func register(with viewController: UIViewController, syncImmediately: Bool = false, animated: Bool = false) { @objc(registerWithViewController:syncImmediately:animated:) public static func register(with viewController: UIViewController, syncImmediately: Bool = false, animated: Bool = false) {
DMTraitCollection.register(with: viewController, syncImmediately: syncImmediately, animated: animated) DMTraitCollection.register(with: viewController, syncImmediately: syncImmediately, animated: animated)
} }