swift - 解决键盘遮挡tableView中输入框的问题

核心思想:  

改变tableView控件的显示高度

解决步骤:

步骤一(监听键盘“出现”和“遮挡”事件):创建TableViewController.swift文件,在其中创建tableView控件,并监听键盘“出现”和“遮挡”的事件:“NotificationCenter.default.addObserver()”,同时要记得在实例对象销毁时删除对应的监听者:“NotificationCenter.default.removeObserver()”

import UIKit

class TableViewController: UIViewController {
    private var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 创建tableView
        self.createTableView()
        
        // 添加监听
        NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow), name: UIResponder.keyboardDidShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide), name: UIResponder.keyboardDidHideNotification, object: nil)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        
        // 刷新tableView的数据
        self.tableView.reloadData()
    }
    
    func createTableView() {
        // 添加tableView控件
        self.tableView = UITableView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
        // 注册tableviewCell复用池
        self.tableView.register(TableViewControllerCell.self, forCellReuseIdentifier: "cell")
        // 设置代理
        self.tableView.delegate = self
        // 设置数据源
        self.tableView.dataSource = self
        
        self.view.addSubview(self.tableView)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
}

步骤二(在监听方法中完成屏幕滑动,避免输入框被遮挡的问题):TableViewController.swift文件中,添加监听键盘事件的方法,代码如下:

class TableViewController: UIViewController {

    // 监听键盘出现事件
    @objc func keyBoardWillShow(_ notification: NSNotification) {
        // 获取键盘高度
        let info = notification.userInfo
        let keyBoardHeight = (info![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.size.height

        // 屏幕滑动
        self.tableView.frame.size.height = UIScreen.main.bounds.height - keyBoardHeight
    }

    // 监听键盘隐藏事件
    @objc func keyBoardWillHide() {
        // 屏幕恢复整屏
        self.tableView.frame.size.height = UIScreen.main.bounds.height
    }
    
}

步骤三(实现textView的代理方法,点击键盘右下角return,键盘消失):代码如下

extension TableViewController: UITextViewDelegate {
    
    // 点击键盘“return”使输入框失去响应,键盘隐藏
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if text == "\n" {
            textView.resignFirstResponder()
        }
        
        return true
    }
}

步骤四(补充显示tableView的其他代码:自定义cell类 + tableView的渲染代码)代码如下

// 自定义TableViewCell类,以便使用“复用”特性
class TableViewControllerCell: UITableViewCell {
    var titleLabel = UILabel()
    var textView = UITextView()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: .value1, reuseIdentifier: nil)
        
        // 设置label控件
        self.titleLabel.frame = CGRect(x: 20, y: 15, width: 60, height: 40)
        self.titleLabel.backgroundColor = .yellow
        self.contentView.addSubview(self.titleLabel)
        
        // 设置textView控件
        self.textView.frame = CGRect(x: 100, y: 10, width: 200, height: 40)
        self.contentView.addSubview(self.textView)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}
extension TableViewController: UITableViewDelegate, UITableViewDataSource {
    // 设置tableView的Section数量
    func numberOfSections(in tableView: UITableView) -> Int {
        return 15
    }

    // 设置tableView每一个section的行数
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    // 渲染tableView每一行的内容
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 复用tableViewCell
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewControllerCell
        
        // 设置每一行的标题
        cell.titleLabel.text = "第" + String(indexPath.section) + "行"
        // 设置textView的代理
        cell.textView.delegate = self
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 65
    }
    
}

结果:

​​​​​​​1)有遮挡时,屏幕自动滑动,显示正常。

2)无遮挡时,屏幕不滑动,显示正常。

3)键盘弹起后,仍不影响tableView的滑动,这是使用tableView.setContentOffset()方法无法做到的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值