UITableView прокручивается в неправильное положение, когда отображается клавиатура

#ios #uitableview #uiscrollview #uikit

Вопрос:

Хотя UITableViewController можно автоматически настраивать представление таблицы при отображении клавиатуры, оно недостаточно гибкое. Я пытаюсь использовать UIViewController и UITableView для создания своего пользовательского интерфейса.

В табличном представлении много ячеек. Среди всех ячеек есть ячейка с а UITextField . Когда я касаюсь этого текстового поля, отображается клавиатура, а представление таблицы ничего не делает, даже если ячейка перекрыта клавиатурой. Это нормально, потому что это ожидаемый результат.

Происходит странная вещь. Если я дам представление таблицы большим contentInset.bottom , например contentInset.bottom = 600 , представление таблицы будет автоматически прокручиваться при отображении клавиатуры.

Я стараюсь использовать авиод tableView.contentInsetAdjustmentBehavior = .never .

Следующий код показывает это странное поведение. Его можно воспроизвести на iOS 14.5, мини-симуляторе iPhone 12.

 class TestViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    let tableView = UITableView()
    
    override func loadView() {
        view = tableView
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.contentInset.bottom = 600
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("scrolling contentOffset-Y: (scrollView.contentOffset.y)")
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Ugly code, only for showing the problem.
        let cell = UITableViewCell()
        if indexPath.row == 9 {
            let textField = UITextField()
            cell.contentView.addSubview(textField)
            textField.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                textField.leadingAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.leadingAnchor),
                textField.trailingAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.trailingAnchor),
                textField.topAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.topAnchor),
                textField.bottomAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.bottomAnchor),
            ])
        } else {
            cell.textLabel?.text = "(indexPath)"
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60
    }
}
 

Ответ №1:

Вы должны добавить делегат UITextField в текстовое поле в ячейке tableview, чтобы проверить, запущена ли клавиатура, и позволить ей проверить вас, как показано в примере ниже:

 func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
        var pointInTable:CGPoint = textField.superview!.convertPoint(textField.frame.origin, toView:_tableview)
        var contentOffset:CGPoint = _tableview.contentOffset
        contentOffset.y  = pointInTable.y
        if let accessoryView = textField.inputAccessoryView {
            contentOffset.y -= accessoryView.frame.size.height
        }
        _tableview.contentOffset = contentOffset
        return true;
    }
 

Надеюсь, это поможет.