最新消息:20190529 VPS服务器已从腾讯云香港换为Vultr新加坡,主题仍用朋友推荐的大前端D8

[已解决]iOS中进入页面后无故触发UIKeyboardWillShowNotification而显示键盘

iOS crifan 1240浏览 0评论

iOS的swift中已经添加了:

//    override func viewDidDisappear(animated: Bool) {

//        super.viewDidDisappear(animated)

//       

//        dismissKeyboard()

//    }

    override func viewWillDisappear(animated: Bool) {

        super.viewWillDisappear(animated)

        dismissKeyboard()

    }

        NSNotificationCenter.defaultCenter().addObserver(self,

            selector: #selector(MessageTableViewController.keyboardWillShow(_:)),

            name: UIKeyboardWillShowNotification,

            object: nil)

        NSNotificationCenter.defaultCenter().addObserver(self,

            selector: #selector(MessageTableViewController.keyboardWillHide(_:)),

            name: UIKeyboardWillHideNotification,

            object: nil)

    func dismissKeyboard(){

        if self.inputTextView.isFirstResponder() {

            self.inputTextView.resignFirstResponder()

        }

//        //Causes the view (or one of its embedded text fields) to resign the first responder status.

//        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())") //true false

//        self.view.endEditing(true)

    }

但是:

当离开页面,虽然已经可以调用到隐藏键盘了

但是再次进入页面,却会调用到UIKeyboardWillShowNotification,而执行到keyboardWillShow

keyboardWillShow always called

uikeyboardwillshownotification still called

ios – Why is UIKeyboardWillShowNotification called every time new TextField is selected – Stack Overflow

ios – keyboardWillShow in IOS8 with UIKeyboardWillShowNotification – Stack Overflow

ios – UIKeyboardWillShowNotification wrongly called from next class in stack – Stack Overflow

Extraneous UIKeyboardWillShowNotifications being setn – Simosh丨Learn to code the world

UITextField UIKeyboardWillShowNotification sent… | Apple Developer Forums

UIKeyboardWillShowNotification called twice if … | Apple Support Communities

ios – UIKeyboardWillShowNotification called twice if screen rotates – Stack Overflow

uikeyboardwillshownotification called unexpected

ios – UIKeyboardWillShowNotification & UIKeyboardDidShowNotification report wrong keyboard height – Stack Overflow

keyboardWillShow called unexpected

iphone – keyboardWillShow called twice – Stack Overflow

Working with the Keyboard on iOS… | Macoscope Blog

我此处是:

在离开页面时,已经调用了resignFirstResponder

    func dismissKeyboard(){

        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())") //true false

//        if self.inputTextView.isFirstResponder() {

            self.inputTextView.resignFirstResponder()

//        }

        self.view.resignFirstResponder()

       

        //Causes the view (or one of its embedded text fields) to resign the first responder status.

        self.view.endEditing(true)

    }

重新进入页面后,结果还是会调用到:

UIKeyboardWillShowNotification-》keyboardWillShow

搜:

after resignFirstResponder still keyboardWillShow

after resignFirstResponder still UIKeyboardWillShowNotification

ios – Why is UITextField animating on resignFirstResponder? – Stack Overflow

Return on the keyboard calls UIKeyboardWillHideNotification and UIKeyboardWillShowNotification · Issue #27 · venmo/VENTokenField

UIKeyboardWillShowNotification problems in iOS9 – codes fans

ios 进入页面 键盘始终显示

ios  页面 键盘 不应该 显示

ios  keyboard hide but show

离开页面后再回来,当还是调用到:

keyboardWillShow

时候的,调用函数堆栈:

看起来,难道是和:

restoreInputViewWithId

有关?

ios input text first responder

ios input text resign first responder

iphone – How to resign first responder from text field when user tap elsewhere? – Stack Overflow

把first responder 换成别的view,或许就可以避免,textview变成first responder而避免显示键盘了?

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)

       

        self.view.endEditing(true)

        gLog.debug("\(self.view.canResignFirstResponder())") //true

        self.view.resignFirstResponder()

       

        if #available(iOS 9.0, *) {

            gLog.debug("self.messageTableView.canBecomeFocused()=\(self.messageTableView.canBecomeFocused())")

        } else {

            // Fallback on earlier versions

        }

        self.messageTableView.becomeFirstResponder()

还是没用:还是会调用到:keyboardWillShow

iphone – How to make text field "become first responder" in UIAlertView – Stack Overflow

