tylerlantern
tylerlantern

Reputation: 85

layout in UICollectionViewCel looks odd when perform setCollectionViewLayout

I have two nib files which are RowRecordLayout and ColumnLayout respectively. enter image description here enter image description here

I do register the nib cells to UICollectionView for be used later in cellForItemAtIndexPath function. Here is my code

 override func viewDidLoad() {
 self.DJCollectionView.registerNib(UINib(nibName: "RowTemplateCell", bundle: NSBundle.mainBundle()), forCellWithReuseIdentifier: "DJCELL")
        self.DJCollectionView.registerNib(UINib(nibName: "ColumnTemplateCell", bundle: NSBundle.mainBundle()), forCellWithReuseIdentifier: "DJCELL2")
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath
    indexPath: NSIndexPath) -> UICollectionViewCell {

  var ProductCardCellpt : DJCell?

    if self._CurrentLayoutType == enum_Layout.RowRecords {
    reuseIdentifier = "DJCELL"
    ProductCardCellpt = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as? DJCell
    …
    }else{
    reuseIdentifier = "DJCELL2"
    ProductCardCellpt = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as? DJCell
    ...
    }
    return   ProductCardCellpt!
    }

and finally when i touch on DJ button. The animation between transition is ok except the unexpected Constraint inside the cells

Initial Layout New Layout

Here is the code of Transition layout

 @IBAction func Action_ToggleLayout(sender: UIBarButtonItem) {
        if _CurrentLayoutType == enum_Layout.TwoColumn {
            _CurrentLayoutType = enum_Layout.RowRecords
            self.DJCollectionView.setCollectionViewLayout(self._RowRecordsLayout_CollectionViewLayout!, animated: true, completion: { (IsDone) -> Void in

            })
        }
        else{
            _CurrentLayoutType = enum_Layout.TwoColumn
            self.DJCollectionView.setCollectionViewLayout(self._TwoColumnLayout_CollectionViewLayout!, animated: true, completion: { (IsDone) -> Void in

                }
            })
        }

    }

The content inside cells are back to normal when i scroll up or down. Any solution to fix this ?

Upvotes: 1

Views: 264

Answers (2)

tylerlantern
tylerlantern

Reputation: 85

After I i have experimented a lot of stuff. I did combined Poql's answer to achieve the result. Here is the procedure.

  1. Do register cell class to UICollectionView without nib attached to it Using initwithframe in custom cell class since There's no nib file and no storyboard refer to the cell
  2. Declare function inside the cell's class for toggling layout Implement
  3. Override function willTransitionFromLayout inside the cell's class
  4. Override function applyLayoutAttributes inside the cell's class
  5. Finally,Callling Toggling function after collectionView.dequeueReusableCellWithReuseIdentifier in collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) function

Below is a portion of the code enjoy

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
     var ProductCardCellpt : ProductCardCell? = collectionView.dequeueReusableCellWithReuseIdentifier("ProductCardCell", forIndexPath: indexPath) as? ProductCardCell
     ProductCardCellpt?.SetLayoutAccordingToDesiredLayout(self._CurrentLayoutType)
 }

Inside the cell's class

func SetLayoutAccordingToDesiredLayout(DesiredLayout : enum_Layout){
     if DesiredLayout == self.Current_Layout && IsSetPosition == true {
        return
     }
     self.IsSetPosition = false
     self.Current_Layout = DesiredLayout
     if DesiredLayout == enum_Layout.OneColumn || DesiredLayout == enum_Layout.TwoColumn {
     DoColumnLayout()
     }else{
     DoRecordLayout()
     }
 }
func DoRecordLayout(){
    let dFrame = self.contentView.frame
    self.Thumbnail.frame = CGRect(x: 0, y: 0, width: dFrame.height, height: dFrame.height)
    ...
 }
func DoColumnLayout(){
    let dFrame = self.contentView.frame
    self.Thumbnail.frame = CGRect(x: 0, y: 0, width: dFrame.width, height: dFrame.width)
    ...
}
override func applyLayoutAttributes(layoutAttributes: UICollectionViewLayoutAttributes!) {
    self.layoutIfNeeded()
    self.SetLayoutAccordingToDesiredLayout(self.Current_Layout)

}
override func willTransitionFromLayout(oldLayout: UICollectionViewLayout, toLayout newLayout: UICollectionViewLayout) {
    let nLayout = newLayout as! ProductCollectionViewLayout
    let enumLayout = nLayout._enumLayout
    self.Current_Layout = enumLayout
}

Upvotes: 0

GaétanZ
GaétanZ

Reputation: 4930

Well the problem is your cells currently displayed don't update when you change the layout. They only update when you're scrolling. Doing something like calling collectionView.reloadData() when the layout has changed should do the work.

But I don't think you're using the collectionView correctly. Layout is nothing to do with UICollectionViewCell and the animation will not work. So I don't think it is a good practice to change the collectionView cell class when you're changing the layout of the UICollectionView. You should override the method willTransitionFromLayout: of your custom collectionViewCell and change the constraints of the cell here. Something like Working with AutoLayout in Portrait and Landscape.

Hope this could lead you on the right way.

Upvotes: 1

Related Questions