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
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
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
170
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.4k
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
3
370
Are APIs Still Relevant in the AI Era?
soyuka
0
300
What We Talk About When We Talk About XP
m_seki
2
680
変化を抱擁するドキュメントの作り方 - ビジネスルール駆動開発がもたらす、コードとの新しい関係
ioki
2
220
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
1
570
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
270
JRuby: Past, Present, and Future
headius
0
190
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
440
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
1
12k
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
5
4.3k
Featured
See All Featured
Producing Creativity
orderedlist
PRO
348
41k
Code Review Best Practice
trishagee
74
20k
The Language of Interfaces
destraynor
162
27k
A better future with KSS
kneath
240
18k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Facilitating Awesome Meetings
lara
57
7.1k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
940
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
460
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
480
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
Evolving SEO for Evolving Search Engines
ryanjones
0
300
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!