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
使い勝手のよいCustomViewをつくる
Search
himaratsu
October 27, 2016
Technology
0
650
使い勝手のよいCustomViewをつくる
@IBDesignable & @IBInspectable が使えて、使い勝手のよいCustomViewの作り方をまとめて紹介しました。
iOS_LT #23 で発表した資料です。
himaratsu
October 27, 2016
Tweet
Share
More Decks by himaratsu
See All by himaratsu
小さなチーム 大きな仕事 - 個人開発でAIをフル活用する
himaratsu
2
770
microCMSではじめるAIライティング
himaratsu
0
430
Next.js × microCMSで道の駅サイトを作った話
himaratsu
0
930
PayPayフリマの速度改善
himaratsu
2
370
Goodbye Code Review, Hello Pair Programming
himaratsu
0
200
UICollectionViewでインタラクティブなCellの並び替え
himaratsu
2
10k
Other Decks in Technology
See All in Technology
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
360
Ruby版 JSXのRuxが気になる
sansantech
PRO
0
170
ECS障害を例に学ぶ、インシデント対応に備えたAIエージェントの育て方 / How to develop AI agents for incident response with ECS outage
iselegant
3
290
StrandsとNeptuneを使ってナレッジグラフを構築する
yakumo
1
120
Exadata Fleet Update
oracle4engineer
PRO
0
1.1k
小さく始めるBCP ― 多プロダクト環境で始める最初の一歩
kekke_n
1
570
ランサムウェア対策としてのpnpm導入のススメ
ishikawa_satoru
0
220
SREのプラクティスを用いた3領域同時 マネジメントへの挑戦 〜SRE・情シス・セキュリティを統合した チーム運営術〜
coconala_engineer
2
770
2026年、サーバーレスの現在地 -「制約と戦う技術」から「当たり前の実行基盤」へ- /serverless2026
slsops
2
260
AI駆動開発を事業のコアに置く
tasukuonizawa
1
360
AIと新時代を切り拓く。これからのSREとメルカリIBISの挑戦
0gm
2
3.1k
Frontier Agents (Kiro autonomous agent / AWS Security Agent / AWS DevOps Agent) の紹介
msysh
3
180
Featured
See All Featured
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
71
The Curious Case for Waylosing
cassininazir
0
240
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
130
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2k
Context Engineering - Making Every Token Count
addyosmani
9
670
How to train your dragon (web standard)
notwaldorf
97
6.5k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
58
50k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
950
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.8k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
117
110k
Automating Front-end Workflow
addyosmani
1371
200k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Transcript
͍উखͷΑ͍ CustomViewΛͭ͘Δ @himara2 / iOS_LT
CustomView? ։ൃ͍ͯ͠ΔͱɺطଘͷUIViewΛ֦ுͨ͠ಠࣗͷΫϥεΛ࡞Γͨ͘ͳΔ
͍উखͷΑ͍CustomView?
- Storyboard / xib Ͱ͑Δ ͍উखͷΑ͍CustomView?
- Storyboard / xib Ͱ͑Δ ͍উखͷΑ͍CustomView? - ιʔείʔυ͔Β͑Δ let customView
= MyCustomView(frame: CGRect(x: 50, y: 100, width: 270, height: 200)) customView.titleLabel.text = "Hello!" view.addSubview(customView) ͜Μͳײ͡ͰॳظԽͯ͑͠Δ
- Storyboard / xib Ͱ͑Δ ͍উखͷΑ͍CustomView? - ιʔείʔυ͔Β͑Δ - @IBDesignable
& @IBInspectable ʹରԠ
- Storyboard / xib Ͱ͑Δ ͍উखͷΑ͍CustomView? - ιʔείʔυ͔Β͑Δ - @IBDesignable
& @IBInspectable ʹରԠ - ৭ʑͳը໘͔Β͍͍͢
- Storyboard / xib Ͱ͑Δ ͍উखͷΑ͍CustomView? - ιʔείʔυ͔Β͑Δ - @IBDesignable
& @IBInspectable ʹରԠ - ৭ʑͳը໘͔Β͍͍͢ → ͻͱඞཁͳͷͰɺखॱΛ·ͱΊ·ͨ͠
Step.1 UIViewΛܧঝͨ͠ΫϥεΛ࡞ͯ͠ɺ xibϑΝΠϧʹίϯϙʔωϯτΛฒΔ
Step.2 xibͷʮFile’s Ownerʯͷ߲ʹɺ ࣗͰͭͬͨ͘ΫϥεΛͯΔ ※ʮViewʯʹͯͳ͍ͷ͕ϙΠϯτ
Step.3 ॳظԽͷίʔυΛॻ͘ override init(frame: CGRect) { super.init(frame: frame) commonInit() }
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } private func commonInit() { let nib = UINib(nibName: "MyCustomView", bundle: nil) let view = nib.instantiate(withOwner: self, options: nil).first as! UIView addSubview(view) view.translatesAutoresizingMaskIntoConstraints = false let bindings = ["view": view] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: bindings)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: bindings)) }
Step.3 override init(frame: CGRect) { super.init(frame: frame) commonInit() } required
init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } private func commonInit() { let nib = UINib(nibName: "MyCustomView", bundle: nil) let view = nib.instantiate(withOwner: self, options: nil).first as! UIView addSubview(view) view.translatesAutoresizingMaskIntoConstraints = false let bindings = ["view": view] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: bindings)) addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: bindings)) } ॳظԽͷίʔυΛॻ͘ ίʔυ͔ΒCustomViewΛ ॳظԽͨ͠ͱ͖ݺΕΔ Storyboard/xib͔ΒCustomViewΛ ॳظԽͨ͠ͱ͖ݺΕΔ viewͷॳظԽॲཧ
Step.4 @IBDesignable, @IBInspectable ͷଐੑΛઃఆ @IBDesignable class MyCustomView: UIView { …
} @IBInspectable var titleText: String = "" { didSet { titleLabel.text = titleText } } @IBInspectable var iconImage: UIImage? { didSet { iconImageView.image = iconImage } }
!
tips ຖճviewͷॳظԽ·ΘΓͷίʔυΛॻ͘ͷπϥΠͷͰɺProtocolΛ༻ҙ͢Δͱྑ͍ protocol XibInstantiatable { func instantiate() } extension XibInstantiatable
where Self: UIView { func instantiate() { let bundle = Bundle(for: type(of: self)) let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle) guard let view = nib.instantiate(withOwner: self, options: nil).first as? UIView else { return } addSubview(view) view.translatesAutoresizingMaskIntoConstraints = false let bindings = ["view": view] addConstraints(NSLayoutConstraint.constraints(withVisualFormat: “H:|[view]|", … addConstraints(NSLayoutConstraint.constraints(withVisualFormat: “V:|[view]|", … } } override init(frame: CGRect) { super.init(frame: frame) instantiate() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) instantiate() } CustomViewଆ͔Β ͜Μͳײ͡Ͱ͏
NibDesignable ͱ͍͏ OSS ͱ͋Θͤͯ͏ͱศརʢΒ͍͠ʣ tips - Swift 3Ͱ͏·͘ϏϧυͰ͖ͣɺ·ͩࢼͤͯͳ͍ - ઌ΄ͲͷExtensionΛݞΘΓͯ͘͠ΕΔΑ͏ͳͷ
IUUQTHJUIVCDPNNCPHI/JC%FTJHOBCMF
ຊ͓ݟͤͨ͠αϯϓϧίʔυ ɹ- https://github.com/himaratsu/CustomViewSample ɹ- ࠓͷLTΛ͖͔͚ͬʹSwift 3ରԠ͠·ͨ͠✌ ੲॻ͍ͨϒϩά ɹ- http://himaratsu.hatenablog.com/entry/ios/customview ɹ-
ࠓͷΑΓ͏ͪΐͬͱৄ͘͠ॻ͍ͯ·͢ ͦͷଞ
͓ΘΓ