UITableView не смещается при прямом переходе от textField к textField

В настоящее время я борюсь с клавиатурой, покрывающей некоторые проблемы с текстовым полем в моем приложении для iPhone на базе Swift.

На этом изображении показана основная проблема (три верхних изображения показывают проблему, три нижних — то, что она должна делать):

Проблема с корректным смещением таблицы

Когда текстовое поле в tableViewCell редактируется, я хочу переместить всю таблицу и панель навигации вверх. Я могу сделать это с помощью приведенного ниже кода (фрагменты взяты из viewController):

var tableViewShiftedUp = false

...

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! QuantityTableViewCell

        let componentLocationQuantity = tableViewData[indexPath.row]

        if let locationString = componentLocationQuantity.location.valueForKey("location_name") as? String {
            cell.setCellContents(locationString, quantity: componentLocationQuantity.quantity.floatValue)
            cell.quantityLabel.delegate = self
        }

        //get stock level related to current build rate and lead time (good - green, warning - orange, urgent - red)
        let status = model.determineStockLevelStatus(component)
        cell.setQuantityLabelBackgroundStatusColor(status)

        if editingMode == true {
            cell.makeQuantityEditable()
        }

        //add control event to detect text change
        cell.quantityLabel.addTarget(self, action: #selector(quantityCellTextChanged(_:)), forControlEvents: UIControlEvents.EditingChanged)
        cell.quantityLabel.addTarget(self, action: #selector(quantityCellSelected(_:)), forControlEvents: UIControlEvents.EditingDidBegin)


        return cell
    }

...

//MARK: - UITextfield delegate
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)

        if tableViewShiftedUp == true {
            moveTable()
        }

    }

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

    func quantityCellSelected(textField: UITextField){
        if tableViewShiftedUp == false {
            moveTable()
        }
        //check table was moved
        print(tableView.frame.origin.y)
    }

    func hideKeyboard(){
        self.view.endEditing(true)
        if tableViewShiftedUp == true {
            moveTable()
        }
    }

    func moveTable(){
        if tableViewShiftedUp == true {
            animateTableViewMoving(false, moveValue: 250)
            animateNavigationBarMoving(false, moveValue: 250)
            tableViewShiftedUp = false
        } else {
            animateTableViewMoving(true, moveValue: 250)
            animateNavigationBarMoving(true, moveValue: 250)
            tableViewShiftedUp = true
        }
    }

    // moving the tableView
    func animateTableViewMoving (up:Bool, moveValue :CGFloat){
        let movementDuration:NSTimeInterval = 0.0
        let movement:CGFloat = ( up ? -moveValue : moveValue)
        UIView.beginAnimations( "animateView", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration )
        self.tableView.frame = CGRectOffset(self.tableView.frame, 0,  movement)
        UIView.commitAnimations()
    }
    // moving the navigationBar
    func animateNavigationBarMoving (up:Bool, moveValue :CGFloat){
        let movementDuration:NSTimeInterval = 0.0
        let movement:CGFloat = ( up ? -moveValue : moveValue)
        UIView.beginAnimations( "animateView", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration )
        self.midNavigationBar.frame = CGRectOffset(self.midNavigationBar.frame, 0,  movement)
        UIView.commitAnimations()
    }

И он отлично работает при переходе непосредственно к текстовому полю в tableView. Однако, когда я уже редактирую текстовое поле вне tableView, сдвиг вверх не происходит, и поэтому переключатель переключения выходит из синхронизации.

Я напечатал начало кадра tableView:

//check table was moved
print(tableView.frame.origin.y)

поэтому я могу видеть, что установлено для tableView, и при этом первом переходе от textField вне tableView к textField внутри tableView, это свойство, как я ожидаю, будет 134, однако оно все еще на 384 на экране, который печатает в следующий раз, когда он будет вызван.

Проблема не возникает при перемещении внутри ячеек в tableView.

Такое ощущение, что у меня какая-то проблема с состоянием гонки или мне не хватает какого-то вызываемого метода делегата, который сбрасывает все при переходе от одной ячейки к другой.

Помощь была бы отличной.


person SimonBarker    schedule 22.04.2016    source источник


Ответы (2)


Ознакомьтесь с этой библиотекой: https://github.com/michaeltyson/TPKeyboardAvoiding. Разработан так, чтобы клавиатура не мешала текстовым полям.

person oyalhi    schedule 22.04.2016
comment
Спасибо, в итоге остановился на IQKeyboardManager - не подумал искать библиотеку - person SimonBarker; 23.04.2016
comment
ОБНОВЛЕНИЕ к комментарию выше: IQKeyboardManager работал неправильно, поэтому попробовал TPKeyboardAvoiding, и он работал отлично. - person SimonBarker; 24.04.2016
comment
Рад, что это сработало для вас. Что не работало с IQKeyboardManager? Была ли ошибка или отсутствие функции? - person oyalhi; 24.04.2016
comment
Это только переместило представление таблицы настолько, чтобы была видна высота текстового поля. Я сделал представление таблицы очень коротким в качестве теста, а затем прокрутил ячейку слишком далеко, поэтому, прежде чем вы могли увидеть редактируемую ячейку, вам пришлось прокрутить назад, чтобы найти ячейку, все в 12px по высоте. - person SimonBarker; 24.04.2016

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

Вы можете следовать официальным инструкциям Apple:

person Alessandro Ornano    schedule 22.04.2016