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
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
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.2k
dSYMのアップロードで SPMを活用する/use_spm_with_upload_dsyms
fromkk
1
3.2k
Bitriseのリモートアクセス機能 #bitrise_meetup/remote_access_of_bitrise
fromkk
1
700
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
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
520
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
360
App Intentsのビルドプロセスを支える技術
kntkymt
0
220
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
150
テストを司るデーモンに会いに行く 〜隔離した仮想マシンでテストを通すまで〜
h1d3mun3
1
120
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
120
Foundry Localでエージェント開発
seosoft
0
170
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
600
What We Talk About When We Talk About XP
m_seki
2
470
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
190
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
130
Featured
See All Featured
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
420
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
30 Presentation Tips
portentint
PRO
1
390
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
540
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
280
How to Talk to Developers About Accessibility
jct
2
540
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
590
Utilizing Notion as your number one productivity tool
mfonobong
4
580
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
570
How GitHub (no longer) Works
holman
316
150k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
520
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
240
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