Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
🤔 with IB/thinking_with_interface_builder
Search
fromkk
March 28, 2018
Programming
4
3.6k
🤔 with IB/thinking_with_interface_builder
2018/03/28にエウレカ様で開催されたAKIBA.swift × エウレカ コードレイアウト勉強会で発表した内容です。
fromkk
March 28, 2018
Tweet
Share
More Decks by fromkk
See All by fromkk
note社の全員野球で品質向上活動について / note_qa_challenge #iOS_test_teatime
fromkk
3
1.8k
1年分のデータが見たいと言われてやったこと/yearly_data_with_note
fromkk
0
920
note iOSチームの自動化 ver.2021/automation_with_iOS_team_on_note_ver2021
fromkk
0
1.9k
Bitrise体験会説明資料/bitrise_explore
fromkk
1
1k
noteのiOSアプリで実装したアクセシビリティの全て #iosdc #a /a11y_with_iOS_App_on_note
fromkk
2
3.6k
dSYMのアップロードで SPMを活用する/use_spm_with_upload_dsyms
fromkk
1
2.7k
Bitriseのリモートアクセス機能 #bitrise_meetup/remote_access_of_bitrise
fromkk
1
550
note社でのMagic Pod活用事例 #af_iosdc/magicpod_with_note
fromkk
2
11k
iOSには無いmacOS独自機能をCatalystで実装する #iosdc #d/make_macos_apps_with_catalyst
fromkk
9
2.1k
Other Decks in Programming
See All in Programming
コミュニティ駆動 AWS CDK ライブラリ「Open Constructs Library」 / community-cdk-library
gotok365
2
250
SwiftUI移行のためのインプレッショントラッキング基盤の構築
kokihirokawa
0
150
未経験でSRE、はじめました! 組織を支える役割と軌跡
curekoshimizu
1
160
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
55
19k
自力でTTSモデルを作った話
zgock999
0
110
AIプログラミング雑キャッチアップ
yuheinakasaka
19
4.7k
複数のAWSアカウントから横断で 利用する Lambda Authorizer の作り方
tc3jp
0
120
もう少しテストを書きたいんじゃ〜 #phpstudy
o0h
PRO
18
4.1k
CDKを使ったPagerDuty連携インフラのテンプレート化
shibuya_shogo
0
110
CDK開発におけるコーディング規約の運用
yamanashi_ren01
2
260
『テスト書いた方が開発が早いじゃん』を解き明かす #phpcon_nagoya
o0h
PRO
9
2.5k
苦しいTiDBへの移行を乗り越えて快適な運用を目指す
leveragestech
0
1.1k
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
Side Projects
sachag
452
42k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
650
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
A Tale of Four Properties
chriscoyier
158
23k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The Cult of Friendly URLs
andyhume
78
6.2k
Scaling GitHub
holman
459
140k
Typedesign – Prime Four
hannesfritz
40
2.5k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Optimizing for Happiness
mojombo
376
70k
Transcript
! with IB AKIBA.swift × ΤϨΧ ίʔυϨΠΞτษڧձ 1
Who is me? Kazuya Ueoka iOS application engineer in Timers
inc. Twitter: @fromkk Github: fromkk Qiita: fromkk 2
Interface Builder͋Δ͋Δ 3
Q. IBͷϑΝΠϧͱίʔυ͕ผʑͷσΟϨΫτϦʹ͍Δʁ 4
A. ಉ͡σΟϨΫτϦʹอଘ͠·͠ΐ͏ 5
Q. IB্Ͱमਖ਼ͨͣ͠ͳͷʹมߋ͕ө͞Εͳ͍? 6
A. IBͷϑΝΠϧΛमਖ਼͢ΔͷΛΊ·͠ΐ͏ جຊతʹίʔυͷมߋ͕ޙউͪ 7
Q. IBOutletআͯ͠͠·ͬͯམͪͨࣄແ͍ʁ *** Terminating app due to uncaught exception 'NSUnknownKeyException',
reason: '[<SampleWithoutIB.ViewController 0x7fe8d4e0a880> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key sampleLabel. 8
A. IB͔Β֬ೝग़དྷΔ • ! ʹͳͬͯΔ࣌ඥ͚͕͏·͍ͬͯ͘ͳ͍ • ϑΝΠϧͷཧ͕2Օॴʹͳͬͯ͠·͏ͷେม 9
Q. Πϯελϯε࡞Δ࣌ʹinitͨ͠Βམͪͨࣄແ͍ʁ 10
A. Extension࡞͙ͬͯ import UIKit protocol NibInstantiatable: class { static var
nibName: String { get } } extension NibInstantiatable where Self: UIView { static func instantiate(bundle: Bundle = Bundle.main, owner: Any? = nil, options: [AnyHashable: Any]? = nil) -> Self { return UINib(nibName: Self.nibName, bundle: bundle).instantiate(withOwner: owner, options: options).first as! Self } } protocol StoryboardInstantiatable: class { static var storyboardName: String { get } static var storyboardIdentifier: String { get } } extension StoryboardInstantiatable where Self: UIViewController { static func instantiate(bundle: Bundle = Bundle.main, identifier: String) -> Self { return UIStoryboard(name: Self.storyboardName, bundle: bundle).instantiateViewController(withIdentifier: Self.storyboardIdentifier) as! Self } } 11
Usage class HogeView: UIView, NibInstantiatable { static var nibName: String
{ return "nibName" } } let hogeView = HogeView.instantiate() 12
Q. IBϑΝΠϧͷϩʔΧϥΠζ໘ष͘ͳ͍ʁ 13
A. ༁ʹؔ͢ΔࣄLocalizable.stringʹू ࣗવͱ༁ίʔυͰରԠ͢Δࣄʹ @IBOutlet weak var sampleLabel: UILabel! { didSet
{ sampleLabel.text = NSLocalizedString("sample.label.text", comment: "ϥϕϧ") } } 14
Q. ৭ϑΥϯτΛڞ௨Ͱཧग़དྷͳ͍ 15
A. ίʔυͰ·ͱΊ͓͖ͯ·͠ΐ͏ • ਖ਼֬ʹ৭ʹؔͯ͠Xcode 9/iOS 11͔ΒColor Asset ར༻Մೳʹͳͬͨ • ԼҐޓੑΛߟ͑Δͱ·ͩ͑ͳ͍
16
৭ΛίʔυͰཧ͢Δ extension UIColor { struct MyColor { static let theme:
UIColor = #colorLiteral(red: 0.2, green: 0.2, blue: 0.2, alpha: 1) static let action: UIColor = #colorLiteral(red: 0.4, green: 0.4, blue: 0.4, alpha: 1) static let backgroundColor: UIColor = #colorLiteral(red: 0.8, green: 0.8, blue: 0.8, alpha: 1) . . . } } 17
ϑΥϯτΛίʔυͰཧ͢Δ extension UIFont { struct MyFont { private static func
font(with name: String, size: CGFloat) -> UIFont { let font = UIFont(name: name, size: size)! guard #available(iOS 11.0, *) else { return font } return UIFontMetrics.default.scaledFont(for: font) } private static func normal(with size: CGFloat) -> UIFont { return font(with: "Awesome-Font", size: size) } private static func bold(with size: CGFloat) -> UIFont { return font(with: "Awesome-Font-Bold", size: size) } static let largeTitle: UIFont = MyFont.normal(with: 34.0) static let title1: UIFont = MyFont.normal(with: 28.0) static let title2: UIFont = MyFont.normal(with: 22.0) static let title3: UIFont = MyFont.normal(with: 20.0) static let headline: UIFont = MyFont.bold(with: 17.0) static let body: UIFont = MyFont.normal(with: 17.0) static let callout: UIFont = MyFont.normal(with: 16.0) static let subheadline: UIFont = MyFont.normal(with: 15.0) static let footnote: UIFont = MyFont.normal(with: 13.0) static let caption1: UIFont = MyFont.normal(with: 12.0) static let caption2: UIFont = MyFont.normal(with: 11.0) } } 18
ଞʹ • ϑΝΠϧΛ։͍͚ͨͩͰDiff͕ൃੜͯ͠͠·͏ • PRͷ࣌ʹϨϏϡʔ͕͍͠ • Ϗϧυͯ͠ΈΔͱ৭͕ҧ͏ • etc... 19
Q. ن(ϧʔϧ)Ͱ͍͍͛ʁ 20
A. ͦͦϧʔϧগͳ͍ํ͕ྑ͍ 21
ϧʔϧഁΒΕΔҝʹ͋Δ • ਓ͕ൈ͚ͨΓೖͬͨΓͯ͠อͯΔʁ • IBͰAutoLayoutͷઃఆ͔͠͠ͳ͍ʁ • ϥϕϧͷ৭ϑΥϯτίʔυͰઃఆ͢ΔʁIBͷํָ͕͡Ό ͳ͍ʁ • ͦͷ࣌ʑͰָͳํ๏ΛબΜͩΓͯ͠ͳ͍ʁ
22
IB͑͞Θͳ͚Εߟ͑ΔࣄݮΔͷͰ 23
Interface BuilderࣺͯΑ͏ 24
1. AutoLayoutΛίʔυͰॻ͘ let sampleLabel = UILabel() sampleLabel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(sampleLabel)
NSLayoutConstraint.activate([ sampleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16.0), sampleLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0), view.trailingAnchor.constraint(equalTo: sampleLabel.trailingAnchor, constant: 16.0), view.bottomAnchor.constraint(equalTo: sampleLabel.bottomAnchor, constant: 8.0) ]) 25
σϝϦοτ͋Δ 26
Q.translatesAutoresizingMaskIntoConstraints Λॻ͖ΕΔ 27
A. ബ͍ϥούʔ࡞Ζ͏ // ఆٛ extension UIView { func addSubview(_ view:
UIView, with layouts: (UIView) -> ([NSLayoutConstraint])) { view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) NSLayoutConstraint.activate(layouts(view)) } } // ༻ addSubview(sampleLabel) { label -> [NSLayoutConstraint] in [ label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16.0), label.topAnchor.constraint(equalTo: topAnchor, constant: 8.0), trailingAnchor.constraint(equalTo: label.trailingAnchor, constant: 16.0), bottomAnchor.constraint(equalTo: label.bottomAnchor, constant: 8.0) ] } 28
Q. SafeAreaਏ͍ let top: NSLayoutConstraint if #available(iOS 11.0, *) {
top = button.topAnchor.constraint(equalTop: view.safeAreaLayoutGuide.topAnchor, constant: 16.0) } else { top = button.topAnchor.constraint(equalTop: view.topAnchor, constant: 16.0) } NSLayoutConstraint.activate([ top, button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16.0), button.widthAnchor.constraint(equalToConstant: 200.0), button.heightAnchor.constraint(equalToConstant: 48.0), ]) 29
A. ബ͍ϥούʔ࡞Ζ͏ extension UIView { struct MySafeAreaLayoutGuide { weak var
view: UIView! var topAnchor: NSLayoutYAxisAnchor { if #available(iOS 11.0, *) { return view.safeAreaLayoutGuide.topAnchor } else { return view.topAnchor } } var bottomAnchor: NSLayoutYAxisAnchor { if #available(iOS 11.0, *) { return view.safeAreaLayoutGuide.bottomAnchor } else { return view.bottomAnchor } } . . . } var myLayoutGuide: MySafeAreaLayoutGuide { return MySafeAreaLayoutGuide(view: self) } } 30
Usage NSLayoutConstraint.activate([ button.topAnchor.constraint(equalTo: view.myLayoutGuide.topAnchor), . . . ]) iOS 11ະຬΛΔ࣌ʹ
myLayoutGuide Λ safeAreaLayoutGuide ʹஔ͢Δ͚ͩͰࡁΉͷͰָ 31
Q. ϨΠΞτΛίʔυͰॻ͍͍ͯΔͱ Ͳͷը໘͔Θ͔Βͳ͘ͳͬͯ͠·͏ 32
A. ίʔυʹը໘֓ཁਤͤͯ͠·͏ 33
Diff͔Γ͍͢ 34
·ͱΊ 1.ϧʔϧΛݮΒ͢ҝʹIBࣺͯͯ͠·͍·͠ΐ͏ 2.AutoLayoutബ͍ϥούʔΛ࡞ͬͯίʔυͰॻ͘ 3.Ͳͷը໘͔͔ΓͮΒ͘ͳΔ࣌ίϝϯτΛۦ͢Δ 35
PR 1 36
37
38
39
PR 2 40
https://pre-wwdc.connpass.com/event/83343/ 41
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ 42