#ios #uicollectionview #focus #ios15
Вопрос:
Я создаю приложение, подобное фотографиям, в котором вы можете прокручивать миниатюры своих фотографий в a UICollectionView
, и вы можете нажать на одну из них, чтобы просмотреть эту фотографию в полноэкранном режиме, а затем проведите пальцем, чтобы перемещаться между фотографиями. Я работаю над добавлением поддержки навигации с клавиатуры, чтобы вы могли использовать клавиши со стрелками для выбора фотографии, нажимать пробел, чтобы просмотреть ее в полноэкранном режиме, использовать клавиши со стрелками для перемещения между фотографиями в полноэкранном режиме, а затем нажимать пробел, чтобы закрыть ее. Это хорошо работает в приложении «Фотографии», но в моем приложении, когда вы отключаете контроллер полноэкранного просмотра, фокус в базовом контроллере представления не обновляется до пути индекса фотографии, которую вы только что отклонили-очевидно, что он знает только путь индекса, который в последний раз был сфокусирован в этом контроллере представления, тот, который был сфокусирован до нажатия пробел. Похоже, мне нужно вручную переместить фокус на потенциально другой путь индекса, когда контроллер полноэкранного просмотра отключен. Как вам это удается?
Чтобы включить фокусировку, я устанавливаю их в UICollectionViewController
:
collectionView.allowsFocus = true
collectionView.allowsFocusDuringEditing = true
collectionView.remembersLastFocusedIndexPath = true
restoresFocusAfterTransition = true
Я попробовал следующее, но фокус не перемещается в эту ячейку, даже если я установил remembersLastFocusedIndexPath
и restoresFocusAfterTransition
false
:
cell.focusGroupPriority = .currentlyFocused
cell.setNeedsFocusUpdate()
cell.updateFocusIfNeeded()
cell.becomeFirstResponder()
Ответ №1:
Можно изменить путь к сфокусированному индексу, если путь к сфокусированному индексу уже существует.
Для этого реализуйте метод делегирования представления коллекции indexPathForPreferredFocusedView(in:)
, чтобы вернуть путь к индексу, на котором вы хотите сосредоточиться. Когда вы захотите изменить фокус, вызовите collectionView.setNeedsFocusUpdate()
, и эта функция будет вызвана системой, что даст вам возможность указать путь индекса для фокусировки. Примечание.Теперь iOS будет запрашивать у вашего приложения информацию о том, на каком пути индекса следует сосредоточиться изначально и по мере изменения состояний фокусировки. Вы можете вернуть ноль, чтобы система могла решить, на чем сосредоточиться.
Примечание. Вы не должны устанавливать collectionView.remembersLastFocusedIndexPath
значение в true
противном случае это не будет работать. Чтобы иметь такую функциональность, вам нужно будет вручную отслеживать последний используемый путь к индексам collectionView(_:didUpdateFocusIn:with:)
и возвращать его indexPathForPreferredFocusedView(in:)
.
func indexPathForPreferredFocusedView(in collectionView: UICollectionView) -> IndexPath? {
return lastFocusedIndexPath
}
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context: UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
lastFocusedIndexPath = context.nextFocusedIndexPath
}
private func moveFocus(to indexPath: IndexPath) {
lastFocusedIndexPath = indexPath
collectionView.setNeedsFocusUpdate()
//collectionView.updateFocusIfNeeded() //can update it now if you need it to
}