chr*_*702 4 ios uicollectionview swift
我正在使用Swift为我工作的医院构建一个iOS应用程序.
不知何故,在一个特定的功能,我必须把一个UICollectionView内部UICollectionViewCell.我想要实现的是父母的每个内容UICollectionView(垂直滚动)将有几个孩子(可以水平滚动),具体取决于父行.
为了说明,我必须显示医生名单(姓名和照片),然后我必须在他们的名字和照片下面显示他们的每个练习时间表.实践时间表因每位医生而异.所以,我必须把它放在里面UICollectionView.
我尝试过在网上找到的几种解决方案,但我仍然无法接近它.
我无法解决的最大问题是:我不知道代码中加载子数据源(医生日程安排)的位置以及何时可以加载它,因为我不能有两个函数,如下所示:
collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
Run Code Online (Sandbox Code Playgroud)
这是我想要实现的目标
在UIImage和医生的名字(UILabel)是在父UICollectionViewCell(垂直滚动),然后在框中(实习n天的练习时间),一切都是孩子UICollectionView(水平滚动)
PS:有很多医生,每个医生都有几天练习.
请帮我怎么做
如果你真的想在collectionViewCell中插入一个collectionView,那么有一个非常简单的步骤.创建UICollectionView的实例并将其添加到collectionViewCell.如果您愿意,可以使用此示例.
//
// ViewController.swift
// StackOverFlowAnswer
//
// Created by BIKRAM BHANDARI on 18/6/17.
// Copyright © 2017 BIKRAM BHANDARI. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
let cellId = "CellId"; //Unique cell id
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red; //just to test
collectionView.register(Cell.self, forCellWithReuseIdentifier: cellId) //register collection view cell class
setupViews(); //setup all views
}
func setupViews() {
view.addSubview(collectionView); // add collection view to view controller
collectionView.delegate = self; // set delegate
collectionView.dataSource = self; //set data source
collectionView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true; //set the location of collection view
collectionView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true; // top anchor of collection view
collectionView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true; // height
collectionView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true; // width
}
let collectionView: UICollectionView = { // collection view to be added to view controller
let cv = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()); //zero size with flow layout
cv.translatesAutoresizingMaskIntoConstraints = false; //set it to false so that we can suppy constraints
cv.backgroundColor = .yellow; // test
return cv;
}();
//deque cell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath);
// cell.backgroundColor = .blue;
return cell;
}
// number of rows
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5;
}
//size of each CollecionViewCell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 200);
}
}
// first UICollectionViewCell
class Cell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
let cellId = "CellId"; // same as above unique id
override init(frame: CGRect) {
super.init(frame: frame);
setupViews();
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId); //register custom UICollectionViewCell class.
// Here I am not using any custom class
}
func setupViews(){
addSubview(collectionView);
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true;
collectionView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true;
collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true;
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true;
}
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout();
layout.scrollDirection = .horizontal; //set scroll direction to horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout);
cv.backgroundColor = .blue; //testing
cv.translatesAutoresizingMaskIntoConstraints = false;
return cv;
}();
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath);
cell.backgroundColor = .red;
return cell;
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5;
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.frame.width, height: self.frame.height - 10);
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Run Code Online (Sandbox Code Playgroud)
这可能有点晚了,但对于仍在尝试寻找答案的人们来说。
经过一些研究和挖掘,我偶然发现了几篇文章,说明了为什么你不应该让你的单元格成为你的 collectionView 的委托。所以,我迷失了,因为我发现的几乎所有解决方案都在这样做,直到我最终找到了我认为是嵌套 CollectionView 的最佳方法。
为了提供一些背景知识,我的应用程序在另一个 collectionView 的不同单元格内不仅包含一个而是 2 个 collectionView,因此使用标签设置委托等等,并不是真正的最佳方法,也不是正确的 OO 解决方案。
因此,最好的方法如下:
首先,您必须创建一个不同的类来充当内部 collectionView 的委托。我是这样做的:
class InnerCollectionViewDelegate: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
// CollectionView and layout delegate methods here
// sizeForItemAt, cellForItemAt, etc...
}
Run Code Online (Sandbox Code Playgroud)
现在,在您的内部collectionView(或者更确切地说,您拥有内部collectionView的单元格)中创建一个函数,该函数将允许您设置其委托
class InnerCell: UICollectionViewCell {
var collectionView: UICollectionView
init() {
let layout = UICollectionViewFlowLayout()
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height), collectionViewLayout: layout)
}
func setCollectionViewDataSourceDelegate(dataSourceDelegate: UICollectionViewDataSource & UICollectionViewDelegate) {
collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.reloadData()
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在您拥有最外层(主)collectionView 的 ViewController 中执行以下操作:
首先实例化内部collectionView的委托
var innerDelegate = InnerCollectionViewDelegate()
Run Code Online (Sandbox Code Playgroud)
进而
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? InnerCell {
cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: innerDelegate)
}
}
Run Code Online (Sandbox Code Playgroud)
这可能并不完美,但至少您可以实现关注点分离,因为您的单元不应该成为代表。请记住,您的单元格应该只负责显示信息,而不是试图弄清楚 collectionView 的大小应该是多少,等等。
我确实找到了处理设置 collectionViews 标签等的类似答案,但我发现这使得单独处理每个 collectionView 变得更加困难,而且处理标签不会导致意大利面条代码或意外行为。
我省略了单元格的注册和出队,但我相信你们都熟悉这一点。如果没有,请告诉我,我会尽力引导您完成它。
| 归档时间: |
|
| 查看次数: |
7984 次 |
| 最近记录: |