【问题标题】:presentViewController from TableViewCell来自 TableViewCell 的 presentViewController
【发布时间】:2016-04-26 22:43:40
【问题描述】:

我有一个 TableViewController、TableViewCell 和一个 ViewController。我在 TableViewCell 中有一个按钮,我想向 ViewController 展示presentViewController(但 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)

同样的错误

【问题讨论】:

  • 该按钮是否意味着辅助(例如,附件视图)选择​​?

标签: ios swift uitableview tableview tableviewcell


【解决方案1】:

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

1) 在你的单元格类中创建一个protocol

2) 让button 操作调用您的protocol 函数

3) 通过cell.delegate = self 将您的cell's protocol 链接到tableViewController

4) 实现cell's protocol 并在那里添加您的代码

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

【讨论】:

  • 我收到错误,不鼓励在分离的视图控制器上显示视图控制器。它的后记崩溃了。我做错了什么?
  • @senty 你可以在问题中添加你的代码,以便我可以看到你的代码
  • 我更新了问题并添加了当前代码。你能查一下吗?
  • @senty 我看不出代码结构中的任何问题会导致Presenting view controllers on detached view controllers is discouraged,但你应该检查你的代码并搜索错误
【解决方案2】:

您似乎已经知道要呈现视图控制器,您需要一个视图控制器。所以这就是你需要做的:

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

这里有一些代码:

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

        //...
    }
//...
}

【讨论】:

  • 使用这种方法,我收到:不鼓励在分离的视图控制器上呈现视图控制器。我没有演示 ViewController() 的情节提要文件
  • 我有一种预感,如果您的 TableViewController 以模态方式呈现而不是被推送到导航堆栈上,您将收到此错误。如果我被误导了,请纠正我。
  • 它现在可以工作了,但是看起来不太好(因为我在下拉时使用了 presentViewController 然后dismissViewController,但是当我拉下视图时,该视图后面全是黑色的,并且当它完全关闭时,它会再次显示表格视图。)所以关于你的评论,它可以正常工作..我不确定除了 presentViewController 之外的其他情况......
  • 正确方法!!
【解决方案3】:

所以 self.presentViewController 是 ViewController 的一个方法。 您收到此错误的原因是因为您所指的“自我”是 tableViewCell。而且tableViewCell没有presentViewController的方法。

我认为您可以使用一些选项: 1.在单元格中添加一个委托和协议,当你点击按钮时,IBAction会调用

self.delegate?.didClickButton()

那么在你的tableVC中,你只需要实现这个方法并调用self.presentViewController

2.使用故事板和转场 在情节提要中,从您的按钮拖动到您想去的 VC。

【讨论】:

  • 这种方法不能解决我的问题。请检查我更新的问题
【解决方案4】:

我遇到了同样的问题,并在 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)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多