swift -> 监听 键盘 事件获取 键盘 高度

一, 在viewDidload() 中 绑定通知,并添加键盘监听

其中绑定的 keyboardWillShow 会有动画, KeyboardDidShow 不会有 动画

func viewDidload(){
	NotificationCenter.default.addObserver(self, selector: #selector(PasscodePane.keyboardWillHide(_:)),name:NSNotification.Name.UIKeyboardWillHide, object: nil)
	NotificationCenter.default.addObserver(self, selector: #selector(PasscodePane.keyboardWillShow(_:)),name:NSNotification.Name.UIKeyboardWillShow, object: nil)
}

//释放
deinit {
	NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
	NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}

func keyboardWillShow(_ sender: Notification) {
	//获取键盘的frame
	guard let keyboardFrame = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue else {
		return
	}
	//如果边框=0也返回
	if(keyboardFrame.height == nill || keyboardFrame.height == 0){return;}
	UIView.animate(withDuration: 0.1, animations: {
		self.containerCenterConstraint?.update(offset: -keyboardFrame.height/2)
		self.layoutIfNeeded()
	})
}

func keyboardWillHide(_ sender: Notification) {
	UIView.animate(withDuration: 0.1, animations: {
		self.containerCenterConstraint?.update(offset: 0)
		self.layoutIfNeeded()
	})
}

 ** 解决有时 或 第三方输入 触发 3次 或 多次 通知 的问题

原理是 获取 1秒 内获取到的最新的高度 ,并 1秒后才更新 UI 

    var keyb_ht:CGFloat = 0;
    var getKbHt_time_over:Bool = true;
    //机制: 1秒内 获取 到 的最后一次 高度 才 更新 UI , 从 第一次 触发 开始 或  1秒之后  再 触发的 第一次 开始
    func keyboardWillShow(aNotification: NSNotification) {
        let userinfo: NSDictionary = aNotification.userInfo! as NSDictionary
        let nsValue = userinfo.object(forKey: UIKeyboardFrameEndUserInfoKey)
        let keyboardRec = (nsValue as AnyObject).cgRectValue
        let key_height = keyboardRec?.size.height
        if(key_height == 0){
            return;
        }
        //更新当前最新的高度
        keyb_ht = key_height!;
        //如果 1秒 延迟 执行UI 还没有 执行 就返回
        if(getKbHt_time_over == false){
            print("111")
            return;
        }
        print("222")
        getKbHt_time_over = false;
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {//1秒之后才执行
            print("333")
            //update ui
            self.kb_top_view?.frame.origin.y = screenHeight - self.keyb_ht - self.kb_top_view_ht;
            self.getKbHt_time_over = true;
        }
    }

   

在执行动画的时候如果遇到 设置 动画时间无效 可用异步

DispatchQueue.main.async{ 

参考 : https://stackoverflow.com/questions/37805885/how-to-create-dispatch-queue-in-swift-3

** 输入框默认获得 焦点

textField.becomeFirstResponder()

 

**  火狐浏览器 关于 该方法 的 使用 源代码

class PasscodePane: UIView {
    let codeInputView = PasscodeInputView(passcodeSize: 4)

    var codeViewCenterConstraint: Constraint?
    var containerCenterConstraint: Constraint?

    fileprivate lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.font = UIConstants.DefaultChromeFont
        label.isAccessibilityElement = true
        return label
    }()

    fileprivate let centerContainer = UIView()

    override func accessibilityElementCount() -> Int {
        return 1
    }

    override func accessibilityElement(at index: Int) -> Any? {
        switch index {
        case 0:     return titleLabel
        default:    return nil
        }
    }

    init(title: String? = nil) {
        super.init(frame: CGRect.zero)
        backgroundColor = UIConstants.TableViewHeaderBackgroundColor

        titleLabel.text = title
        centerContainer.addSubview(titleLabel)
        centerContainer.addSubview(codeInputView)
        addSubview(centerContainer)

        centerContainer.snp.makeConstraints { make in
            make.centerX.equalTo(self)
            containerCenterConstraint = make.centerY.equalTo(self).constraint
        }

        titleLabel.snp.makeConstraints { make in
            make.centerX.equalTo(centerContainer)
            make.top.equalTo(centerContainer)
            make.bottom.equalTo(codeInputView.snp.top).offset(-PasscodeUX.TitleVerticalSpacing)
        }

        codeInputView.snp.makeConstraints { make in
            codeViewCenterConstraint = make.centerX.equalTo(centerContainer).constraint
            make.bottom.equalTo(centerContainer)
            make.size.equalTo(PasscodeUX.PasscodeFieldSize)
        }
        layoutIfNeeded()
        NotificationCenter.default.addObserver(self, selector: #selector(PasscodePane.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(PasscodePane.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    }

    func shakePasscode() {
        UIView.animate(withDuration: 0.1, animations: {
                self.codeViewCenterConstraint?.update(offset: -10)
                self.layoutIfNeeded()
        }, completion: { complete in
            UIView.animate(withDuration: 0.1, animations: {
                self.codeViewCenterConstraint?.update(offset: 0)
                self.layoutIfNeeded()
            }) 
        }) 
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    }
    
    func keyboardWillShow(_ sender: Notification) {
        guard let keyboardFrame = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue else {
            return
        }
        
        UIView.animate(withDuration: 0.1, animations: {
            self.containerCenterConstraint?.update(offset: -keyboardFrame.height/2)
            self.layoutIfNeeded()
        })
    }
    
    func keyboardWillHide(_ sender: Notification) {
        UIView.animate(withDuration: 0.1, animations: {
            self.containerCenterConstraint?.update(offset: 0)
            self.layoutIfNeeded()
        })
    }
}

猜你喜欢

转载自mft.iteye.com/blog/2377203