使用 UIViewController 作为 TableView 单元格
Posted
技术标签:
【中文标题】使用 UIViewController 作为 TableView 单元格【英文标题】:Use UIViewController as TableView cell 【发布时间】:2016-09-18 20:30:02 【问题描述】:我有一个在两个 UIViewController 之间切换的分段控件。一个信息视图和一个列表视图 (TableView)。
我想使用第一个 UIViewController 作为我的 TableView 的第一个单元格(即在另一个段上)。
有没有办法将 UIViewController 转换为单元格或以某种方式将其用作 TableView 的单元格?
【问题讨论】:
是的,您可以将 VC 的视图添加为单元格 contentView 的子视图。您还需要将 VC 作为子 VC 添加到某些父 VC。使用自动布局定位 VCs 视图。 谢谢。如何将我的 InfoViewController 添加为孩子?对于什么父母。这部分我做得不太好。 【参考方案1】:以您自己的方式使用此代码。在这里,我们将控制器视图添加为单元格的子视图,并使用自动布局来正确管理。您只需要理解使用代码即可。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:indexPath)
cell.layoutIfNeeded()
let infoVC = self.storyboard.instantiateViewControllerWithIdentifier("InfoVC")
self.addChildViewController(infoVC)
cell.contentView.addSubview(infoVC.view)
infoVC.view.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addConstraint(NSLayoutConstraint(item: infoVC.view, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.Leading, multiplier: 1.0, constant: 0.0))
cell.contentView.addConstraint(NSLayoutConstraint(item: infoVC.view, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.Trailing, multiplier: 1.0, constant: 0.0))
cell.contentView.addConstraint(NSLayoutConstraint(item: infoVC.view, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0.0))
cell.contentView.addConstraint(NSLayoutConstraint(item: infoVC.view, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 0.0))
infoVC.didMoveToParentViewController(self)
infoVC.view.layoutIfNeeded()
【讨论】:
这段代码假设拥有UITableView的VC是DataSource 我刚刚回答了您对@Sajjon 的建议,因为通过阅读提问者想要做什么,我也有同样的想法。如有错误,您可以更正答案。 这似乎有效。但是我会尝试。让我问你一件事。我的 tableview 的其他单元格具有不同大小的 infoVC。我该如何处理?例如...我的 InfoVC 的高度为 300,而我的其他单元格的高度为 70。 您可能需要考虑添加一些代码来解决重复使用单元格的情况。在添加新视图控制器之前,应删除以前的视图控制器。完成后,之前的 VC 应该调用willMove(toParentViewController: nil)
和 removeFromParentViewController()
UITableViewCell
有一个方法 prepareForReuse()
在重用单元格之前调用。覆盖此方法并在其中包含的任何 UIViewController
上调用 removeFromParentViewController()
是一个可行的选择。【参考方案2】:
Swift 5.0 语法
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)
cell.layoutIfNeeded()
let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.addChild(vc)
cell.contentView.addSubview(vc.view)
vc.view.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addConstraint(NSLayoutConstraint(item: vc.view, attribute: NSLayoutConstraint.Attribute.leading, relatedBy: NSLayoutConstraint.Relation.equal, toItem: cell.contentView, attribute: NSLayoutConstraint.Attribute.leading, multiplier: 1.0, constant: 0.0))
cell.contentView.addConstraint(NSLayoutConstraint(item: vc.view, attribute: NSLayoutConstraint.Attribute.trailing, relatedBy: NSLayoutConstraint.Relation.equal, toItem: cell.contentView, attribute: NSLayoutConstraint.Attribute.trailing, multiplier: 1.0, constant: 0.0))
cell.contentView.addConstraint(NSLayoutConstraint(item: vc.view, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: cell.contentView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1.0, constant: 0.0))
cell.contentView.addConstraint(NSLayoutConstraint(item: vc.view, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: cell.contentView, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1.0, constant: 0.0))
vc.didMove(toParent: self)
vc.view.layoutIfNeeded()
return cell
【讨论】:
在这种情况下,在视图控制器“vc”中,您将如何访问单元格属性?【参考方案3】:好吧,我建议使用自己的 nib 文件创建一个自定义 UITableViewCell 并从 nib 加载它。
这可以添加/取消队列到UITableViewSection
。
然后可以在 UI Builder 中以您希望的任何方式设计 Cell 本身。您可以将所有内容放入您喜欢的单元格中。
这里有一个简短的教程如何做到这一点: using-nib-xib-files
可以在此处找到有关该主题的问题: Custom UITableViewCell from nib in Swift
【讨论】:
我可以这样工作。问题是我已经有了故事板中所有约束的布局。有办法将其“转换”为 nib(或 xib)文件吗? 很抱歉告诉你,但我认为没有自动的方法可以这样做。我认为您可以将内容复制到 nib/xib 文件中。我认为创建这样的自定义单元格将是一个干净的解决方案。此外,它易于维护,您不必在代码中设置约束。您可以尝试使用ContainerViewController
将另一个故事板加载到 xib/nib 单元格中。 (这肯定是一个肮脏的黑客,它不会推荐它!)developer.apple.com/library/content/featuredarticles/…以上是关于使用 UIViewController 作为 TableView 单元格的主要内容,如果未能解决你的问题,请参考以下文章
在不使用 IB 的情况下添加 UIImageView 作为 UIViewController 的子视图
从 UIViewController 显示 UIView 作为上下文菜单预览
在 uiviewcontroller 中添加 uitableviewcontroller 作为子视图时出错
如何将 UIViewController 作为子视图添加到 UIViewController(RootViewController)?
添加根视图控制器 OCMockObject[UIViewController] 作为子视图控制器错误
如何最好地将使用一个 UIViewController 将所有页面作为 UIView 处理为 StoryBoarding 和 UIPageView 的图书应用程序转换?