当键盘消失时,增加Tableview的高度?

时间:2018-05-22 04:26:40

标签: ios swift uitableview tableview

我想在键盘消失时增加tableview的高度。我有一个从底部向上填充的tableview。 tableview没有完全填充数据,这意味着tableview顶部有一些空白区域。 tableview中会有一些单元格。由于表格视图从底部向上填充,因此这些单元格应朝向tableview的底部。显示键盘时,tableview的总高度约为屏幕的一半。当键盘消失时,tableview的总高度几乎应该是整个屏幕。这意味着当键盘消失时,单元格应该从屏幕上的更下方开始。

当tableview中有两个单元格时,这就是它的样子:

enter image description here

这是在将两个以上的单元格添加到tableview时的样子:

enter image description here

这是键盘消失时的样子:

enter image description here

当键盘消失时,四个单元格应从屏幕底部开始,而不是从屏幕的一半开始。四个单元格应该向下移动,以便它们从屏幕底部的灰线开始。第一个单元格(表示“Apple”)与屏幕底部的灰色线条之间的距离应该不大。同时,tableView本身应该更大。这意味着虽然tableview的顶部保持在同一位置,但tableview的底部现在比之前更低,因为键盘现在不占据大约一半的屏幕。我怎样才能做到这一点?感谢。

这是我现在的代码:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var lowerGrayLine: UIView!

    @IBOutlet weak var tableView: UITableView!

    var fruits = [FruitModel]()

    override func viewDidLoad() {
        super.viewDidLoad()

        //Adjust height of the lower Gray Line
        lowerGrayLine.frame.origin.y = 411

        //No dividing lines in the tableview initially
        self.tableView.separatorStyle = .none

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 140

        if (self.tableView(self.tableView, numberOfRowsInSection: 0) > 0) 
        {
            self.updateTableContentInset()
        }

        // Allow for keyboard dismissal
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.dismissKeyboard))
        view.addGestureRecognizer(tap)

        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

        // Show keyboard
        textField.becomeFirstResponder()
    }

    func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            //Adjust text box, and dividing line placement
            textField.frame.origin.y = 416
            lowerGrayLine.frame.origin.y = 411
        }
    }

    func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            textField.frame.origin.y = 597
            lowerGrayLine.frame.origin.y = 557
        }
    }

    //Calls this function when the tap is recognized.
    func dismissKeyboard() {
        //Causes the view (or one of its embedded text fields) to resign the first responder status.
        view.endEditing(true)
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.fruits.count;
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellIdentifier = "fruitCell"
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? FruitTableViewCell else {
            fatalError("The dequeued cell is not an instance of FruitTableViewCell.")
        }

        var fruitName = fruits[indexPath.row]
        var fruitNamename = fruitName.name

        var colon = ":"

        cell.nameLabel.text = fruitNamename + colon

        cell.fruitLabel.text = fruitName.fruit

        //Make some adjustments to make a line appear when a fruitCell is actually being shown
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsets.zero
        cell.layoutMargins = UIEdgeInsets.zero

        // This causes the bottom-most cell to not have a cell separator 
        if (indexPath.row == fruits.count-1) {
            cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0);
        }
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    // Adjust the tableView
    func updateTableContentInset() {
        let numRows = tableView(tableView, numberOfRowsInSection: 0)

        var contentInsetTop = tableView.bounds.size.height
        for i in 0..<numRows {
            contentInsetTop -= tableView(tableView, heightForRowAt: IndexPath(item: i, section: 0))
            if contentInsetTop <= 0 {
                contentInsetTop = 0
            }
        }
        self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0)
        self.tableView.scrollToRow(at: IndexPath(item: numRows-1, section: 0), at: .bottom, animated: false)
        //Prevent scrolling
        self.tableView.bounces = false;
        //When we have actual fruit Cells to show, we want the line divisions
        self.tableView.separatorStyle = .singleLine
    }
}

我尝试将以下代码添加到我的keyboardWillShow函数中:

var tableViewFrame: CGRect!
tableViewFrame = self.tableView.frame
tableViewFrame.size.height += 146.0
tableView.frame = tableViewFrame
tableView.contentInset = UIEdgeInsetsMake(146.0, 0, 0, 0);

但是,当键盘消失时,屏幕上会出现水平灰线,如下所示:

修改

enter image description here

这些水平灰线(总共六条)不应该在那里。当键盘消失时,如何防止它们出现?

3 个答案:

答案 0 :(得分:0)

为此,您需要在keyboardWillHide中编写代码:

  1. 调整<{>}增加框架的高度(或相对约束的常量值)键盘的高度;

  2. 关键点:将tableView的顶级内容插入设置为等于键盘的高度。

  3. 因此,例如,如果键盘的高度为216pt,您将执行以下操作:

    tableView

    如果您使用约束,唯一的区别是您将相对于CGRect tableViewFrame = tableView.frame; tableViewFrame.size.height += 216.0; tableView.frame = tableViewFrame; tableView.contentInset = UIEdgeInsetsMake(216.0, 0, 0, 0); 的高度更改约束常量的高度。

    P.S。如果您想更深入地了解tableView是什么,请查看此处:https://developer.apple.com/documentation/uikit/uiedgeinsets 它们完全是为了创建具有特定偏移的空白空间。

答案 1 :(得分:0)

    func keyboardWillShow(notification:NSNotification) {

          if let keyboardSize = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
        let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: 
         keyboardSize.height, right: 0)
        print(contentInsets)


        btnBottomConstrain.constant = contentInsets.bottom
        UIView.animate(withDuration: 0.2, delay: 0, options: .transitionCurlDown, animations: {
            self.view.layoutIfNeeded()
        }, completion: nil)

    }
}

func keyboardWillHide(notification:NSNotification) {



    if let keyboardSize = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
        let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
        print(contentInsets)

        self.btnBottomConstrain.constant = 0

        UIView.animate(withDuration: 0.2, delay: 0, options: .transitionCurlDown, animations: {
            self.view.layoutIfNeeded()
        }, completion: nil)


    }
}

相应地用您的keyboardshow和keybordhide方法替换这两个方法。这里btnBottomConstrain将成为tableview底部约束的出口。我希望这对你有用。

答案 2 :(得分:0)

最简单的解决方案是IQKeyboardManager。这将为您管理键盘下方的空间。

否则,在表视图中添加底部约束tableViewBottomConstraint。设置其初始值tableViewBottomConstraint.constant = 0

现在设定它等于keyboardWillShow keyboardWillHide

中的键盘高度+填充
func keyboardWillShow(notification: NSNotification) {
    tableViewBottomConstraint.constant = keyboardHeight + padding
    layoutTableView()
}

func keyboardWillHide(notification: NSNotification) {
    tableViewBottomConstraint.constant = 0
    layoutTableView()
}

private func layoutTableView() {
    UIView.animate(withDuration: 0.3, animations: {
        tableView.superview?.layoutIfNeeded()
    }, completion: nil) 
}