Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
20180710_iOSLT_iOSでDarkModeを実装する
Search
shtnkgm
July 10, 2018
Programming
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
20180710_iOSLT_iOSでDarkModeを実装する
shtnkgm
July 10, 2018
More Decks by shtnkgm
See All by shtnkgm
Combine入門
shtnkgm
2
330
Property Wrappers
shtnkgm
0
380
Saliency Detection
shtnkgm
0
89
パフォーマンス改善とユニットテスト
shtnkgm
4
1.8k
iOSのコードベースレイアウト
shtnkgm
2
840
20190117_iOSLT_CBLinSwift.pdf
shtnkgm
0
130
SwiftとFunctional Reactive Programming
shtnkgm
0
200
20180410_iOSLT_SwiftとProtocol-OrientedProgramming
shtnkgm
0
140
20180220_iOSLT_Swiftとオブジェクト間の通知のパターン
shtnkgm
0
170
Other Decks in Programming
See All in Programming
Hono + Inertia + React で LP を構築した話
oukayuka
2
220
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
130
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
2
270
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
3
460
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
55
37k
Foundry Localでエージェント開発
seosoft
0
160
Webの地図
yosuke_furukawa
PRO
4
3.8k
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
500
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
130
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
590
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
300
App Intentsのビルドプロセスを支える技術
kntkymt
0
170
Featured
See All Featured
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Odyssey Design
rkendrick25
PRO
2
800
Optimizing for Happiness
mojombo
378
71k
Color Theory Basics | Prateek | Gurzu
gurzu
0
460
Automating Front-end Workflow
addyosmani
1369
210k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
990
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
Exploring anti-patterns in Rails
aemeredith
3
500
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
240
New Earth Scene 8
popppiees
3
2.5k
Transcript
iOSͰDarkModeΛ࣮͢Δ 2018.7.10 iOSLT / Shota Nakagami (@shtnkgm)
Mojaveͷ৽ػೳDarkMode iOSͷαϙʔτͳ͍͚Ͳ࣮ͯ͠ΈΔ
DarkModeͬͯͲΜͳͷ?
None
None
DarkMode͔͍͍ͬ͜
DarkModeʹ͍͞͠
DarkMode
ࣗͰ࣮͢Δ
৭Λߟ͑Δ • ௨ৗ࣌ͱDarkModeͷ࣌ͲΜͳ৭ʹ͢Δ͔ • Human Interface GuidelinesʹMacOSͰͷDarkModeͷํ͋Γ • ͨͩ୯७ʹ໌Λస͢Εྑ͍Θ͚Ͱͳ͍ •
ݟ͍͢Α͏ʹDarkModeͰͷ৭ͷௐ͕ඞཁ • ۩ମతͳ৭ͷࢦఆGoogle Material Design͕ࢀߟʹͳΔ
৭ΛͱʹUIColorΛ֦ு͢Δ
UI DarkMode ௨ৗ ϝΠϯςΩετ ϗϫΠτʢα=100%ʣ ϒϥοΫʢα=87%ʣ αϒςΩετ ϗϫΠτʢα=70%ʣ ϒϥοΫʢα=54%ʣ DisabledςΩετ
ϗϫΠτʢα=50%ʣ ϒϥοΫʢα=38%ʣ ΞΫςΟϒΞΠίϯ ϗϫΠτʢα=100%ʣ ϒϥοΫʢα=54%ʣ ඇΞΫςΟϒΞΠίϯ ϗϫΠτʢα=38%ʣ ϒϥοΫʢα=50%ʣ σΟόΠμʔ άϨʔʢ#303030ʣ ϒϥοΫʢα=12%ʣ πʔϧόʔ άϨʔʢ#212121ʣ άϨʔʢ#F5F5F5ʣ Χʔυ άϨʔʢ#424242ʣ ϗϫΠτʢα=100%ʣ എܠ άϨʔʢ#303030ʣ άϨʔʢ#FAFAFAʣ
UIColorͷϓϥΠϕʔτExtensionͰෆಁ໌৭༻ͷมΛ࡞ private extension UIColor { static var gray050: UIColor {
return color("#FAFAFA") } static var gray100: UIColor { return color("#F5F5F5") } static var gray200: UIColor { return color("#EEEEEE") } static var gray300: UIColor { return color("#E0E0E0") } static var gray400: UIColor { return color("#BDBDBD") } static var gray500: UIColor { return color("#9E9E9E") } static var gray600: UIColor { return color("#757575") } static var gray700: UIColor { return color("#616161") } static var gray800: UIColor { return color("#424242") } static var gray850: UIColor { return color("#303030") } static var gray900: UIColor { return color("#212121") } }
UIColorͷϓϥΠϕʔτExtensionͰಁ໌৭༻ͷมΛ࡞ private extension UIColor { static var blackHalfTranslucent: UIColor {
return .init(white: 0, alpha: 0.5) } static var black012: UIColor { return .init(white: 1.00 - 0.12, alpha: 1) } static var black038: UIColor { return .init(white: 1.00 - 0.38, alpha: 1) } static var black050: UIColor { return .init(white: 1.00 - 0.50, alpha: 1) } static var black054: UIColor { return .init(white: 1.00 - 0.54, alpha: 1) } static var black070: UIColor { return .init(white: 1.00 - 0.70, alpha: 1) } static var black087: UIColor { return .init(white: 1.00 - 0.87, alpha: 1) } static var black100: UIColor { return .init(white: 1.00 - 1.00, alpha: 1) } static var whiteHalfTranslucent: UIColor { return .init(white: 1, alpha: 0.5) } static var white012: UIColor { return .init(white: 0.12, alpha: 1) } static var white038: UIColor { return .init(white: 0.38, alpha: 1) } static var white050: UIColor { return .init(white: 0.50, alpha: 1) } static var white054: UIColor { return .init(white: 0.54, alpha: 1) } static var white070: UIColor { return .init(white: 0.70, alpha: 1) } static var white087: UIColor { return .init(white: 0.87, alpha: 1) } static var white100: UIColor { return .init(white: 1.00, alpha: 1) } }
UIColorͷύϒϦοΫExtensionͰ෦৭ͷมΛ࡞ public extension UIColor { static var primary: UIColor {
return Config.shared.primaryColor } static var activeIcon: UIColor { return isDarkTheme ? .white100 : .black054 } static var inactiveIcon: UIColor { return isDarkTheme ? .white038 : .black050 } static var primaryText: UIColor { return isDarkTheme ? .white100 : .black087 } static var secondaryText: UIColor { return isDarkTheme ? .white070 : .black054 } static var disabledText: UIColor { return isDarkTheme ? .white050 : .black038 } static var linkText: UIColor { return .flatSkyBlue() } static var dividers: UIColor { return isDarkTheme ? .gray850 : .black012 } static var statusBar: UIColor { return isDarkTheme ? .black100 : .gray300 } static var appBar: UIColor { return isDarkTheme ? .gray900 : .gray100 } static var highlightedAppBar: UIColor { return isDarkTheme ? .gray800 : .gray200 } static var background: UIColor { return isDarkTheme ? .gray850 : .gray050 } static var card: UIColor { return isDarkTheme ? .gray800 : .white100 } static var highlightedCard: UIColor { return isDarkTheme ? .gray850 : .gray100 } }
৭Λࢦఆ͢Δ backgroundColor = .card mainLabel.textColor = .primaryText settingSwitch.onTintColor = .primary
ΞΠίϯը૾Ͳ͏͢Δʁ
UIImageΛUIColorͰృΕΔΑ͏ʹ͢Δ
public extension UIImage { public func image(withTint color: UIColor) ->
UIImage { let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) UIGraphicsBeginImageContextWithOptions(rect.size, false, 0) guard let context: CGContext = UIGraphicsGetCurrentContext(), let cgImage = cgImage else { return UIImage() } context.scaleBy(x: 1, y: -1) context.translateBy(x: 0, y: -self.size.height) context.clip(to: rect, mask: cgImage) context.setFillColor(color.cgColor) context.fill(rect) guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return UIImage() } UIGraphicsEndImageContext() return image } }
let iconImage = UIImage(named: "icon").image(withTint: .activeIcon)
image(withTint: )OSSͷta1n/Swi3ExtensionsͰར༻Մ
ࣗcontribu)onͯ͠·͢
ΊͰͨ͠ΊͰͨ͠
ΊͰͨ͠ΊͰͨ͠
ϞʔυΓସ͑࣌ʹ৭ͷมߋ͕ඞཁ DarkMode⁶௨ৗ
͜Ε͕Γ͍ͨ ΈΜͳʙ৭Λߋ৽ͯ͠ʙ
௨ઌ͕nݸͷ௨ͷΈͱ͍͑ʁ
No#fica#onCenter ࢀߟ: shtnkgm / Swi.ͱΦϒδΣΫτؒͷ௨ͷύλʔϯ
࣮֓ཁ 1. ֤ViewͰ௨Λߪಡ͓ͯ͘͠ 2. Ϟʔυͷมߋ࣌ʹNo*fica*onCenterͰ௨ 3. ֤ViewͰ௨Λड͚औΔ 4. ֤ViewͰ৭Λߋ৽
֤ViewͰड৴ॲཧΛॻ͘ͷ໘ public extension Notification.Name { static let styleUpdated = Notification.Name("styleUpdated")
} class HogeView { init() { let center = NotificationCenter.default center.addObserver(self, selector: #selector(updateStyle), name: .styleUpdated, object: nil) updateStyle() } @objc func updateStyle() { backgroundColor = .card } }
ϓϩτίϧͰॲཧΛڞ௨Խ
StyleUpdatable
public protocol StyleUpdatable: class { /// ௨Λղআ͢Δ߹ObserverΛอ࣋͢Δඞཁ͋Γ var updateStyleObserver: NSObjectProtocol?
{ get set } /// ৭ͷߋ৽ॲཧඞͣupdateStyleͱ͍͏໊લͷϝιουͰߦ͏ func updateStyle() }
public extension StyleUpdatable { /// updateStyleObserverΛҙ࣮ͱ͢ΔͨΊͷσϑΥϧτ࣮ var updateStyleObserver: NSObjectProtocol? {
get { return nil } set { } } /// ߪಡ & updateStyle()Λ࣮ߦ func observeAndUpdateStyle() { updateStyle() let center = NotificationCenter.default updateStyleObserver = center.addObserver(forName: .styleUpdated, object: nil, queue: nil) { [weak self] _ in self?.updateStyle() } } }
class HogeView: StyleUpdatable { init() { observeAndUpdateStyle() } // StyleUpdatableʹΑΓ࣮͕ڧ੍͞ΕΔ
func updateStyle() { backgroundColor = .card } }
ద༻αϯϓϧ ͡ͿΜͷΞϓϦͰಋೖ
None
None
None
None
ͦΕͬΆ͘ͳͬͨ
·ͱΊ • DarkModeͱ௨ৗ࣌ͷ৭Λߟ͑Δ • UIColorΛ֦ுͯ͠ɺDarkMode͔Ͳ͏͔Ͱذ (֤ViewDarkMode͔Ͳ͏͔Λߟྀ͠ͳͯ͘ྑ͍) • ΞΠίϯUIImageΛUIColorͰృΕΔΑ͏ʹ͢Δ • StyleUpdatableϓϩτίϧͰ৭ͷߋ৽ॲཧΛڞ௨Խ
͓ΘΓ ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