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
iOS 上 self-sizing cell 的過去、現在、與未來
Search
Jeff Lin
November 08, 2016
Programming
49
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
iOS 上 self-sizing cell 的過去、現在、與未來
2016 mopcon session
Jeff Lin
November 08, 2016
Other Decks in Programming
See All in Programming
Foundation Models frameworkで画像分析
ryodeveloper
1
610
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
230
仕様書を書く前にハーネスを作る - Agent Native開発は「探索を速く、判定を固く」
gotalab555
4
1.6k
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
700
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
150
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
440
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
500
運用ダッシュボードの設計を誰も教えてくれないのだけどみなさんどうしてるんですか? - チームに監視するという文化を根付かせるための第一歩を踏みたい -
satoshi256kbyte
1
120
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
560
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
140
これって Effect でできたのでは? / TSKaigi Mashup Kansai #2
susisu
0
240
変わらないものが、変わるものを決める — 意図駆動開発 × イベントソーシング × イミュータブル | What Doesn't Change Decides What Can — IDD × Event Sourcing × Immutability
tomohisa
0
1.6k
Featured
See All Featured
Become a Pro
speakerdeck
PRO
31
6.2k
Faster Mobile Websites
deanohume
310
32k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
270
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
A designer walks into a library…
pauljervisheath
211
24k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
480
Odyssey Design
rkendrick25
PRO
2
750
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.7k
[SF Ruby Conf 2025] Rails X
palkan
2
1.3k
BBQ
matthewcrist
89
10k
Transcript
iOS Ӥ self-sizing cell ጱ螂݄牏 匍ࣁ牏膏๚㬵 ฏਡ(Jeff Lin)
ፘ橕捍纷 • Yahoo 樄რ樄咳ॺկ AppDevKit - 樄咳ᑃ蜢膏 ۑ胼獤Ձ-ਟப痷(Anistar) • https://github.com/yahoo/AppDevKit
• ᤈᘏ – iOS BDD ᛔ㵕介手礍-磷ܮᄪ(qcl) • https://github.com/qcl/zizhi
About me • YAHOO App Engineer • 㷢膏珶उ牏ೌ搚iOS App樄咳牧ፓ獮揗揣搳ᇔӾஞ •
AppDevKit 樄რ懯向
Agenda • Ջ讕ฎSelf-sizing牫 • ݱ圵Self-sizing薹ဩ膏穉斃 • Xcode 8盅蝽کጱ㺔氂
Self-sizingአࣁߺ牫
ྯ㳷獉裾ଶ犋嘦ਧ
ྯ㳷獉裾ଶ犋嘦ਧ
獉ݢ胼氥纈/褲萢
獉ݢ胼氥纈/褲萢
Expandable cell
㵕眲ਁ羷 • iOS dynamic type • UIFont.preferredFontForTex tStyle:
㵕眲ਁ羷
向ᶎزկ䯤౮ • ਁ牏瑽粙物 • UIImageView, UILabel, UITextView… • Container物 •
UITableView, UICollectionView • 䋿֢物 • storyboard, xib, 纷ୗ嘨䌃constraint
Layout 㻌奈ਁ 瑽ṛ犋段ਁ 瑽ṛ段ਁ
Self-sizingெ讕狶?
ᓒ! • 磧ፗ矑牧֕磪碻玱ᘒݢ犥薹究auto self-sizing蒂ቘ犋㬵ጱ 㺔氂
ெ讕ᓒ牫 • NSString • sizeWithAttributes • boundingRectWithSize:options:attributes:context: • UILabel •
sizeToFit: • UIScrollView/UITextView • contentSize
Ӟ犚ᥝੜஞጱ瑿ො • کጱsizeݢ胼ࢩ傶ੜ碍讨磪藮癩牧አceil()狕ྋ • sizeToFit:䨝ፗ矑硬虋frame牧磪ݢ胼Ꮘ瓥 constraint牧碚蟳ֵአ
UITextView contentSize • sizeForItemAtIndexPath: • ࢧ㯽textView.ContentSize
櫞螇iOS䷱蒂ቘ蝡կԪ?
UITableview self sizing • 磪ݢ胼矦ᤈጱUILabel戔ਧnumberOfLines = 0 • 獵ӥ疰ฎAutoLayoutጱԪԧ self.tableView?.rowHeight
= UITableViewAutomaticDimension self.tableView?.estimatedRowHeight = 100
That’s all!
UITableview self sizing • ฃ䋿֢ • 螕አࢴਧڜ蔭ୗጱlayout
UICollectionView • Grid view, ፘ罏 • ੜܜ粙/य़ܜ粙牧ֵአᘏ ݢ螡䢔layout • 犖ݢ犥螕አෝ礿ڜୗ獉
UICollectionView self-sizing
ෝฎ۱౮ԧAppDevKit • UICollectionViewCell • subclass ADKTableViewDynamicSizeCell/ ADKCollectionViewDynamicSizeCell • 戔অಅ磪嘦ਧጱ璎ፗ constraint
• collectionView:layout:sizeForItemAtIndexPath: • ℂADKNibCacheManager೭ڊcell虻碘ऴ蝱݄ • 㯽獈cell懯ጱय़ੜ牧ᓒڊṛ
AppDevKit Solution
AppDevKit Solution collectionView:layout:sizeForItemAtIndexPath: 1. 叨ኞcellአ㬵ऴ獈虻碘 let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName")
as! String? let cell = ADKSWNibCacheManager.sharedInstance().instance( className: appName?.appending(".\ (SSSmallCardCollectionViewCell.self)")) as! SSSmallCardCollectionViewCell
AppDevKit Solution 2.妔ਧ疝ଶ现ڡྍጱṛଶ牧伛猋盅媲懯ᓒ let preferSize = CGSize.init(width: collectionView.frame.size.width / 2.0
- 10, height: 100.0) cell.frame = CGRect.init(origin: .zero, size: preferSize) 3.ݞlayoutIfNeeded虏constraint咳䠁֢አ cell.contentView.layoutIfNeeded()
AppDevKit Solution 4.秇硈ऴ獈虻碘 func setup(cell: SSSmallCardCollectionViewCell, indexPath: IndexPath) { let
productInfo = self.products[indexPath.row] cell.contentView.layoutIfNeeded() cell.titleLabel?.text = productInfo.productTitle ... }
AppDevKit Solution 5.ᓒڊṛ牦 let size = ADKCellDynamicSizeCalculator.sharedInstance().size (forDynamicHeightCellInstance: cell, preferredSize:
preferSize) return size
Sample Code @objc(collectionView:layout:sizeForItemAtIndexPath:) func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize { // 1. 叨ኞcellአ㬵ऴ獈虻碘 let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String? let cell = ADKSWNibCacheManager.sharedInstance().instance(className: appName?.appending(".\(SSSmallCardCollectionViewCell.self)")) as! SSSmallCardCollectionViewCell // 2. 妔ਧ疝ଶ现ڡྍጱṛଶ牧伛猋盅媲懯ᓒ let preferSize = CGSize.init(width: collectionView.frame.size.width / 2.0 - 10, height: 100.0) cell.frame = CGRect.init(origin: .zero, size: preferSize) // 3.ڥአlayoutIfNeeded虏constraint咳䠁֢አ cell.contentView.layoutIfNeeded() // 4.秇硈ऴ獈虻碘 setup(cell: cell, indexPath: indexPath) // 5.ᓒڊṛ牦 let size = ADKCellDynamicSizeCalculator.sharedInstance().size(forDynamicHeightCellInstance: cell, preferredSize: CGSize.init(width: collectionView.frame.size.width / 2.0 - 10, height: 0.0)) return size }
Recap 1. 叨ኞcellአ㬵ऴ獈虻碘 2. 妔ਧ疝ଶ现ڡྍጱṛଶ牧 伛猋盅媲懯ᓒ 3. ڥአlayoutIfNeeded虏 constraint咳䠁֢አ 4.
秇硈ऴ獈虻碘 5. ᓒڊṛ牦 ImageView Title Description Price
Recap 1. 叨ኞcellአ㬵ऴ獈虻碘 2. 妔ਧ疝ଶ现ڡྍጱṛଶ牧 伛猋盅媲懯ᓒ 3. ڥአlayoutIfNeeded虏 constraint咳䠁֢አ 4.
秇硈ऴ獈虻碘 5. ᓒڊṛ牦 ImageView Title Description Price
Recap 1. 叨ኞcellአ㬵ऴ獈虻碘 2. 妔ਧ疝ଶ现ڡྍጱṛଶ牧 伛猋盅媲懯ᓒ 3. ڥአlayoutIfNeeded虏 constraint咳䠁֢አ 4.
秇硈ऴ獈虻碘 5. ᓒڊṛ牦 ImageView Title Description Price
Recap 1. 叨ኞcellአ㬵ऴ獈虻碘 2. 妔ਧ疝ଶ现ڡྍጱṛଶ牧 伛猋盅媲懯ᓒ 3. ڥአlayoutIfNeeded虏 constraint咳䠁֢አ 4.
秇硈ऴ獈虻碘 5. ᓒڊṛ牦 ImageView Title Description Price ImageView SO NICE᮷䨝 ᮷䨝菠妟೪矑朼 $ 790
ImageView SO NICE᮷䨝 ᮷䨝菠妟೪矑朼 790 Recap 1. 叨ኞcellአ㬵ऴ獈虻碘 2. 妔ਧ疝ଶ现ڡྍጱṛଶ牧
伛猋盅媲懯ᓒ 3. ڥአlayoutIfNeeded虏 constraint咳䠁֢አ 4. 秇硈ऴ獈虻碘 5. ᓒڊṛ牦 ImageView SO NICE᮷䨝 ᮷䨝菠妟೪矑朼 $ 790 SO NICE᮷䨝 菠妟೪矑朼而Ӥ 蔬 ᮷䨝菠妟೪矑朼 而Ӥ蔬 蝚憙櫕 䍅翕菥奋,吖 搡೪矑朼而Ӥ 蔬牐 狐讀ူ讨 玢臺牏缏誢菠妟 蕕觽ᤥ,猻褷碻 牐
AppDevKit Solution ADKCellDynamicSizeCalculator.sharedInsta nce().size(forDynamicHeightCellInstance: cell, preferredSize: CGSize.init(width: collectionView.frame.size.width / 2.0
- 10, height: 0.0)) 磭Ӟ皰ੜܜฎ蓦癷疝ጱӞ牧樌蚣傶10px
How AppDevKit works? • ᛔ㵕懯ᓒ CGSize resultSize = [contentView systemLayoutSizeFittingSize:UILayoutFittingCompr
essedSize]; resultSize.width = preferredSize.width; resultSize.height = MAX(resultSize.height, preferredSize.height); 疝ݢ胼ॡय़ ṛݢ胼襑ᥝ婘ੜ
systemLayoutSizeFittingSize • UILayoutFittingCompressedSize • 礬硁viewጱconstraints礿կᓒڊ螕ݳጱ磧ੜsize • UILayoutFittingExpandedSize • 礬硁viewጱconstraints礿կᓒڊ螕ݳጱ磧य़size
layoutIfNeeds • layoutIfNeeds • 獮کreloadDataਠ౮ጱcontentSize • Animate autoLayout
獮کcontentSize // contentSize: {0, 0} collectionView.dataSource = self.delegator // contentSize:
{0, 0} collectionView.reloadData() // contentSize: {0, 0} collectionView.layoutIfNeeded // contentSize: {375, 2557.5}
layoutIfNeeds-Animation viewForAnimate.someConstraint.constanst = 0.0 UIView.animate(withDuration: 0.3) { viewForAnimate.layoutIfNeeded() } UIView.animate(withDuration:
0.3) { viewForAnimate.frame = CGRect.init(origin: .zero, size: CGSize.init(width: 100, height: 100)) } Frame base layout Constraint Autolayout
櫞螇iOS䷱蒂ቘ蝡կԪ?
ᛔᤈ妔ਧྯ㮆cellጱ疝ṛ • collectionView:layout:sizeForItemAtIndexPath: • Customized UICollectionViewLayout
estimatedItemSize
estimatedItemSize • iOS 8 above • UICollectionViewFlowLayout • estimatedItemSize •
UICollectionViewCell • preferredLayoutAttributesFittingAttributes
estimatedItemSize • 觊犲UITableViewጱestimatedRowHeight • UICollectionViewFlowLayout flowLayout.estimatedItemSize = CGSize.init(width: UIScreen.main.bounds.size.width /
2 - 20, height: 100)
Sample Code func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { self.contentView.layoutIfNeeded()
layoutAttributes.frame.size.height = systemLayoutSizeFitting(UILayoutFittingCompressedSi ze).height layoutAttributes.frame.size.width = self.bounds.size.width return layoutAttributes }
蝽کጱ獋㮆㺔氂 • ᆙclass referenceୌ捍ݞ super.preferredLayoutAttributesFitting(layoutAttributes) • newLayoutAttributes೭کsize 1000x1000 • iOS
10 self.contentView.layoutIfNeeded()
Ӟ犚ݢ犥ኸጱԪ • 戔ਧԧestimatedItemSize疰䨝藉咳cellጱ preferredLayoutAttributesFitting • estimatedItemSize䨝ኼ螂sizeForItemAtIndexPath ጱ奾ຎ
preferredLayoutAttributesFittingA ttributes
preferredLayoutAttributesFittingA ttributes • ݝ磪ਁ᮷অঅጱ • 磪瑽戔ਧṛ犖অঅጱ • 磪瑽+穉ֺ...
ெ讕旰牫 • 毆ض戔অӞ礿瑽粙ṛ constraint • ݢࣁwillDisplayCell֢皨 蝱ᤈ藲碉 • ADKSetConstraintConsta nt:forAttribute:
can help!
螭䷱薹究ጱ㺔氂 • ग़圵cell窾ݳ珌牫֕ estimatedItemSize䌘虡ฎ碉 㮆flowLayout • 螭ฎࢧکአ collectionView:layout:sizeFo rItemAtIndexPath:薹究މ
Expandable cell • 獋圵䋿֢ොୗ • estimatedItemSize+invalidLayout +UIViewAnimation • sizeForCellAtIndexPath+performBatchUpdate:
ੜ奾 • TableView • estimatedRowHeightܨݢ薹究य़蟂獤ጱ制丆 • CollectionView • 㻌Ӟ圵ጱcellአestimatedItemSize螭䄪አ牧݈犋櫞䌃 •
斃֯薹物sizeForItemAtIndexPath牧֕ᥝ臺讨ێ穥 • 螭篷ဩ笕᪃牫ݝ磪Custom flowLayoutԧ • AppDevKit might help for nib!
Xcode 8 & iOS 10
self-sizing in iOS 10 • WWDC 216 What's New in
UICollectionView in iOS 10 • ፓ獮螭手犋ڊྋ嘦ጱֵአොୗ flowLayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
xib in Xcode 8
xib in Xcode 8 • xibӾزկ磪constraint疰䷱磪frameፘ橕ጱ戔ਧ • init褩ྦྷݢ胼玲ک梊ጱframeጱ独 • Update:Xcode
8.1ےࢧ㬵ԧ
Frame size1000!
xib in Xcode 8 NSLayoutConstraint(item: star, attribute: .height, relatedBy: .equal,
toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: self.frame.height).isActive = true; ᘉ౮ጮ扖物̣ጱṛଶ戔ਧӤ䍅 ጱṛ”独”Ӟ䰬
1000x1000 star!
Solution • ̣ ṛଶፘ缛oṛ䌘Ӥӥ螲ኴ傶0 NSLayoutConstraint(item: star, attribute: .height, relatedBy: .equal,
toItem: self, attribute: .height, multiplier: 1.0, constant: 0.0).isActive = true;
xib戔獋ᤈጱṛଶᤩ㳫ധԧ Xcode 7 Xcode 8
ԧ獋ᤈṛඪ砤 ݈ԧӞ礿constraint...
ྋ嘦ጱ薹究ොဩ • 愆᪃扗磪ጱauto layout constraint戔ਧ • ᓒṛ獮嘦狒contentViewय़ੜྋ嘦ٚ layoutIfNeeded • 螕吚戔ਧpreferredMaxLayoutWidth藉咳矦ᤈ
অৼ犋ᥝ䋊
Ӟ犚狕ྋୌ捍 • 疰吚֢xibӤጱ፡کጱṛጱ犋ਂࣁ • sizeӞፗᓒ梊ጱ扖牧䲒礚ฎ犋ฎԧconstraint • constraint螨عֵአself.frame.sizeጱ独
ԧconstraintࡂ...
Self-sizing checklist • estimatedItemSize • 懿䋿֢cellӾጱ preferredLayoutAttributesFittingAttributes • 嘦ਧ覍self-sizingጱconstraint䷱磪笙ധ
Self-sizing checklist • sizeForItemAtIndexPath: ᓒṛ獮 • 蝚螂虻碘ऴ獈cache cell • 纷ୗ嘨䌃constraintᥝኸframe戔౮毆懯य़ੜ
• 嘦ਧ覍self-sizingጱconstraint䷱磪笙ധ • ADKNibSizeCalculator & ADKCellDynamicSizeCalculator can help!
犥现… • 嘦ਧ覍self-sizingጱconstraint䷱磪笙ധ • 瑽粙ೲ穉ֺ戔ݢ胼蝨౮ጱ㺔氂(ੜܜ) • 螕吚戔ਧpreferredMaxLayoutWidth
Thank you!