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
🤔 with IB/thinking_with_interface_builder
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
fromkk
March 28, 2018
Programming
4.1k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
🤔 with IB/thinking_with_interface_builder
2018/03/28にエウレカ様で開催されたAKIBA.swift × エウレカ コードレイアウト勉強会で発表した内容です。
fromkk
March 28, 2018
More Decks by fromkk
See All by fromkk
note社の全員野球で品質向上活動について / note_qa_challenge #iOS_test_teatime
fromkk
3
2.1k
1年分のデータが見たいと言われてやったこと/yearly_data_with_note
fromkk
0
1.1k
note iOSチームの自動化 ver.2021/automation_with_iOS_team_on_note_ver2021
fromkk
0
2.1k
Bitrise体験会説明資料/bitrise_explore
fromkk
1
1.2k
noteのiOSアプリで実装したアクセシビリティの全て #iosdc #a /a11y_with_iOS_App_on_note
fromkk
2
5.4k
dSYMのアップロードで SPMを活用する/use_spm_with_upload_dsyms
fromkk
1
3.3k
Bitriseのリモートアクセス機能 #bitrise_meetup/remote_access_of_bitrise
fromkk
1
710
note社でのMagic Pod活用事例 #af_iosdc/magicpod_with_note
fromkk
2
12k
iOSには無いmacOS独自機能をCatalystで実装する #iosdc #d/make_macos_apps_with_catalyst
fromkk
9
2.3k
Other Decks in Programming
See All in Programming
Optunaを作ったときにやりたかったこと、その後 (2026/10/16, Optuna Meetup #3)
iwiwi
4
1.4k
SODA - FACT BOOK(JP)
sodainc
1
40k
Crash Auto Pipelines
veronikapj
1
340
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
270
8年前のNode.jsを動かして分かった、npm installの裏側
keisukeikeda
0
130
Spec-Driven Development - Why Vaadin Is the Perfect Fit
simas
PRO
0
210
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
1.4k
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
400
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
190
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
6.3k
オーケストレーション記述言語 Katari
yukikurage
0
220
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
130
Featured
See All Featured
エンジニアに許された特別な時間の終わり
watany
109
250k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
480
Designing for humans not robots
tammielis
254
26k
Embracing the Ebb and Flow
colly
88
5.2k
So, you think you're a good person
axbom
PRO
2
2.2k
The browser strikes back
jonoalderson
0
1.9k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
470
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Prompt Engineering for Job Search
mfonobong
0
570
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.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