问题
I have a TableViewController, TableViewCell and a ViewController. I have a button in the TableViewCell and I want to present ViewController with presentViewController (but ViewController doesn't have a view on storyboard). I tried using:
@IBAction func playVideo(sender: AnyObject) {
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
}
Error: Value of type TableViewCell has no member presentViewController
Then, I tried
self.window?.rootViewController!.presentViewController(vc, animated: true, completion: nil)
Error: Warning: Attempt to present whose view is not in the window hierarchy!
What am I doing wrong? What should I do in order to presentViewController from TableViewCell? Also how can I pass data to the new presenting VC from TableViewCell?
Update:
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)
}
I receive error: Presenting view controllers on detached view controllers is discouraged
(Please note that I have a chain of NavBar & TabBar behind TableView.)
I also tried
self.parentViewController!.presentViewController(vc, animated: true, completion: nil)
Same Error.
Also tried,
self.view.window?.rootViewController?.presentViewController(vc, animated: true, completion: nil)
Same Error
回答1:
You should use protocol to pass the action back to tableViewController
1) Create a protocol in your cell class
2) Make the button action call your protocol func
3) Link your cell's protocol in tableViewController by cell.delegate = self
4) Implement the cell's protocol and add your code there
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
回答2:
It seems like you've already got the idea that to present a view controller, you need a view controller. So here's what you'll need to do:
- Create a protocol that will notify the cell's controller that the button was pressed.
- Create a property in your cell that holds a reference to the delegate that implements your protocol.
- Call the protocol method on your delegate inside of the button action.
- Implement the protocol method in your view controller.
- When configuring your cell, pass the view controller to the cell as the delegate.
Here's some code:
// 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
//...
}
//...
}
回答3:
So self.presentViewController is a method from the ViewController. The reason you are getting this error is because the "self" you are referring is the tableViewCell. And tableViewCell doesn't have method of presentViewController.
I think there are some options you can use: 1.add a delegate and protocol in the cell, when you click on the button, the IBAction will call
self.delegate?.didClickButton()
Then in your tableVC, you just need to implement this method and call self.presentViewController
2.use a storyboard and a segue In the storyboard, drag from your button to the VC you want to go.
来源:https://stackoverflow.com/questions/34911022/presentviewcontroller-from-tableviewcell