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
20190117_iOSLT_CBLinSwift.pdf
Search
shtnkgm
January 17, 2019
Programming
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
20190117_iOSLT_CBLinSwift.pdf
Code-Based Layout in Swift
shtnkgm
January 17, 2019
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
SwiftとFunctional Reactive Programming
shtnkgm
0
200
20180710_iOSLT_iOSでDarkModeを実装する
shtnkgm
0
130
20180410_iOSLT_SwiftとProtocol-OrientedProgramming
shtnkgm
0
140
20180220_iOSLT_Swiftとオブジェクト間の通知のパターン
shtnkgm
0
170
Other Decks in Programming
See All in Programming
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
AIを上手に使っていこうとしたら越境せざるを得なくなった話 〜実践1年で見えた境界を越えなければならない理由と進め方〜 / Crossing borders with AI
tomoyakitaura
4
1.1k
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
1.6k
巨大モノリシックアプリ モダン化大作戦
ktcryomm
0
380
Security issues being discussed on Web Platforms
petamoriken
0
490
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
120
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
220
自分的「カンファレンスの楽しみ方」
syumai
0
200
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
140
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
190
RSSとCodexを使ってX投稿自動化してみた
ochtum
0
110
AIとGame Jamで、ゲームを完成させた話
takahirosaeki
0
110
Featured
See All Featured
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
380
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Evolving SEO for Evolving Search Engines
ryanjones
0
280
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
400
Fireside Chat
paigeccino
43
4k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
510
Between Models and Reality
mayunak
4
450
Faster Mobile Websites
deanohume
310
32k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Transcript
CBL in Swift Shota Nakagami
Talking about "CBL"
!
CBL Code-Based layout
I ! Code-Based Layout
How to layout ? 4 StoryBoard 4 XIB 4 Code-BasedʢProgrammaticallyʣ
Storyboard & XIB features 4 Ease of use ☺ 4
Segue ☺ 4 Visual (multi device screen size) 4 Constraint Checker ☺ 4 Non-Reusable " 4 Hard to Resolve Conflict " 4 Hard to review (XML) "
Testable? ! class ViewController: UIViewController { let dependency: Dependency //
Dependency Injection with Initializer init(dependency: Dependency) { self.dependency = dependency } } 4 NG: Storyboard ☠ no initializer... 4 OK: XIB " 4 OK: CBL "
CBL features 4 Reusable ☺ 4 Speedy ☺ 4 Easy
to Resolve Conflict ☺ 4 Easy to Review ☺ 4 Cost of Learning " 4 Non-Visual "
StoryBoard XIB Codebased ! Segue ✅ # Visual ✅ ✅
$ Compiler Check ✅ ✅ % Testable (DI) ✅ ✅ ♻ Reusable ✅ ' Less Conflict ✅ ( Reviewable ✅
6 Tips for CBL
1. Initialization Closure 2. "Then" 3. Custom View Class 4.
lazy var 5. "SnapKit" 6. UIStackView
class ViewController: UIViewController { let priceLabel = UILabel() let imageView
= UIImageView() override func viewDidLoad() { super.viewDidLoad() priceLabel.numberOfLines = 2 priceLabel.textColor = .red priceLabel.font = .boldSystemFont(ofSize: 14) imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true imageView.layer.cornerRadius = 4 // addSubview, AutoLayout... } }
messy viewDidLoad...
1. Initialization Closure
class ViewController: UIViewController { let priceLabel: UILabel = { let
label = UILabel() label.numberOfLines = 2 label.textColor = .red label.font = .boldSystemFont(ofSize: 14) return label }() let imageView: UIImageView = { let view = UIImageView() view.contentMode = .scaleAspectFill view.clipsToBounds = true view.layer.cornerRadius = 4 return view }() override func viewDidLoad() { super.viewDidLoad() // addSubview, AutoLayout... } }
viewDidLoad is clean, but...
class ViewController: UIViewController { let priceLabel: UILabel = { //
type annotation let label = UILabel() // renaming label.numberOfLines = 2 label.textColor = .red label.font = .boldSystemFont(ofSize: 14) return label // return }() let imageView: UIImageView = { // type annotation let view = UIImageView() // renaming view.contentMode = .scaleAspectFill view.clipsToBounds = true view.layer.cornerRadius = 4 return view // return }() override func viewDidLoad() { super.viewDidLoad() // addSubview, AutoLayout... } }
2. "Then" https://github.com/devxoul/Then
class ViewController: UIViewController { let priceLabel = UILabel().then { $0.numberOfLines
= 2 $0.textColor = .red $0.font = .boldSystemFont(ofSize: 14) } let imageView = UIImageView().then { $0.contentMode = .scaleAspectFill $0.clipsToBounds = true $0.layer.cornerRadius = 4 } override func viewDidLoad() { super.viewDidLoad() // addSubview, AutoLayout... } }
3. Custom View Class
class ViewController: UIViewController { let priceLabel = PriceLabel() let imageView
= ItemImageView() override func viewDidLoad() { super.viewDidLoad() } }
private let captureButton = CaptureButton().then { $0.onTapped = { [weak
self] in self?.camera.capture() } }
private let captureButton = CaptureButton().then { $0.onTapped = { [weak
self] in // Compile Error self?.camera.capture() // Compile Error } }
4. lazy var
private lazy var captureButton = CaptureButton().then { $0.onTapped = {
[weak self] in self?.camera.capture() // OK } }
Codebased AutoLayout
NSLayoutAnchor ? // addSubview, AutoLayout... view.addSubview(button) button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true button.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active
= true button.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true button.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
!
5. "SnapKit" https://github.com/SnapKit/SnapKit
view.addSubview(button) // button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true // button.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true //
button.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true // button.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true button.snp.makeConstraints { $0.edges.equalToSuperview() }
// readable button.snp.makeConstraints { $0.center.equalToSuperview() $0.size.equalTo(CGSize(width: 64, height: 64)) }
// Support Safe Area tableView.snp.makeConstraints { $0.top.bottom.equalTo(view.safeAreaLayoutGuide) $0.leading.trailing.equalToSuperview() }
6. UIStackView
UIStackView = Stack "Layouted" View Less Constraints ! stackView.addArrangedSubview(label) stackView.addArrangedSubview(imageView)
stackView.addArrangedSubview(button) label.snp.makeConstraints { $0.height.equalTo(20) } button.snp.makeConstraints { $0.height.equalTo(60) }
Summary
CBL: Code-Based layout 4 Testable, Speedy, and Reusable 4 Use
"6 Tips" to clean code When to Use 4 Use CBL for simple layout 4 Use XIB for complicated layout 4 Use StoryBoard for segue