Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 单集合视图和多集合视图布局。为什么布局混乱?_Ios_Swift_Uicollectionview_Uicollectionviewlayout - Fatal编程技术网

Ios 单集合视图和多集合视图布局。为什么布局混乱?

Ios 单集合视图和多集合视图布局。为什么布局混乱?,ios,swift,uicollectionview,uicollectionviewlayout,Ios,Swift,Uicollectionview,Uicollectionviewlayout,我有一个UICollectionView,我想动态应用两种不同的布局 UICollectionViewFlowLayout:具有相同大小单元格和圆形图像的布局 var flowLayout: UICollectionViewFlowLayout { let flowLayout = UICollectionViewFlowLayout() flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width/3, heig

我有一个
UICollectionView
,我想动态应用两种不同的布局

  • UICollectionViewFlowLayout
    :具有相同大小单元格和圆形图像的布局

    var flowLayout: UICollectionViewFlowLayout {
        let flowLayout = UICollectionViewFlowLayout()
    
        flowLayout.itemSize = CGSize(width: UIScreen.main.bounds.width/3, height: 140)
        flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0)
        flowLayout.scrollDirection = UICollectionViewScrollDirection.vertical
        flowLayout.minimumInteritemSpacing = 0.0
    
        return flowLayout
    }
    
  • Pintrest布局

  • 例如:当用户单击Profile按钮时,将应用FlowLayout,单元格显示为圆形图像。当用户单击图片按钮时,将应用pintrest布局,单元格显示为动态高度的矩形图像。

    最初的CollectionView有1.1.1的flowLayout,它看起来非常完美。但当我点击图片按钮时,Pintrest布局与上图所示的先前布局弄乱了。

    下面是更改布局的代码

    if isGrid {
        let horizontal = flowLayout
        recentCollectionView.setCollectionViewLayout(horizontal, animated: true)
        recentCollectionView.reloadData()
    }
    else {
        let horizontal = PinterestLayout()
        horizontal.delegate = self
        recentCollectionView.setCollectionViewLayout(horizontal, animated: true)
        recentCollectionView.reloadData()
    }
    
    视图层次结构:

    我有包含标题和一个底部单元格的主集合视图。单元格包含我正在应用多个布局的其他集合视图。每个布局有两个不同的单元格。我希望底部单元格大小等于内容集合视图内容大小,以便用户可以垂直滚动整个主集合视图。

     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            var cell : UICollectionViewCell!
    
            switch isGrid {
            case true:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchProfileCell", for: indexPath)
                if let annotateCell = cell as? SearchProfileCell {
                    annotateCell.photo = photos[indexPath.item]
                }
            case false:
                 cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AnnotatedPhotoCell", for: indexPath)
    
                if let annotateCell = cell as? AnnotatedPhotoCell {
                    annotateCell.cellwidth = collectionView.contentSize.width/3
                    annotateCell.photo = photos[indexPath.item]
    
                }
            }
    
            cell.contentView.layer.cornerRadius = 0
            return cell
        }
    
    配置文件和图片按钮动作代码

    @IBAction func pictureClick(sender:UIButton) {
            isGrid = false
            self.searchCollectionView.reloadData()
        }
    
        @IBAction func profilClick(sender:UIButton) {
            isGrid = true
            self.searchCollectionView.reloadData()
        }
    

    我认为问题不在于内部布局,而在于cellForItemAt内部。如果两种布局使用不同的单元格,则不要在cellForItemAt方法中比较bool。您应该比较布局类类型 如下代码所示:

     func  collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            if collectionView.collectionViewLayout.isKind(of: PinterestLayout.self) {
               // return cell for PinterestLayout 
                 guard let annotateCell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchProfileCell", for: indexPath) as? SearchProfileCell else {
                  fatalError("SearchProfileCell Not Found")
                }
                annotateCell.photo = photos[indexPath.item]
                return annotateCell
            } else {
             // return cell for flowLayout 
                  guard let annotateCell = collectionView.dequeueReusableCell(withReuseIdentifier: "AnnotatedPhotoCell", for: indexPath) as? AnnotatedPhotoCell else {
                    fatalError("AnnotatedPhotoCell Not Found")
                 }
                 annotateCell.cellwidth = collectionView.contentSize.width/3
                 annotateCell.photo = photos[indexPath.item]
                 return annotateCell
            }
     }
    
    还需要更新布局更改操作方法,如:

         @IBAction func pictureClick(sender:UIButton) {
                   isGrid = false
    
            self.collectionView?.collectionViewLayout.invalidateLayout()  
           self.collectionView?.setCollectionViewLayout(PinterestLayout(), 
                 animated: false, completion: { [weak self] (complite) in
                        guard let strongSelf = self else {
                            return
                        }
                        strongSelf.searchCollectionView?.reloadData()
                    })
           }
    
          @IBAction func profilClick(sender:UIButton) {
              isGrid = true
              self.collectionView?.collectionViewLayout.invalidateLayout()              
           self.collectionView?.setCollectionViewLayout(flowLayout, 
                 animated: false, completion: { [weak self] (complite) in
                        guard let strongSelf = self else {
                            return
                        }
                        strongSelf.searchCollectionView?.reloadData()
                    })
         }
    

    为什么您使用两种不同的布局,即使您可以通过pintrestLayout获得相同的结果

    仔细检查销支架布局,它具有动态高度

     let photoHeight = delegate.collectionView(collectionView, heightForPhotoAtIndexPath: indexPath)
    
    如果在此处返回静态高度,pintrest布局将成为GridLayout(第一个布局)

    如果希望pintrest layout同时用于这两种布局,则需要在pintrest layout.com中声明相同的布尔值(isGrid),并使用此布尔值返回UICollectionViewLayoutAttribute

    更重要的是,raywenderlich pintrest布局使用缓存来存储布局属性。在应用其他布局之前,必须删除缓存对象

    在本教程中查看如何将相同的布局用于栅格、列表和线性。

    在布局中需要什么

     var isGrid : Bool = true {
            didSet {
                if isGrid != oldValue {
                    cache.removeAll()
                    self.invalidateLayout()
                }
            }
        }
    

    试试PerformBatchUpdate你的意思是我应该使用PerformBatchUpdate而不是重载数据,对吗?在PerformBatchUpdate的块中放入布局重置代码好的。让我试试,我认为你应该使用LayoutSubview而不是重载数据(),所以在你的IF语句之后尝试self.view.LayoutSubview。您希望触发视图控制器的重画谢谢您的建议。我已经替换了您的cellforindexpath代码,但仍然存在相同的问题。您可以尝试使用完成块设置CollectionViewLayout吗?您好,请给出一些代码示例,说明单个布局如何适用于不同的设计。