Apple TV - как реализовать выделение липкой фокусировки, как в UISegmentedControl? - PullRequest
0 голосов
/ 30 октября 2019

Как в пользовательском элементе управления реализовать липкий выбор фокуса, как это видно в UISegmentedControl, UITabBar, UITableView или UICollectionView? Под «закрепленным выделением» я подразумеваю автоматическое переключение фокуса на последний сфокусированный / выбранный элемент при фокусировке в контейнер.

Как UISegmentedControl + другие реализуют это самостоятельно? Я попытался проверить UISegmentedControl и с удивлением обнаружил, что это один большой фокусируемый элемент, а не группа фокусируемых сегментов. Я не смог выяснить, как UISegmentedControl может переключать фокус между сегментами, учитывая его архитектуру.

Пока что у меня есть обходной путь:

На уровне экрана поддерживайте каждый липкий выбор. Например, если на экране есть два пользовательских верхних меню, экран поддерживает два активных выбора. Переопределите shouldUpdateFocus, чтобы обнаружить изменения фокуса в контейнере / меню с липким выбором. Возврат false + вызов setNeedsFocusUpdate в сочетании с переопределением предпочитаемых предпочтений для фокуса, чтобы вместо этого перенаправить фокус на липкое / выбранное подпредставление.

Мое решение работает, но неудовлетворительно для написания настраиваемых пользовательских интерфейсов многократного использования, которые автоматически поддерживают липкие выделения. Apple удалось создать несколько таких пользовательских интерфейсов, поэтому я должен упустить какой-то метод.

1 Ответ

0 голосов
/ 11 ноября 2019

Я нашел метод, который работает для многоразовых элементов управления:

Окружить элемент управления в UIFocusGuide . Затем просто используйте UIFocusGuide.preferredEnvironments, чтобы определить, какое подпредставление получает фокус, когда фокус смещается на контейнер.

Существует предостережение, что если подпредставления контейнера заполняют контейнер, подпредставления будут выполняться вместо направляющей фокуса контейнера, окружающего,Итак, в целом, у меня есть:

    self.focusGuide = UIFocusGuide()
    let focusGuideExpansion: CGFloat = 1
    self.addLayoutGuide(focusGuide)
    focusGuide.leadingAnchor.constraint(equalTo:self.leadingAnchor, constant:-focusGuideExpansion).isActive = true
    focusGuide.trailingAnchor.constraint(equalTo:self.trailingAnchor, constant:focusGuideExpansion).isActive = true
    focusGuide.topAnchor.constraint(equalTo:self.topAnchor, constant:-focusGuideExpansion).isActive = true
    focusGuide.bottomAnchor.constraint(equalTo:self.bottomAnchor, constant:focusGuideExpansion).isActive = true

    // default to focusing on the first subview
    focusGuide.preferredFocusEnvironments = [subviews.first!]
...