为啥这个 UITableViewController 会模态地关闭?

Posted

技术标签:

【中文标题】为啥这个 UITableViewController 会模态地关闭?【英文标题】:Why does this UITableViewController dismiss modally?为什么这个 UITableViewController 会模态地关闭? 【发布时间】:2016-12-17 19:57:49 【问题描述】:

我有一个UITableViewController,当从一个屏幕呈现时,从右到左呈现标准的“显示”序列,当从另一个屏幕(UIViewController)呈现时,从底部模态呈现.在几个月前我问过的question 的帮助下,我让它正常工作(有截图)。

关键是创建从我的设置屏幕的UINavigationController 到共享UITableViewController 的segue,而不是从UITableViewCell 创建它。奇怪的是,即使它从右到左正确显示,关闭它也会模态地关闭它(从上到下)。

我正在将呈现的表格视图控制器设置为它正在呈现的UITableViewController 的代表,因此它将处理解雇。这是它实现的协议和扩展(Swift 2.3):

protocol DismissalDelegate : class 
    func selectionDidFinish(controller: UIViewController)


extension DismissalDelegate where Self: UIViewController 
    func selectionDidFinish(viewController: UIViewController) 
        self.dismissViewControllerAnimated(true, completion: nil)
    

我将它设置在呈现控制器中定义的 segue 中:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if segue.identifier == "goToLifts" 
        let destination = segue.destinationViewController as! LiftSelectionTableViewController
        destination.dismissalDelegate = self
     else 
        return
    

当用户做出选择时(在didSelectRowAtIndexPath中),呈现的表格视图控制器调用delegate?.selectionDidFinish(self)

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        guard (dismissalDelegate != nil ) else 
            return
        
        dismissalDelegate?.selectionDidFinish(self)
    

在呈现表视图控制器中调用此方法:

func selectionDidFinish(controller: LiftSelectionTableViewController) 
    self.dismissViewControllerAnimated(true, completion: nil)

我查看了 APIs 以展示视图控制器,但找不到任何公开选项来控制它的东西。 dismiss(animated:completion:) API 甚至说它是用于解除以模态方式呈现的视图控制器,但我看不出与解除有任何其他关系。

我怎样才能让这个东西以从我的UITableViewController(从右到左,然后从右到左)呈现时的相同方式消除,但在从另一个视图(UIViewController)呈现时保持模态行为?

【问题讨论】:

【参考方案1】:

我在这里有点困惑,看起来您正在使用委托,因为呈现视图控制器应该知道 LiftSelectionTableViewController 是如何呈现的。

所以在表格视图控制器中,你会有

func selectionDidFinish(viewController: UIViewController) 
    self.navigationController?.popViewControllerAnimated(true)

在另一个视图控制器中,你应该有

func selectionDidFinish(viewController: UIViewController) 
    self.dismissViewControllerAnimated(true, completion: nil)

如果我错了并且您不知道视图控制器是如何呈现的,那么我会尝试检查导航控制器上的顶部视图控制器是否呈现视图控制器。如果是则弹出视图控制器,如果不是则关闭视图控制器。

func selectionDidFinish(viewController: UIViewController) 
    if self.navigationController?.topViewController == viewController 
        self.navigationController?.popViewControllerAnimated(true)
     else 
        self.dismissViewControllerAnimated(true, completion: nil)
    

【讨论】:

@Jeffery,非常接近。它们都是 tableViewControllers。我尝试了您的两个建议,但行为是相同的。由于不清楚发生了什么,我编辑了我的问题和示例以使其更容易理解(你是对的,它并不像它本来可以的那样清楚)。看看,如果有什么不同,请告诉我。 我意识到我不需要在我的委托视图控制器中实现func selectionDidFinish(viewController:) 方法,因为如果它们符合协议,它们将自动在扩展中定义实现。因此,我将您的建议放入协议扩展中,并且有效!那是你建议我应该放的地方吗?

以上是关于为啥这个 UITableViewController 会模态地关闭?的主要内容,如果未能解决你的问题,请参考以下文章

如何呈现UICollectionViewController?

UINavigationController 中的仅横向 UIViewController

UIActionSheet 事件未触发

ReloadData (UITableView) 不起作用

从 xib 调用 viewController

使用导航按钮从 UITableView 中的选中元素返回数据