繁体   English   中英

如何有一个视图 controller 有两个集合视图,但只有一个有页眉/页脚视图?

[英]How to have a view controller with two collection views, but only one has header/footer views?

我的视图 controller 中有两个集合视图,它们被设置为两者的委托和数据源。 其中一个集合视图有一个注册的补充视图作为它的 header,它在我添加第二个集合视图之前将其出列并正确显示。 现在使用第二个集合视图, viewForSupplementaryElementOfKind会导致错误,因为第二个集合视图没有任何注册的标头。 如何确保仅在第一个集合视图上调用 function?

为 UICollectionView 创建一个简单而简短的自定义子类,如下所示:

class CustomCollectionView : UICollectionView {
    let showFooter : Bool
    let showHeader : Bool

    init(showHeader:Bool,showFooter:Bool) {
        self.showFooter = showFooter
        self.showHeader = showHeader
        //Create a custom UICollectionViewLayout and frame according to your requirement here (You can send parent ViewControllers frame as a param in the init above too)
        super.init(frame: CGRect.zero, collectionViewLayout: UICollectionViewLayout.init())
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

现在只需使用 showHeader 和/或 showFooter 将第一个 CollectionView 初始化为 true 和其他相应的。您现在需要在请求补充视图的委托回调中执行以下操作:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    guard let collectionView = collectionView as? CustomCollectionView else {
        return UICollectionReusableView.init(frame: .zero)
    }

    switch kind {
    case UICollectionView.elementKindSectionFooter:
        if collectionView.showFooter {
                //Dequeue a footer and return
        }
    case UICollectionView.elementKindSectionHeader:
        if collectionView.showHeader {
                //Dequeue a header and return
        }
    default:
        return UICollectionReusableView.init(frame: .zero)
    }
    return UICollectionReusableView.init(frame: .zero)
}

各种数据源和委托方法的第一个参数是集合视图。

我不建议像其他海报建议的那样使用视图标签。 这种方法很脆弱。

相反,让您的视图 controller 保留指向每个的指针,然后让方法检查正在调用哪个:

@IBOulet collectionView1: UICollectionView!
@IBOulet collectionView2: UICollectionView!

然后在您的 viewForSupplementaryElementOfKind 方法中:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    switch collectionView {
        case collectionView1:
            //code to return a view for collection view 1
        case collectionView2:
            //code to return a view for collection view 2
        default: 
            //Can't happen, but keep the compiler happy:
            return UIView(frame: CGRect.zeroRect)
    }
}

或者,设置单独的对象作为每个集合视图的数据源。 让您的视图 controller 创建数据源并将它们连接到其 viewDidLoad 方法中。

如果一个集合视图具有 header 而另一个没有,则需要为每个集合视图单独配置布局对象。 (您需要有类似上面的代码,为您的所有集合视图方法分别处理两个集合视图。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM