我试图在UICollectionView Cell中添加一个UIViewController,但不知道该怎么做.
您需要创建一个自定义容器视图控制器:https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html
func display(contentController content: UIViewController, on view: UIView) {
self.addChildViewController(content)
content.view.frame = view.bounds
view.addSubview(content.view)
content.didMove(toParentViewController: self)
}
Run Code Online (Sandbox Code Playgroud)
对于容器中的每个单元格,您必须在单元格的内容视图上使用正确的子视图控制器调用类似上述函数的内容.
小心不要尝试将多个视图控制器添加到同一个单元格中,并确保它们也被正确删除.
这个想法很复杂,不利于简单的堆栈溢出答案,但希望上面的内容足以让你开始.
问题 1,对于表格视图,如果您只有少量单元格,您只需单击即可使单元格静态 - 就完成了。不幸的是与收集的意见,苹果并没有增加,使其静态的能力。所以你必须以艰难的方式去做。
本教程:https : //stackoverflow.com/a/23403979/294884
完美解释了如何动态添加容器视图(到普通场景)。
向下滚动到“动态加载...”
事实是你的单元必须知道它自己的老板视图控制器:
class CrazyBigCell: UICollectionViewCell {
weak var boss: ThatClass? = nil
Run Code Online (Sandbox Code Playgroud)
当你制作单元格时,设置那个“老板”变量......
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "CrazyBigCellID", for: indexPath) as! CrazyBigCell
cell.boss = self
cell.data = someData[indexPath.row]
return cell
}
Run Code Online (Sandbox Code Playgroud)
完全按照上面的教程进行,但是:在添加子 VC 时,将其添加到老板VC。
class CrazyBigCell: UICollectionViewCell {
weak var boss: ThatClass? = nil
@IBOutlet var chatHolder: UIView!
var chat: Chat? = nil
....
Run Code Online (Sandbox Code Playgroud)
所以......秘诀是:通常你会说类似的话
self.addChild(chat!)
Run Code Online (Sandbox Code Playgroud)
但它是
boss?.addChild(chat!)
Run Code Online (Sandbox Code Playgroud)
所以 ...
private func _installChatBlock() {
if chat == nil {
print(">>> installing chat for " + name etc)
chat = _sb("Chat") as? Chat
boss?.addChild(chat!)
chatHolder.addSubview(chat!.view)
chat!.view.bindEdgesToSuperview()
chat!.didMove(toParent: boss)
}
else {
print(">>> already had a Chat for " + name etc)
}
chat!.data = data // or whatever
chat!.loadOurChat() // or whatever
}
Run Code Online (Sandbox Code Playgroud)
在哪里打电话_installChatBlock ?
很可能,在您为此单元格设置数据的地方调用
var data: [String : Any] = [:] { // whatever
didSet {
headline.text = data["headline.text"] // etc
name.text = data["name"] // etc
_installChatBlock()
}
}
Run Code Online (Sandbox Code Playgroud)
呼。
Daniel 说的是正确的,但是如果您必须childViewControllers向 a UICollectionViewCellor 中添加许多UITableViewCell,则维护起来可能很麻烦。
这是 Suroush Khanlou 的一篇很好的帖子,它处理了这种复杂性并简化了过程。
http://khanlou.com/2015/04/view-controllers-in-cells/
通用方法
protocol ChildControllersManagerDelegate: class {
associatedtype ViewControllerType: UIViewController
func willAdd(_ childViewController: ViewControllerType, at index: Int)
}
final class ChildControllersManager<V, D: ChildControllersManagerDelegate> where D.ViewControllerType == V {
private var viewControllers = [Int: V]()
weak var delegate: D?
func addChild(at index: Int, to viewController: UIViewController, displayIn contentView: UIView) {
let childVC: V
if let vc = viewControllers[index] {
print("Using cached view controller")
childVC = vc
} else {
print("Creating new view controller")
childVC = V()
viewControllers[index] = childVC
}
delegate?.willAdd(childVC, at: index)
viewController.addChild(childVC)
childVC.view.frame = contentView.bounds
contentView.addSubview(childVC.view)
childVC.didMove(toParent: viewController)
}
func remove(at index: Int) {
print("Remove at \(index)")
guard let vc = viewControllers[index] else { return }
vc.willMove(toParent: nil)
vc.view.removeFromSuperview()
vc.removeFromParent()
}
func cleanCachedViewControllers(index: Int) {
let indexesToClean = viewControllers.keys.filter { key in
key > index + 1 || key < index - 1
}
indexesToClean.forEach {
viewControllers[$0] = nil
}
}
}
...
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
childControllersManager.addChild(at: indexPath.row, to: self, displayIn: cell.contentView)
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
childControllersManager.remove(at: indexPath.row)
childControllersManager.cleanCachedViewControllers(index: indexPath.row)
}
}
extension ViewController: ChildControllersManagerDelegate {
typealias ViewControllerType = MyVC
func willAdd(_ childViewController: MyVC, at index: Int) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7351 次 |
| 最近记录: |