在 tvOS 10 GM 上打开 UIAlertController 时焦点消失

Focus disappearing when opening a UIAlertController on tvOS 10 GM

我想在 UIViewController 的顶部显示一个 UIAlertController,里面有一个 UICollectionView。集合视图需要关注启动,所以我覆盖了preferredFocusableView变量如下:

override var preferredFocusedView: UIView? {
    return self.collectionView
}

使用 tvOS 9 一切正常:警报控制器正确打开,我可以选择显示的 UIAlertAction 之一。

在 tvOS 10 Golden Master 上,打开警报控制器并滚动到另一个操作后,焦点从屏幕上消失,我无法滚动到其他操作或点击 Siri Remote 的菜单按钮。该应用程序仍然停留在警报控制器中,当我尝试滚动到其他操作但屏幕上没有任何反应时,我可以听到滚动的声音。我必须强制退出应用程序并重新打开它。

这是应用程序的代码。我尝试将 preferredFocusableView 设置为 alertController.preferredFocusedView 或通过删除集合视图的焦点方法但没有结果。

var alertController : UIAlertController?

func showAlert() {

    alertController = UIAlertController(title:"Example title", message: "Example description", preferredStyle: .Alert)

    let action1 = UIAlertAction(title: "Option 1", style: .Default) { (action : UIAlertAction) -> Void in
        //call to another method
    }

    // action2, action3, action4...

    let action5 = UIAlertAction(title: "Option 5", style: .Default) { (action : UIAlertAction) -> Void in
        //call to another method
    }

    let actionDismiss = UIAlertAction(title: "Dismiss", style: .Destructive) { (action : UIAlertAction) -> Void in
        self.alertController!.dismissViewControllerAnimated(true, completion: nil)
    }

    alertController!.addAction(action1)
    alertController!.addAction(action2)
    alertController!.addAction(action3)
    alertController!.addAction(action4)
    alertController!.addAction(action5)
    alertController!.addAction(actionDismiss)

    alertController!.preferredAction = action1

    self.presentViewController(alertController!, animated: true, completion: nil)
}

override var preferredFocusedView: UIView? {
    if self.alertController != nil {
        return self.alertController!.preferredFocusedView
    } else {
        return self.collectionView
    }
}

您正在覆盖整个系统焦点引擎。试试这个:

// MARK: - Update Focus Helper
var viewToFocus: UIView? = nil {
    didSet {
        if viewToFocus != nil {
            self.setNeedsFocusUpdate()
            self.updateFocusIfNeeded()
        }
    }
}

override weak var preferredFocusedView: UIView? {
    if viewToFocus != nil {
        return viewToFocus
    } else {
        return super.preferredFocusedView
    }
}

然后将您的警报设置为您希望焦点更改到它时的视图:

viewToFocus = someView

Apple 刚刚回复了我的雷达:

Inside the attached application, you’re overwriting the functionality of UIScrollView in an extension to return true for canBecomeFocused(), which is the cause of these unexpected side effects. The focus seems to be disappearing when moving to a second UIAlertController option; however, it is actually transferring focus to the scroll view wrapped around the various components of the UIAlertController, since this is now allowed due to the extension mentioned above.

To solve this, create a custom subclass of UIScrollView to be used only in the instances where canBecomeFocused() must return true.