Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
CollectionViewの 新しいレイアウトの作り方
ry-itto
November 02, 2019
Programming
0
37
CollectionViewの 新しいレイアウトの作り方
ry-itto
November 02, 2019
Tweet
Share
More Decks by ry-itto
See All by ry-itto
CA.swift#14
ryitto
3
2.5k
swift-argument-parserで 簡単 CLI ツール作り
ryitto
1
50
Data Essentials in SwiftUI
ryitto
1
300
Composable Architecture
ryitto
0
490
Swift5.1 SwiftUI
ryitto
0
96
Other Decks in Programming
See All in Programming
How GitHub Supports Vim License Detection, The Five Years Journey
othree
1
370
パスワードに関する最近の動向
kenchan0130
1
330
Rに管理されてみる
kazutan
0
260
回帰分析ではlm()ではなくestimatr::lm_robust()を使おう / TokyoR100
dropout009
0
4.5k
モデルの定義に基づくバリデーションを実現するためのpydantic入門
daikikatsuragawa
0
120
設計の考え方とやり方
masuda220
PRO
54
30k
Amazon SageMakerでImagenを動かして猫画像生成してみた
hotoke_neko
0
110
kintone × LINE Bot で餃子検定Botを作った話
naberina
0
330
Regular expressions basics/正規表現の基本
kishikawakatsumi
6
260
Google IO 2022 社内LT会 / What's new in Android development tools
shingo_kobayashi
0
410
RustのWebフレームワーク周りの概観
hayao
0
180
サーバーレスパターンから学ぶデータ分析基盤構築 / devio2022
kasacchiful
0
490
Featured
See All Featured
Music & Morning Musume
bryan
35
4.3k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
Creatively Recalculating Your Daily Design Routine
revolveconf
207
10k
GraphQLの誤解/rethinking-graphql
sonatard
31
6.8k
What's new in Ruby 2.0
geeforr
335
30k
Fontdeck: Realign not Redesign
paulrobertlloyd
73
4.1k
Thoughts on Productivity
jonyablonski
44
2.4k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
655
120k
Imperfection Machines: The Place of Print at Facebook
scottboms
253
12k
Building Better People: How to give real-time feedback that sticks.
wjessup
344
17k
VelocityConf: Rendering Performance Case Studies
addyosmani
316
22k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
39
13k
Transcript
CollectionViewͷ ৽͍͠ϨΠΞτͷ࡞Γํ ձେֶֶ෦3ɹҏ౻྇
ࣗݾհ • ҏ౻྇ • ΧϐόϥѪ • iOSΤϯδχΞ • ͚ͭ໙େ͖
CollectionViewͱʁ “UICollectionView is a flexible, powerful tool to help you
achieve great user experiences in your applications.” –WWDC2018 A Tour of UICollectionView https://developer.apple.com/videos/play/wwdc2018/225/
͜Μͳը໘Λදݱ͢ΔͨΊʹ͏
iOS13Ͱ৽͘͠Ճ͞Εͨ CollectionViewपΓͷAPI • Compositional Layouts • DiffableDataSource
iOS13Ͱ৽͘͠Ճ͞Εͨ CollectionViewपΓͷAPI • Compositional Layouts • DiffableDataSource
Compositional Layouts • Item • Group • Section • Layout
ͷ4߲ͰCollectionViewͷϨΠΞτΛߏ͢Δ 88%$"EWBODFTJO$PMMFDUJPO7JFX-BZPVU TMJEF ˞ ˞ IUUQTEFWFMPQFSBQQMFDPNWJEFPTQMBZXXED
Compositional Layoutsͷ ੜ·Εͨཧ༝ʢલஔ͖ʣ • ࡢࠓͷΞϓϦͷUIෳࡶʹͳ͖͍ͬͯͯΔ • ैདྷͷFlowLayoutΛͬͨϨΠΞτߏͩͱ ͔ͳΓෳࡶͳίʔυʹͳͬͯ͠·͏ • ύϑΥʔϚϯε໘Λߟ͑ͳ͕ΒUIΛߏ͢Δඞཁ
͕͋ͬͨ
Compositional Layoutsͷ ࡾຊͷப • ComposableʢߏՄೳʣ γϯϓϧͳίʔυͰෳࡶͳUI͕࡞ΕΔ • Flexibleʢॊೈʣ ෳࡶͳUI͕࡞ΕΔ •
Fastʢૣ͍ʣ ύϑΥʔϚϯεʹྀ͠ͳͯ͘ྑ͍
σϞ, ίʔυ
αϯϓϧΞϓϦ ηΫγϣϯ͕ෳ͋ͬ ͯͦΕͧΕͷηΫγϣ ϯ͕10ݸ΄ͲͷཁૉΛ ͍࣋ͬͯΔ εΫϩʔϧ͢Δ
ैདྷͷFlowLayout Λ༻ͨ͠߹
࣮ํ େݩͷ $PMMFDUJPO7JFX ʢ5BCMF7JFXͰՄʣ େݩͷ $PMMFDUJPO7JFXͷηϧ ࢠͷ$PMMFDUJPO7JFX ࢠͷ$PMMFDUJPO7JFXͷηϧ
େݩͷCollectionView class LegacyViewController: UIViewController { func configureHierarchy() { collectionView.register(CollectionCell.self, forCellWithReuseIdentifier:
CollectionCell.reuseIdentifier) ɹɹɹ collectionView.collectionViewLayout = createLayout() } func createLayout() -> UICollectionViewLayout { let layout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: view.bounds.width, height: view.bounds.height * 0.3) return layout } } extension LegacyViewController: UICollectionViewDataSource { } ηϧΛొɾϨΠΞτΛηοτ
ࢠͷCollectionView class SectionCollectionView: UICollectionView { override init(frame: CGRect, collectionViewLayout layout:
UICollectionViewLayout) { super.init(frame: frame, collectionViewLayout: layout) self.collectionViewLayout = createLayout() self.register(TextCell.self, forCellWithReuseIdentifier: TextCell.reuseIdentifier) self.contentInset = .init(top: 20, left: 20, bottom: 20, right: 20) } func createLayout() -> UICollectionViewLayout { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontalɹ/// εΫϩʔϧͷ͖Λԣ͖ʹ͢Δ layout.itemSize = CGSize(width: self.frame.width / 2, height: self.bounds.height - 40) return layout } } extension SectionCollectionView: UICollectionViewDataSource { }
େݩͷCollectionViewͷηϧ class CollectionCell: UICollectionViewCell { static let reuseIdentifier = "collectionCell"
var collectionView: SectionCollectionView! override init(frame: CGRect) { super.init(frame: frame) configure() } func configure() { self.collectionView = SectionCollectionView(frame: self.bounds, collectionViewLayout: .init()) contentView.addSubview(collectionView) collectionView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), collectionView.topAnchor.constraint(equalTo: contentView.topAnchor), collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) self.collectionView.backgroundColor = .white } } ηϧʹ$PMMFDUJPO7JFXΛηοτ
ࢠͷCollectionViewͷηϧ class TextCell: UICollectionViewCell { let label = UILabel() override
init(frame: CGRect) { super.init(frame: frame) configure() } } extension TextCell { func configure() { label.translatesAutoresizingMaskIntoConstraints = false label.adjustsFontForContentSizeCategory = true contentView.addSubview(label) label.font = UIFont.preferredFont(forTextStyle: .caption1) ... } }
ैདྷͷํ๏ͰαϯϓϧΞϓϦͷ UIΛ࡞͢ΔͨΊʹ ωετͨ͠CollectionView͕ඞཁ ίʔυ͕ଟ͘ͳΓɺ͔ͭߏ͕௫Έʹ͍͘
Compositional LayoutsΛ ༻ͨ͠߹
࣮ํ $PMMFDUJPO7JFX $PMMFDUJPO7JFXͷηϧ
CollectionView class ViewController: UIViewController { var collectionView: UICollectionView! override func
viewDidLoad() { super.viewDidLoad() configureHierarchy() } func configureHierarchy() { collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: createLayout()) collectionView.register(TextCell.self, forCellWithReuseIdentifier: TextCell.reuseIdentifier) collectionView.dataSource = self view.addSubview(collectionView) } func createLayout() -> UICollectionViewLayout { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1.0)) let item = NSCollectionLayoutItem(layoutSize: itemSize) item.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(0.3)) let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) let section = NSCollectionLayoutSection(group: group) section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20) section.orthogonalScrollingBehavior = .continuous let layout = UICollectionViewCompositionalLayout(section: section) return layout } }
CollectionViewͷηϧ class TextCell: UICollectionViewCell { let label = UILabel() override
init(frame: CGRect) { super.init(frame: frame) configure() } } extension TextCell { func configure() { label.translatesAutoresizingMaskIntoConstraints = false label.adjustsFontForContentSizeCategory = true contentView.addSubview(label) label.font = UIFont.preferredFont(forTextStyle: .caption1) ... } }
Compositional Layouts Λ ༻͢Δ͜ͱͰ̍ͭͷCollectionView Ͱදݱ͢Δ͜ͱ͕Մೳʹͳͬͨ
·ͱΊ • Compositional LayoutsΛ͏͜ͱͰࠓ·Ͱ͔ͬͨ͠ UIͷදݱ͕؆୯ʹͰ͖Δ • ࠷ۙॳΊͯiOSΞϓϦ։ൃΛ࢝ΊͨͬͯਓʹΦεεϝ ※ iOS13Ҏ߱Ͱ͔͑͠ͳ͍ͷʹҙ
ࢀߟͳͲ • ࠓճͷαϯϓϧΞϓϦͷϦϙδτϦ https://github.com/ry-itto/CompositionalLayoutsSample • Advances in Collection View Layout(ηογϣϯ)
https://developer.apple.com/videos/play/wwdc2019/215/ • ࣌ͷมԽʹԠͯ͡ਐԽ͢ΔCollectionView ~Compositional LayoutsͱDiffable Data Sources~ https://qiita.com/shiz/items/a6032543a237bf2e1d19
͋Γ͕ͱ͏͍͟͝·ͨ͠