ios - UICollectionView Self Sizing Cells with Auto Layout -


i'm trying self sizing uicollectionviewcells working auto layout, can't seem cells size content. i'm having trouble understanding how cell's size updated contents of what's inside cell's contentview.

here's setup i've tried:

  • custom uicollectionviewcell uitextview in contentview.
  • scrolling uitextview disabled.
  • the contentview's horizontal constraint is: "h:|[_textview(320)]", i.e. uitextview pinned left of cell explicit width of 320.
  • the contentview's vertical constraint is: "v:|-0-[_textview]", i.e. uitextview pinned top of cell.
  • the uitextview has height constraint set constant uitextview reports fit text.

here's looks cell background set red, , uitextview background set blue: cell background red, uitextview background blue

i put project i've been playing on github here.

updated ios 9

after seeing github solution break under ios 9 got time investigate issue fully. have updated repo include several examples of different configurations self sizing cells. conclusion self sizing cells great in theory messy in practice. word of caution when proceeding self sizing cells.

tl;dr

check out github project


self sizing cells supported flow layout make sure thats using.

there 2 things need setup self sizing cells work.

1. set estimateditemsize on uicollectionviewflowlayout

flow layout become dynamic in nature once set estimateditemsize property.

self.flowlayout.estimateditemsize = cgsize(width: 100, height: 100) 

2. add support sizing on cell subclass

this comes in 2 flavours; auto-layout or custom override of preferredlayoutattributesfittingattributes.

create , configure cell's auto layout

i won't go in detail there's brilliant so post configuring constraints cell. wary xcode 6 broke bunch of stuff ios 7 so, if support ios 7, need stuff ensure autoresizingmask set on cell's contentview , contentview's bounds set cell's bounds when cell loaded (i.e. awakefromnib).

things need aware of cell needs more constrained table view cell. instance, if want width dynamic cell needs height constraint. likewise, if want height dynamic need width constraint cell.

implement preferredlayoutattributesfittingattributes in custom cell

when function called view has been configured content (i.e. cellforitem has been called). assuming constraints have been appropriately set have implementation this:

//forces system 1 layout pass var isheightcalculated: bool = false  override func preferredlayoutattributesfittingattributes(_ layoutattributes: uicollectionviewlayoutattributes) -> uicollectionviewlayoutattributes {     //exhibit - need cache our calculation prevent crash.     if !isheightcalculated {         setneedslayout()         layoutifneeded()         let size = contentview.systemlayoutsizefittingsize(layoutattributes.size)         var newframe = layoutattributes.frame         newframe.size.width = cgfloat(ceilf(float(size.width)))         layoutattributes.frame = newframe         isheightcalculated = true     }     return layoutattributes } 

note on ios 9 behaviour changed bit cause crashes on implementation if not careful (see more here). when implement preferredlayoutattributesfittingattributes need ensure change frame of layout attributes once. if don't layout call implementation indefinitely , crash. 1 solution cache calculated size in cell , invalidate anytime reuse cell or change content have done isheightcalculated property.

experience layout

at point should have 'functioning' dynamic cells in collectionview. haven't yet found out-of-the box solution sufficient during tests feel free comment if have. still feels uitableview wins battle dynamic sizing imho.

caveats

be mindful if using prototype cells calculate estimateditemsize - break if xib uses size classes. reason when load cell xib size class configured undefined. broken on ios 8 , since on ios 7 size class loaded based on device (ipad = regular-any, iphone = compact-any). can either set estimateditemsize without loading xib, or can load cell xib, add collectionview (this set traitcollection), perform layout, , remove superview. alternatively make cell override traitcollection getter , return appropriate traits. it's you.

let me know if missed anything, hope helped , luck coding



Comments

Popular posts from this blog

node.js - ldapjs - write after end error -

DOM Manipulation in Wordpress (and elsewhere) using php -