来自TableViewCell的presentViewController

时间:2016-01-20 21:33:54

标签: ios swift uitableview tableview tableviewcell

我有一个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)

相同错误

4 个答案:

答案 0 :(得分:7)

您应该使用protocol将操作传回tableViewController

1)在您的单元格类中创建protocol

2)将button动作调用protocol func

3)将cell's protocol tableViewControllercell.delegate = self

联系起来

4)实施cell's protocol并在那里添加代码

let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)

答案 1 :(得分:7)

看起来你已经有了提出视图控制器的想法,你需要一个视图控制器。所以这就是你需要做的事情:

  1. 创建一个协议,通知单元格的控制器按下按钮。
  2. 在单元格中创建一个属性,该属性包含对实现协议的委托的引用。
  3. 在按钮操作内调用您的委托上的协议方法。
  4. 在视图控制器中实现协议方法。
  5. 配置单元格时,将视图控制器作为委托传递给单元格。
  6. 以下是一些代码:

    // 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。