Создание textView в ячейке collectionView как firstResponder при навигации по ячейкам

У меня есть collectionView, и я разрешаю пользователю динамически добавлять ячейки в collectionView. Контроллер представления показывает только одну ячейку за раз, и я хочу, чтобы первый textView (который является частью ячейки) стал первым ответчиком (и постоянно поддерживал видимость клавиатуры), который отлично работает при загрузке контроллера представления (а также как в одном из случаев ниже).

Я создал метод для определения текущей ячейки, который я вызываю каждый раз в любом из следующих случаев: (1) пользователь прокручивает от одной ячейки к другой (метод помещен в scrollViewWillEndDragging), (2) пользователь нажимает UIButtons для перехода из одной ячейки к другому (3) пользователь нажимает UIButton, чтобы создать и добавить новую ячейку в конец массива (который используется collectionView).

Это метод:

func setNewFirstResponder() {
    let currentIndex = IndexPath(item: currentCardIndex, section: 0)
    if let newCell = collectionView.cellForItem(at: currentIndex) as? AddCardCell {
        newCell.questionTextView.becomeFirstResponder()
    }
}

Теперь моя проблема в том, что это работает только в случае (1). Видимо у меня нет ячейки типа AddCardCell в случаях (2) и (3). Когда я печатаю currentCardIndex, я получаю один и тот же результат во всех случаях, что очень сбивает с толку.

Любые подсказки, почему я еще не смог получить ячейку в случаях 2 и 3, но я в случае 1?

В качестве справки вот некоторые из методов, которые я использую:

//Update index and labels based on user swiping through card cells
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    //Update index based on targetContentOffset
    let x = targetContentOffset.pointee.x
    currentCardIndex = Int(x / view.frame.width)

    setNewFirstResponder()
}

И другой способ, от которого не работает (случай 3):

//Method to add a new cell at end of collectionView
@objc func handleAddCell() {
    //Inserting a new index path into tableView
    let newIndexPath = IndexPath(item: autoSaveCards.count - 1, section: 0)
    collectionView.insertItems(at: [newIndexPath])

    collectionView.scrollToItem(at: newIndexPath, at: .left, animated: true)
    currentCardIndex = autoSaveCards.count - 1

    setNewFirstResponder()
}

person rantanplan    schedule 05.06.2018    source источник


Ответы (1)


Что касается случая 2,3, я думаю, что ячейка еще не загружена, поэтому if let терпит неудачу, вы можете попытаться отправить ее через некоторое время, а также общее примечание, если ячейка не видна, тогда она равна нулю

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
   setNewFirstResponder()  
}

Также это может работать, если вы установите animated:false на scrollToItem

person Sh_Khan    schedule 05.06.2018
comment
Это отличный маленький хак и работает, спасибо! Однако мне непонятно, почему в случае (2) клетки еще не существовало бы? Он был создан ранее - есть идеи, почему? - person rantanplan; 06.06.2018
comment
Продолжая это - возможно ли, что, не отказываясь от первых респондентов, я могу столкнуться с проблемами пользовательского интерфейса с моими ячейками collectionView? Похоже, что при использовании метода отправки мои ячейки отображаются неправильно (при навигации по ним они часто исчезают), тогда как, когда я полностью отказываюсь от первых ответчиков (что означает, что между просмотром каждой ячейки клавиатура полностью исчезает), ячейка отображается правильно . - person rantanplan; 06.06.2018
comment
Это может быть изолированная проблема, поэтому я разместил еще один вопрос: stackoverflow.com/questions/50715980/ - person rantanplan; 06.06.2018