Text input field moves up to first responder height, but keyboard does not show · Issue #396 · jessesquires/JSQMessagesViewController

去didAppear中试试

还是找不到根本原因

UITextFieldDelegate Protocol Reference

实在不行,就去在

textFieldShouldBeginEditing

中,首次进入页面时,不允许编辑。。

好像也不靠谱

难道真的和restore有关?

UITextField Class Reference

“State Preservation

When you assign a value to a text field’s restorationIdentifier property, it preserves the selected range of text, if any. During the next launch cycle, the text field attempts to restore that selection. If the selection range cannot be applied to the current text, no selection is made. For more information about how state preservation and restoration works, see App Programming Guide for iOS.”

注:

离开当前页面时,也会调用到:

keyboardWillHide

的,堆栈是:

_preserveInputViewsWithId

iOS-Runtime-Headers/UIPeripheralHost.h at master · nst/iOS-Runtime-Headers

UIKit-Class-Dump/UIPeripheralHost.h at master · modocache/UIKit-Class-Dump

restoreInputViewsWithId

去给自己当前的类中初始化时候加上:

self.restorationIdentifier = nil

不行。

感觉,难道是这个有问题:setAnimationBeginsFromCurrentState?

ios – How to show keyboard after used inputView – Stack Overflow

中也没有:setAnimationBeginsFromCurrentState

UIView Class Reference

“+ setAnimationBeginsFromCurrentState:

Sets whether the animation should begin playing from the current state.

Declaration

SWIFT

class func setAnimationBeginsFromCurrentState(_ fromCurrentState: Bool)

OBJECTIVE-C

+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState

Parameters

fromCurrentState   

Specify YES if animations should begin from their currently visible state; otherwise, NO.

Discussion

If set to YES when an animation is in flight, the current view position of the in-flight animation is used as the starting state for the new animation. If set to NO, the in-flight animation ends before the new animation begins using the last view position as the starting state. This method does nothing if an animation is not in flight or invoked outside of an animation block. Use the beginAnimations:context: class method to start and the commitAnimations class method to end an animation block. The default value is NO.

Use of this method is discouraged in iOS 4.0 and later. Instead, you should use theanimateWithDuration:delay:options:animations:completion: method to specify your animations and the animation options.

Availability

Available in iOS 2.0 and later.”

uikeyboardwillshownotification called twice

最后无奈,是通过:

[已解决]swift中判断当前页面是否显示完毕

去定义一个变量,判断页面是否完全出现显示了

然后去决定,是否让文本输入框允许编辑

-》当页面没有完全显示,那么就不允许文本框编辑

-》就可以禁止那个键盘无故的被显示出来了。

相关代码,包括期间折腾所用的代码,如下:

    var inputTextView:UITextView

    var isViewDidAppear:Bool

    init(curContactItem:ContactItem){

 

        self.isViewDidAppear = false

        self.inputTextView = UITextView()

}

    func forceNotShowKeyboard() {

        self.view.endEditing(true)

        self.inputTextView.resignFirstResponder()

       

        //UIApplication.sharedApplication().sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, forEvent:nil)

//        self.view.endEditing(true)

//        gLog.debug("\(self.view.canResignFirstResponder())") //true

//        self.view.resignFirstResponder()

//        self.inputTextView.resignFirstResponder()

//

//        if #available(iOS 9.0, *) {

//            gLog.debug("self.messageTableView.canBecomeFocused()=\(self.messageTableView.canBecomeFocused())")

//        } else {

//            // Fallback on earlier versions

//        }

//        self.messageTableView.becomeFirstResponder()

    }

   

//    override func viewDidDisappear(animated: Bool) {

//        super.viewDidDisappear(animated)

//       

////        dismissKeyboard()

//       

//        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())")

//       

////        forceNotShowKeyboard()

//       

//        self.isViewDidAppear = false

//    }

    override func viewWillDisappear(animated: Bool) {

        super.viewWillDisappear(animated)

       

        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())")

       

        forceNotShowKeyboard()

        self.isViewDidAppear = false

    }

   

    override func viewDidAppear(animated: Bool) {

        super.viewDidAppear(animated)

        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())")

       

        self.isViewDidAppear = true

    }

   

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)

       

//        forceNotShowKeyboard()

        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())")

    }

    override func viewDidLoad() {

        super.viewDidLoad()

        addListenKeyboard()

}

    func textViewShouldBeginEditing(textView: UITextView) -> Bool {

        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder()), self.view.isFirstResponder()=\(self.view.isFirstResponder()), self.isViewDidAppear=\(self.isViewDidAppear)")

        return self.isViewDidAppear

    }

   

