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
이 함수, 실패하면 어떻게 되나요? null부터 Rich Errors까지, Kotlin 에러 처리 15년
haeti2
0
110
業務時間外もAIに働いてもらう話
colorful12
3
9.7k
Press start. Python's next generation.
willingc
PRO
3
300
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.4k
仕様駆動開発の消費期限
watany
20
9.2k
Oxlintはいいぞ(続)
yug1224
1
510
私のClaude Code活用法 (個人開発編) - PHPerKaigi mini #4(2026/08/24)
panda_program
1
200
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
250
Flow は今どうなっているか
mizdra
PRO
0
820
AI駆動開発にグラフDBを重ねてみた
satoshi256kbyte
2
540
不幸な GC
chencmd
0
850
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
730
Featured
See All Featured
A Modern Web Designer's Workflow
chriscoyier
698
190k
Between Models and Reality
mayunak
4
430
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
540
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Darren the Foodie - Storyboard
khoart
PRO
3
3.8k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
230
Navigating Team Friction
lara
192
16k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
680
Facilitating Awesome Meetings
lara
57
7.1k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
510
Speed Design
sergeychernyshev
33
2.1k
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!