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
46
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
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
120
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
250
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
250
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
990
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
技術記事、 専門家としてのプログラマ、 言語化
mizchi
13
6.6k
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
dRuby over BLE
makicamel
2
400
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
770
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
220
Agentic UI
manfredsteyer
PRO
0
200
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.5k
Featured
See All Featured
Speed Design
sergeychernyshev
33
1.9k
sira's awesome portfolio website redesign presentation
elsirapls
0
290
Paper Plane (Part 1)
katiecoart
PRO
0
9.4k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
150
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Raft: Consensus for Rubyists
vanstee
141
7.6k
How to Talk to Developers About Accessibility
jct
2
270
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
440
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!