//    func textViewDidEndEditing(textView: UITextView) {

//        gLog.debug("textView=\(textView), isFirstResponder()=\(textView.isFirstResponder())")

//        textView.resignFirstResponder()

//    }

   

    func addListenKeyboard() {

        NSNotificationCenter.defaultCenter().addObserver(self,

                                                         selector: #selector(MessageTableViewController.keyboardWillShow(_:)),

                                                         name: UIKeyboardWillShowNotification,

                                                         object: nil)

        NSNotificationCenter.defaultCenter().addObserver(self,

                                                         selector: #selector(MessageTableViewController.keyboardWillHide(_:)),

                                                         name: UIKeyboardWillHideNotification,

                                                         object: nil)

    }

//    func removeListenKeyboard() {

//        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)

//       

//        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)

//    }

   

    func dismissKeyboard(){

//        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())") //true false

//

////        if self.inputTextView.isFirstResponder() {

//            self.inputTextView.resignFirstResponder()

////        }

//

//        self.view.resignFirstResponder()

       

        //Causes the view (or one of its embedded text fields) to resign the first responder status.

        self.view.endEditing(true)

    }

   

    func keyboardWillShow(notification: NSNotification) {

        //if !self.inputTextView.isFirstResponder() {

        if !self.isViewDidAppear {

            // -> most happened in, quit current view while showing keyboard, switch to other view then come back

            //-> this will cause this case: currently inputview not first responder but will got UIKeyboardWillShowNotification, then call this keyboardWillShow

            //can NOT find the root cause till now

            gLog.debug("inputTextView not first responder and view has not did appear, so not show keyboard, and force not show keyboard")

           

            //forceNotShowKeyboard()

           

            return

        }

        if let userInfo = notification.userInfo {

            if let originKeyboardFrameEnd:CGRect = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue {

                UIView.beginAnimations(nil, context: nil)

                UIView.setAnimationBeginsFromCurrentState(true)

                UIView.setAnimationDuration(AnimationTime)

                let convertedKeyboardFrameEnd:CGRect = self.view.convertRect(originKeyboardFrameEnd, fromView: nil)

                chatView.frame = CGRectMake(

                    0,

                    0,

                    self.view.frame.width,

                    convertedKeyboardFrameEnd.origin.y

                )

               

                self.messageTableView.frame.size.height = chatView.frame.size.height self.toolbarHeight 

                scrollTableviewToBottom(self.messageList, tableView:self.messageTableView)

               

                //convertedKeyboardFrameEnd.height = 216

                let paddingForFixBug:CGFloat = 20

                //workaround for bug:

                //uitableview – iOS 8 Auto cell height – Can’t scroll to last row – Stack Overflow

                //http://stackoverflow.com/questions/25686490/ios-8-auto-cell-height-cant-scroll-to-last-row

                let paddingContentInsets:UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, paddingForFixBug, 0.0)

                messageTableView.contentInset = paddingContentInsets

                UIView.commitAnimations()

            }

        }

    }

   

    func keyboardWillHide(notification: NSNotification) {

        gLog.debug("self.inputTextView.isFirstResponder()=\(self.inputTextView.isFirstResponder())")

        if let userInfo = notification.userInfo {

            if let originKeyboardFrameEnd:CGRect = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue {

                gLog.debug("originKeyboardFrameEnd=\(originKeyboardFrameEnd)")

               

                UIView.beginAnimations(nil, context: nil)

                UIView.setAnimationBeginsFromCurrentState(true)

                UIView.setAnimationDuration(AnimationTime)

                chatView.frame = originChatViewFrame

                 self.messageTableView.frame.size.height = chatView.frame.size.height self.toolbarHeight

                UIView.commitAnimations()

            }

        }

    }

总之是:

还是没有找到根本原因。

不知道,为何:

在离开当前页面时,

本身会自动调用keyboardWillHide去隐藏掉键盘

但是当再次进入当前页面时

为何会先去(估计触发了UIKeyboardWillShowNotification而)调用了keyboardWillShow

以后有空再深究吧。

转载请注明:在路上 » [已解决]iOS中进入页面后无故触发UIKeyboardWillShowNotification而显示键盘

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
63 queries in 0.205 seconds, using 18.68MB memory