一, 在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()
})
}
}
所有评论(0)