执行 setCollectionViewLayout 时 UICollectionViewCel 中的布局看起来很奇怪

Posted

技术标签:

【中文标题】执行 setCollectionViewLayout 时 UICollectionViewCel 中的布局看起来很奇怪【英文标题】:layout in UICollectionViewCel looks odd when perform setCollectionViewLayout 【发布时间】:2015-07-10 16:25:06 【问题描述】:

我有两个 nib 文件,分别是 RowRecordLayout 和 ColumnLayout。

我确实将笔尖单元格注册到 UICollectionView 以便稍后在 cellForItemAtIndexPath 函数中使用。这是我的代码

 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!
    

最后当我触摸 DJ 按钮时。除了单元格内的意外约束之外,过渡之间的动画还可以

这是Transition布局的代码

 @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

                
            )
        

    

当我向上或向下滚动时,单元格内的内容恢复正常。 有什么解决办法吗?

【问题讨论】:

你可以把collectionView布局放在nib文件中吗?您只能将 UICollectionViewCell 放在 nib 中,不是吗? 它们是 nib 中的 UICollectionViewCell。 你什么时候改变了你的collectionView的布局? 触摸 DJ 按钮时布局发生变化。我已经编辑了我的帖子以包含更改布局代码。 【参考方案1】:

问题是您当前显示的单元格在您更改布局时不会更新。它们仅在您滚动时更新。当布局发生变化时调用 collectionView.reloadData() 应该可以完成工作。

但我认为您没有正确使用 collectionView。布局与 UICollectionViewCell 无关,动画将不起作用。因此,我认为在更改 UICollectionView 的布局时更改 collectionView 单元类不是一个好习惯。您应该覆盖自定义 collectionViewCell 的方法 willTransitionFromLayout: 并在此处更改单元格的约束。像Working with AutoLayout in Portrait and Landscape 这样的东西。

希望这可以引导您走上正确的道路。

【讨论】:

【参考方案2】:

在我尝试了很多东西之后。我确实结合了 Poql 的答案来达到这个结果。这是程序。

    将单元格类注册到 UICollectionView 而不附加 nib 在自定义单元格类中使用 initwithframe,因为没有 nib 文件,也没有故事板引用单元格 在单元格的类中声明用于切换布局实现的函数 在单元格的类中覆盖函数 willTransitionFromLayout 在单元格的类中覆盖函数 applyLayoutAttributes 最后,在collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath)函数中collectionView.dequeueReusableCellWithReuseIdentifier之后调用Toggling函数

下面是部分代码欣赏

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

在单元格的类中

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

【讨论】:

以上是关于执行 setCollectionViewLayout 时 UICollectionViewCel 中的布局看起来很奇怪的主要内容,如果未能解决你的问题,请参考以下文章

jvm的解释执行与编译执行

Jmeter--多个线程组顺序执行和并行执行

小记---------手动执行脚本正常执行,使用crontab定时执行时 不执行

同步执行与异步执行

js函数执行顺序,怎麼让一个函数执行完再执行下面的程序

java中定时执行任务,为啥方法没有执行完就不执行了?