我有一个TableViewController,TableViewCell和一个ViewController。我在TableViewCell中有一个按钮,我想用presentViewController
呈现ViewController(但是ViewController没有在故事板上有一个视图)。我尝试使用:
@IBAction func playVideo(sender: AnyObject) {
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
}
错误:TableViewCell类型的值没有成员presentViewController
然后,我试过
self.window?.rootViewController!.presentViewController(vc, animated: true, completion: nil)
错误:警告:尝试显示其视图不在窗口层次结构中!
我做错了什么?我应该怎么做才能从TableViewCell中呈现ViewController?另外,我如何将数据传递给TableViewCell的新呈现VC?
更新
protocol TableViewCellDelegate
{
buttonDidClicked(result: Int)
}
class TableViewCell: UITableViewCell {
@IBAction func play(sender: AnyObject) {
if let id = self.item?["id"].int {
self.delegate?.buttonDidClicked(id)
}
}
}
----------------------------------------
// in TableViewController
var delegate: TableViewCellDelegate?
func buttonDidClicked(result: Int) {
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
}
我收到错误:不建议在分离的视图控制器上显示视图控制器
(请注意,我在TableView后面有一个NavBar和TabBar链。)
我也试过
self.parentViewController!.presentViewController(vc, animated: true, completion: nil)
相同的错误。
也尝试了,
self.view.window?.rootViewController?.presentViewController(vc, animated: true, completion: nil)
相同错误
答案 0 :(得分:7)
您应该使用protocol
将操作传回tableViewController
1)在您的单元格类中创建protocol
2)将button
动作调用protocol
func
3)将cell's protocol
tableViewController
与cell.delegate = self
4)实施cell's protocol
并在那里添加代码
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
答案 1 :(得分:7)
看起来你已经有了提出视图控制器的想法,你需要一个视图控制器。所以这就是你需要做的事情:
以下是一些代码:
// 1.
protocol PlayVideoCellProtocol {
func playVideoButtonDidSelect()
}
class TableViewCell {
// ...
// 2.
var delegate: PlayVideoCellProtocol!
// 3.
@IBAction func playVideo(sender: AnyObject) {
self.delegate.playVideoButtonDidSelect()
}
// ...
}
class TableViewController: SuperClass, PlayVideoCellProtocol {
// ...
// 4.
func playVideoButtonDidSelect() {
let viewController = ViewController() // Or however you want to create it.
self.presentViewController(viewController, animated: true, completion: nil)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath: NSIndexPath) -> UITableViewCell {
//... Your cell configuration
// 5.
cell.delegate = self
//...
}
//...
}
答案 2 :(得分:1)
我遇到了同样的问题,并在stackoverflow的某处找到了此代码,但我不记得在哪里,所以这不是我的代码,但我将在此处展示。
这是我要在任何地方显示视图控制器时使用的方式,它会提示keyWindow
已被禁用,但效果很好。
extension UIApplication
{
class func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController?
{
if let nav = base as? UINavigationController
{
let top = topViewController(nav.visibleViewController)
return top
}
if let tab = base as? UITabBarController
{
if let selected = tab.selectedViewController
{
let top = topViewController(selected)
return top
}
}
if let presented = base?.presentedViewController
{
let top = topViewController(presented)
return top
}
return base
}
}
您可以在任何地方使用它,就我而言,我使用过:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "WeekViewController")
UIApplication.topViewController()?.navigationController?.show(vc, sender: nil)
}
答案 3 :(得分:0)
所以self.presentViewController是ViewController的一个方法。 你得到这个错误的原因是因为" self"你指的是tableViewCell。并且tableViewCell没有presentViewController的方法。
我认为你可以使用一些选项: 1.在单元格中添加委托和协议,当您单击按钮时,IBAction将调用
self.delegate?.didClickButton()
然后在你的tableVC中,你只需要实现这个方法并调用self.presentViewController
2.使用故事板和segue 在故事板中,从按钮拖动到想要的VC。