首页 > 解决方案 > 如何解除使用 contextForSegue 呈现的 WKInterfaceController?

问题描述

我有一个WKInterfaceControllerwith a WKInterfaceTable,其中列出了用户在我的应用程序中记录的一些事件。

用户可以点击表格的一行以查看有关该事件的更多详细信息。为了实现这一点,我已经覆盖contextForSegue(withIdentifier:in:rowIndex:)WKInterfaceController包含表格的 ,因此点击一行以模态方式在新的WKInterfaceController名为EventDetailController.

modal演示文稿在故事板上定义。我不能使用push演示文稿,因为WKInterfaceControllerwith是我的应用程序顶层WKInterfaceTable多个实例中的一个页面。WKInterfaceController

这是主要问题:

在 中EventDetailController,有一个删除按钮来销毁表格行所代表的记录。

当用户点击删除按钮时,我会显示一个警报,允许用户确认或取消删除操作。

一旦用户确认删除记录,我想关闭EventDetailController它,因为它不再相关,因为它代表已删除的记录。

这是点击删除按钮时调用的IBAction定义:EventDetailController

@IBAction func deleteButtonTapped(_ sender: WKInterfaceButton) {

    let deleteAction = WKAlertAction(title: "Delete", style: .destructive) {

        // delete the record

        // as long as the delete was successful, dismiss the detail view
        self.dismiss()
    }

    let cancelAction = WKAlertAction(title: "Cancel", style: .cancel) {
        // do nothing
    }

    presentAlert(withTitle: "Delete Event",
                 message: "Are you sure you want to delete this event?",
                 preferredStyle: .alert,
                 actions: [deleteAction, cancelAction])
}

问题是 watchOS 似乎不允许这样做。测试此代码时,EventDetailController不会关闭。相反,控制台中会记录一条错误消息:

[WKInterfaceController dismissController]:434: calling dismissController from a WKAlertAction's handler is not valid. Called on <Watch_Extension.EventDetailController: 0x7d1cdb90>. Ignoring

我尝试了一些奇怪的变通方法来试图诱使他们EventDetailController解除,例如在事件被删除时触发通知并EventDetailController从通知观察者调用的函数中解除通知,但这也不起作用。

在这一点上,我在想有一些正确的方法我应该能够关闭 a WKInterfaceController,或者换句话说,反转contextForSegue(withIdentifier:in:rowIndex:)呼叫,但我不知道它是什么。

当我dismiss()直接在IBAction, 而不是在WKAlertAction处理程序中调用时,它可以正常工作,但我不喜欢这种实现,因为它不允许用户先确认操作。

标签: watchkitwatchoswkinterfacetablewkinterfacecontroller

解决方案


我觉得自己像个白痴,但我想出了解决方案。

答案一直在 Apple 的WKInterfaceController.dismiss()文档中(强调):

当您想要关闭您以模态方式呈现的界面控制器时调用此方法。始终从 WatchKit 扩展的主线程调用此方法。

我所要做的就是调用self.dismiss()主线程。

这是删除操作的更新代码,现在可以按预期工作:

let deleteAction = WKAlertAction(title: "Delete", style: .destructive) {

    // delete the record

    // as long as the delete was successful, dismiss the detail view
    DispatchQueue.main.async {
        self.dismiss()
    }
}

希望这可以为其他人节省一些故障排除时间!


推荐阅读