ios - UICollectionViewCell resizing on device rotation -
i have simple uicollectionview embedded in viewcontroller.
the uicollectionview uses auto-layout (defined in ib) take whole space in viewcontroller.
my uicollectionviewcell have same size , take whole space of uicollectionview because want 1 cell displayed in viewcontroller. uicollectionviewcell displays uiimage (which embedded in uiscrollview zooming).
it works fine except when device rotate. there's error message:
the behavior of uicollectionviewflowlayout not defined because: item height must less height of uicollectionview minus section insets top , bottom values, minus content insets top , bottom values. relevant uicollectionviewflowlayout instance , , attached ; animations = { bounds.origin=; bounds.size=; position=; }; layer = ; contentoffset: {0, 0}; contentsize: {4875, 323}> collection view layout: .
that's pretty clear, need resize uicollectionviewcell fit new height / width. after rotation uicollectionviewcell display appropriate height / width poor animation.
here's code:
@iboutlet weak var thecollectionview: uicollectionview! @iboutlet weak var theflowlayout: uicollectionviewflowlayout! override func viewdidload() { super.viewdidload() //thecollectionview.delegate = self thecollectionview.datasource = self automaticallyadjustsscrollviewinsets = false theflowlayout.itemsize = thecollectionview.frame.size theflowlayout.sectioninset = uiedgeinsetsmake(0,0,0,0) theflowlayout.minimumlinespacing = 0.0 thecollectionview.reloaddata() } override func viewwillappear(_ animated: bool) { super.viewwillappear(animated) } override func viewwilltransition(to size: cgsize, coordinator: uiviewcontrollertransitioncoordinator) { super.viewwilltransition(to: size, with: coordinator) print("\(#function) \(view.frame.size)") coordinator.animate(alongsidetransition: nil, completion: { _ in self.theflowlayout.itemsize = self.thecollectionview.frame.size }) } override func viewwilllayoutsubviews() { super.viewwilllayoutsubviews() print("\(#function) \(view.frame.size)") } override func viewdidlayoutsubviews() { super.viewdidlayoutsubviews() print("\(#function) \(view.frame.size)") }
the question is, how , when perform uicollectionviewcell change avoid warning , smooth animation?
when device rotation happens, can see following: viewwilltransition(to:with:) (375.0, 667.0) viewwilllayoutsubviews() (667.0, 375.0) viewdidlayoutsubviews() (667.0, 375.0)
the error displayed after viewdidlayoutsubviews(). have tried call theflowlayout.invalidatelayout() in viewdidlayoutsubviews() doesn't change issue.
i have read others similar questions not find answer :-(
thanks help,
sebastien
i have not found best solution @ least works.
i use viewwilltransition compute index of cell , reset offset after rotation. avoid poor animation set alpha 0 , @ beginning , 1 again @ end of animation.
viewwilllayoutsubviews used invalidated layout of uicollectionviewflowlayout , viewdidlayoutsubviews set new cell size.
maybe others if have better solution, please share it!
@iboutlet weak var thecollectionview: uicollectionview! { didset { thecollectionview.backgroundcolor = uicolor.black thecollectionview.delegate = self thecollectionview.datasource = self } } @iboutlet weak var theflowlayout: uicollectionviewflowlayout! { didset { theflowlayout.itemsize = thecollectionview.frame.size theflowlayout.sectioninset = uiedgeinsetsmake(0,0,0,0) theflowlayout.minimumlinespacing = 0.0 } } var assets:[phasset]! var startassetindex = 0 override func viewdidload() { super.viewdidload() view.backgroundcolor = uicolor.black automaticallyadjustsscrollviewinsets = false thecollectionview.reloaddata() } override func viewwillappear(_ animated: bool) { super.viewwillappear(animated) thecollectionview.scrolltoitem(at: indexpath(row:startassetindex, section:0), at: .left, animated: true) } /// resize collectionview during device rotation /// /// - parameters: /// - size: new size of viewcontroller /// - coordinator: coordinator animation override func viewwilltransition(to size: cgsize, coordinator: uiviewcontrollertransitioncoordinator) { super.viewwilltransition(to: size, with: coordinator) // compute index of image/video displayed let offset = self.thecollectionview.contentoffset; let index = round(offset.x / self.thecollectionview.bounds.size.width); // hide collection view avoid horrible animation during rotation // animation horrible due offset change thecollectionview.alpha = 0.0 coordinator.animate(alongsidetransition: nil, completion: { _ in // display collectionview during animation self.thecollectionview.alpha = 1.0 // compute new offset based on index , new size let newoffset = cgpoint(x: index * self.thecollectionview.frame.size.width, y: offset.y) self.thecollectionview.setcontentoffset(newoffset, animated: false) }) } /// invalidate layout of flowlayout, it's mandatory rotation override func viewwilllayoutsubviews() { theflowlayout.invalidatelayout() super.viewwilllayoutsubviews() } /// set size of items (mandatory rotation) override func viewdidlayoutsubviews() { super.viewdidlayoutsubviews() theflowlayout.itemsize = thecollectionview.frame.size }
Comments
Post a Comment