Как вы заставляете контроллер представления вызывать предпочитаемый FocusView?

Итак, у меня есть контроллер представления, который имеет следующие методы:

    var viewToFocus: UIView? = nil {
        didSet {
            if viewToFocus != nil {
                self.setNeedsFocusUpdate()
                self.updateFocusIfNeeded()
            }
        }
    }

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

Так что, по сути, я могу заставить обновление фокуса к желаемому представлению, установив viewToFocus к значению, которое прекрасно работает в большинстве случаев. Тем не менее, при удалении подпредставления это не работает должным образом и preferredFocusedView никогда не называется.

С точки зрения моего подпредставления, это наложение, которое покрывает экран (не спрашивайте, почему я не использовал модал, были причины для этого) и имеет родительский контроллер представления в качестве делегата. Родительский контроллер представления имеет следующие методы:

// Delegate of 'OverlayView'. Called BEFORE it is added as a subview
func beforeOpeningOverlay() {
    focusedViewBeforeOverlay = UIScreen.mainScreen().focusedView
}

// Delegate of 'OverlayView'. Called after its close action is triggered.
func closedOverlay(overlay: OverlayView) {
    if focusedViewBeforeOverlay != nil {
        viewToFocus = focusedViewBeforeOverlay
        focusedViewBeforeOverlay = nil
    }
    overlay.delegate = nil
    overlay.removeFromSuperview()
}

По какой-то причине при вызове closedOverlay и focusedViewBeforeOverlay имеет допустимое представление, отличное от nil, оно никогда не будет сфокусированным на следующем представлении после удаления наложения из суперпредставления. Как я и сказал preferredFocusedView никогда не вызывается, и фокус вместо этого сосредотачивается на том, что двигатель фокуса решает, должен быть следующим фокусом.

Кто-нибудь знает, почему это может иметь место? Разве удаление подпредставления не позволяет запустить обновление фокуса?

Таким образом, порядок или, по крайней мере, ожидаемый порядок должен быть:

  1. Что-то срабатывает OverlayView быть воплощенным в жизнь
  2. beforeOpeningOverlay() вызывается, и в настоящее время сфокусированное представление установлено на focusedViewBeforeOverlay, Оверлей затем открывается и захватывает фокус
  3. Что-то вызывает закрытие наложения, вызывая closedOverlay()
  4. viewToFocus = focusedViewBeforeOverlay линия называется
  5. Обновление фокуса должно быть вызвано для родительского viewcontroller, вызывая его preferredFocusedView
  6. preferredFocusedView должен вернуться viewToFocus который был установлен на focusedViewBeforeOverlay и вернуть фокус обратно к виду, который был сфокусирован до открытия наложения

Кажется, проблема в том, что шаг 5 и далее не называется

1 ответ

Как прокомментировал Роман, referredFocusedView устарела в tvOS 10. Теперь вы должны определить свой preferredFocusEnvironments,

Это в вашем случае будет что-то вроде:

override var preferredFocusEnvironments: [UIFocusEnvironment] {
    if let focusEnviroment = self.viewToFocus { return [focusEnviroment] }
    return super.preferredFocusEnvironments
}

Вам также нужно позвонить self.setNeedsFocusUpdate() для обновления фокуса.

Другие вопросы по тегам