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.5k
dSYMのアップロードで SPMを活用する/use_spm_with_upload_dsyms
fromkk
1
2.7k
Bitriseのリモートアクセス機能 #bitrise_meetup/remote_access_of_bitrise
fromkk
1
540
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
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
240
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
890
Grafana Cloudとソラカメ
devoc
0
140
Lottieアニメーションをカスタマイズしてみた
tahia910
0
120
AHC041解説
terryu16
0
590
Java Webフレームワークの現状 / java web framework at burikaigi
kishida
9
2.2k
テストをしないQAエンジニアは何をしているか?
nealle
0
130
Amazon Bedrock Multi Agentsを試してきた
tm2
1
280
SRE、開発、QAが協業して挑んだリリースプロセス改革@SRE Kaigi 2025
nealle
3
4.1k
昭和の職場からアジャイルの世界へ
kumagoro95
1
350
【PHP】破壊的バージョンアップと戦った話〜決断と説得
satoshi256kbyte
0
120
Pulsar2 を雰囲気で使ってみよう
anoken
0
230
Featured
See All Featured
How GitHub (no longer) Works
holman
313
140k
Done Done
chrislema
182
16k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Designing for humans not robots
tammielis
250
25k
GraphQLとの向き合い方2022年版
quramy
44
13k
Optimizing for Happiness
mojombo
376
70k
Six Lessons from altMBA
skipperchong
27
3.6k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
20
2.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.1k
Building Applications with DynamoDB
mza
93
6.2k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.8k
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