来自 TableViewCell 的 presentViewController
presentViewController from TableViewCell
我有一个表ViewController、TableViewCell 和一个ViewController。我在 TableViewCell 中有一个按钮,我想用 presentViewController
显示 ViewController(但 ViewController 在故事板上没有视图)。我尝试使用:
@IBAction func playVideo(sender: AnyObject) {
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
}
Error: Value of type TableViewCell has no member presentViewController
然后,我尝试了
self.window?.rootViewController!.presentViewController(vc, animated: true, completion: nil)
Error: Warning: Attempt to present whose view is not in the window hierarchy!
我做错了什么?我应该怎么做才能从 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)
}
I receive error: Presenting view controllers on detached view controllers is discouraged
(请注意,我在 TableView 后面有一个 NavBar 和 TabBar 链。)
我也试过了
self.parentViewController!.presentViewController(vc, animated: true, completion: nil)
同样的错误。
也试过了,
self.view.window?.rootViewController?.presentViewController(vc, animated: true, completion: nil)
同样的错误
您应该使用 protocol
将操作传递回 tableViewController
1) 在您的单元格 class
中创建一个 protocol
2) 让 button
动作调用你的 protocol
func
3) Link 你的 cell's protocol
在 tableViewController
by cell.delegate = self
4) 实施 cell's protocol
并在其中添加您的代码
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
您似乎已经有了这样的想法:要呈现视图控制器,您需要一个视图控制器。所以这是你需要做的:
- 创建一个协议,通知单元的控制器按钮已被按下。
- 在您的单元格中创建一个 属性,其中包含对实现您的协议的委托的引用。
- 在按钮操作内对您的委托调用协议方法。
- 在你的视图控制器中实现协议方法。
- 配置单元格时,将视图控制器作为委托传递给单元格。
这是一些代码:
// 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
//...
}
//...
}
所以self.presentViewController是来自ViewController的方法。
您收到此错误的原因是因为您所指的 "self" 是 tableViewCell。而且 tableViewCell 没有 presentViewController.
方法
我认为您可以使用以下选项:
1.add单元格中的委托和协议,当您单击按钮时,IBAction 将调用
self.delegate?.didClickButton()
然后在你的表VC中,你只需要实现这个方法并调用self.presentViewController
2.use 故事板和转场
在故事板中,从您的按钮拖动到您想要去的 VC。
我遇到了同样的问题,在 Whosebug 的某个地方找到了这段代码,但我不记得在哪里,所以它不是我的代码,但我会在这里展示它。
当我想从任何地方显示视图控制器时,这就是我使用的,它会提示 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)
}
我有一个表ViewController、TableViewCell 和一个ViewController。我在 TableViewCell 中有一个按钮,我想用 presentViewController
显示 ViewController(但 ViewController 在故事板上没有视图)。我尝试使用:
@IBAction func playVideo(sender: AnyObject) {
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
}
Error: Value of type TableViewCell has no member presentViewController
然后,我尝试了
self.window?.rootViewController!.presentViewController(vc, animated: true, completion: nil)
Error: Warning: Attempt to present whose view is not in the window hierarchy!
我做错了什么?我应该怎么做才能从 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)
}
I receive error: Presenting view controllers on detached view controllers is discouraged
(请注意,我在 TableView 后面有一个 NavBar 和 TabBar 链。)
我也试过了
self.parentViewController!.presentViewController(vc, animated: true, completion: nil)
同样的错误。
也试过了,
self.view.window?.rootViewController?.presentViewController(vc, animated: true, completion: nil)
同样的错误
您应该使用 protocol
将操作传递回 tableViewController
1) 在您的单元格 class
中创建一个protocol
2) 让 button
动作调用你的 protocol
func
3) Link 你的 cell's protocol
在 tableViewController
by cell.delegate = self
4) 实施 cell's protocol
并在其中添加您的代码
let vc = ViewController()
self.presentViewController(vc, animated: true, completion: nil)
您似乎已经有了这样的想法:要呈现视图控制器,您需要一个视图控制器。所以这是你需要做的:
- 创建一个协议,通知单元的控制器按钮已被按下。
- 在您的单元格中创建一个 属性,其中包含对实现您的协议的委托的引用。
- 在按钮操作内对您的委托调用协议方法。
- 在你的视图控制器中实现协议方法。
- 配置单元格时,将视图控制器作为委托传递给单元格。
这是一些代码:
// 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
//...
}
//...
}
所以self.presentViewController是来自ViewController的方法。 您收到此错误的原因是因为您所指的 "self" 是 tableViewCell。而且 tableViewCell 没有 presentViewController.
方法我认为您可以使用以下选项: 1.add单元格中的委托和协议,当您单击按钮时,IBAction 将调用
self.delegate?.didClickButton()
然后在你的表VC中,你只需要实现这个方法并调用self.presentViewController
2.use 故事板和转场 在故事板中,从您的按钮拖动到您想要去的 VC。
我遇到了同样的问题,在 Whosebug 的某个地方找到了这段代码,但我不记得在哪里,所以它不是我的代码,但我会在这里展示它。
当我想从任何地方显示视图控制器时,这就是我使用的,它会提示 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)
}