Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Add dark mode to your apps. #potatotips / add dark mode to your apps

Add dark mode to your apps. #potatotips / add dark mode to your apps

potatotips #61にて発表したきたものです。
# Typeにダークモードを追加したのでその考え方と方法、ライブラリとして書き出した( https://github.com/fromkk/ColorSet )の宣伝です。

fromkk

May 15, 2019
Tweet

More Decks by fromkk

Other Decks in Programming

Transcript

  1. 1SPpMF struct Profile { let name = "Kazuya Ueoka" let

    twitter = "@fromkk" let github = "fromkk" let qiita = "fromkk" let company = "Timers Inc." } • 2
  2. *GZPVBSFVTJOH3Y4XJGU ZPVDBOJNQMFNFOUFBTJMZ import UIKit import RxSwift import RxCocoa struct ColorSet

    { static var backgroundColor = BehaviorRelay<UIColor>(value: defaultBackgroundColor) static var theme = BehaviorRelay<UIColor>(value: defaultThemeColor) } // Bind background color ColorSet.backgroundColor.bind(to: view.rx.backgroundColor).disposed(by: disposeBag)
 
 // Change background color ColorSet.backgroundColor.accept(backgroundColorDark)
  3. #VU

  4. TU$SFBUFPCTFSWBUJPO import Foundation public class ColorObservation: Equatable { private let

    observation: NSObjectProtocol weak var notificationCenter: NotificationCenter? init(_ observation: NSObjectProtocol, notificationCenter: NotificationCenter) { self.observation = observation self.notificationCenter = notificationCenter } public func unregister() { notificationCenter?.removeObserver(observation) } public func append(to observationBag: ColorObservationBag) { observationBag.add(self) } public static func == (lhs: ColorObservation, rhs: ColorObservation) -> Bool { return lhs.observation.isEqual(rhs.observation) && (lhs.notificationCenter?.isEqual(rhs.notificationCenter) ?? false) } }
  5. OE4UPSFPCTFSWBUJPOTUPCBH import Foundation public class ColorObservationBag { var observations: [ColorObservation]

    = [] public init() {} deinit { observations.forEach { observation in observation.unregister() } observations = [] } public func add(_ observation: ColorObservation) { observations.append(observation) } public func remove(_ observation: ColorObservation) { guard let index = observations.firstIndex(of: observation) else { return } observation.unregister() observations.remove(at: index) } }
  6. SE$SFBUF0CTFSWBCMF public class ColorObservable { let didChange: Notification.Name = .init("me.fromkk.ColorSet.didChange")

    let notificationCenter: NotificationCenter = .init() public private(set) var value: UIColor { didSet { notificationCenter.post(name: didChange, object: value) } } public init(_ value: UIColor) { self.value = value } /// Change color /// /// - Parameter value: Color public func accept(_ value: UIColor) { self.value = value } }
  7. UI*NQMFNFOUTTVCTDSJCFBOECJOE extension ColorObservable { public func subscribe(_ callback: @escaping (UIColor)

    -> Void) -> ColorObservation { callback(value) return ColorObservation( notificationCenter.addObserver(forName: didChange, object: nil, queue: .main, using: { notification in guard let value = notification.object as? UIColor else { return } callback(value) }), notificationCenter: notificationCenter ) } public func bind<O: AnyObject>(to object: O, keyPath: ReferenceWritableKeyPath<O, UIColor>) -> ColorObservation { return subscribe { [weak object] value in object?[keyPath: keyPath] = value } } public func bind<O: AnyObject>(to object: O, keyPath: ReferenceWritableKeyPath<O, UIColor?>) -> ColorObservation { return subscribe { [weak object] value in object?[keyPath: keyPath] = value } } }
  8. )PXUPVTF #JOEDPMPSUPZPVSQSPQFSUZ class ViewController: UIViewController { @IBOutlet var label: UILabel!

    @IBOutlet var darkmodeSwitch: UISwitch! let observationBag = ColorObservationBag() override func viewDidLoad() { super.viewDidLoad() MyColorSet.backgroundColor.bind(to: view, keyPath: \.backgroundColor).append(to: observationBag) MyColorSet.textColor.bind(to: label, keyPath: \.textColor).append(to: observationBag) MyColorSet.textColor.subscribe { [weak self] color in self?.label.layer.borderColor = color.cgColor }.append(to: observationBag) } @IBAction func darkmodeSwitchDidChanged(_ sender: UISwitch) { if sender.isOn { MyColorSet.replace(DarkColorSet.self) } else { MyColorSet.replace(DefaultColorSet.self) } } }
  9. 13

  10. • αʔόʔαΠυΤϯδχΞ (PHP, Golang, AWS) • AndroidΤϯδχΞ (Kotlin) • iOSΤϯδχΞ

    (Swift) TimersͰ͸ݱࡏΤϯδχΞશ৬छ࠾༻தʂ
 ৄ͘͠͸”Timers”Ͱݕࡧ