IQKeyboardManager是键盘管理库,当开启他时,可以在键盘出现时,自动把输入框向上移动到键盘之上,实现原理是把整个页面向上移动,在底部加上键盘高度,这样就导致有些不想想上移动的,想要固定的view被往上移动(可能出现在视野外)。本文介绍两种方式解决。
使用IQKeyboardManager
pod依赖
pod 'IQKeyboardManagerSwift'
在应用启动的地方(AppDelegate)启用 IQKeyboardManager
//导入
import IQKeyboardManagerSwift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
IQKeyboardManager.shared.enable = true
return true
}
向上偏移问题解决 方式一
主要应该用这个方式。
把UITextFiled或者UITextView放到UIScrollView上,这样移动的就是UIScrollView,不会影响其他地方view的位置。这也是正常用法。
一个简单例子:
import SnapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let scrollView = UIScrollView()
view.addSubview(scrollView)
scrollView.alwaysBounceVertical = true
scrollView.snp.makeConstraints {
make in
make.edges.equalToSuperview()
}
let textView = UITextView()
scrollView.addSubview(textView)
textView.backgroundColor = .yellow
textView.snp.makeConstraints {
make in
make.height.width.equalTo(300)
make.top.equalToSuperview().offset(300)
}
let textView2 = UITextField()
scrollView.addSubview(textView2)
textView2.backgroundColor = .red
textView2.snp.makeConstraints {
make in
make.height.width.equalTo(200)
make.top.equalTo(textView.snp.bottom).offset(100)
make.bottom.equalToSuperview()
}
let topView = UIView()
view.addSubview(topView)
topView.backgroundColor = .black
topView.snp.makeConstraints {
make in
make.leading.trailing.top.equalToSuperview()
make.height.equalTo(100)
}
}
}
向上偏移问题解决 方式二
有些时候项目所迫,输入框就是不能放到UIScollView之上,只能出此下策。
监听根view的frame改变,获知更view偏移量,把要固定的view往反方向偏移的方式,解决页面上移问题。需要注意的是,如果阻止页面根view偏移会导致异常,我尝试了,所以本文用了覆盖frame而不是kvo去监听frame变化。
监听根view的frame变化,这里其实可以用KVO,但是还是用了替换view覆盖属性的方案:
自定义根view 覆盖 frame函数
let kKeybordHeightChangeNoti = NSNotification.Name.init("kKeybordHeightChangeNoti")
override var frame: CGRect {
didSet {
NotificationCenter.default.post(name: kKeybordHeightChangeNoti, object: frame.origin.y)
super.frame = frame//UIScreen.main.bounds
}
}
重写vc的loadVIew替换成上面那个自定义view
override func loadView() {
view = TestView()
}
在vc监听变化:
NotificationCenter.default.addObserver(self, selector: #selector(change(noti:)), name: kKeybordHeightChangeNoti, object: nil)
把想要固定的view,向下偏移(30是view该在屏幕上的位置的偏移量)
@objc func change(noti:Notification) {
if let height = noti.object as? CGFloat {
topView.top = -height + 30
}
}