当键盘出现Swift时,使用文本字段和按钮向上移动视图

Posted

技术标签:

【中文标题】当键盘出现Swift时,使用文本字段和按钮向上移动视图【英文标题】:moving View up with textfield and Button when keyboard appear Swift 【发布时间】:2018-05-14 07:26:48 【问题描述】:

我知道有一些关于此主题的已发布问题,但没有一个有效。我有一个 tableview,在它下面有一个 UIView,其中包含一个文本字段和按钮。当我的键盘出现时,它覆盖了整个 UIView,使我无法单击“发送”。显示我的应用外观的图片:

目前,我的代码是:

 override func viewDidLoad() 
    super.viewDidLoad()
    inputTextField.delegate = self
    inputTextField.layer.cornerRadius = 5
    inputTextField.clipsToBounds = true
    sendButton.layer.cornerRadius = 5
    sendButton.clipsToBounds = true
    self.tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "TableViewCell")
    loadMsg()
    self.hideKeyboardWhenTappedAround()



override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    inputTextField.becomeFirstResponder()

当我的键盘出现时,我应该如何将 UIView 连同 UIView 包含的文本字段和按钮一起向上移动?

【问题讨论】:

你应该使用inputAccessoryView,请找到这个question 你使用AutoLayout来布局你的视图 是的,我是@AbdelahadDarwish 好的,我现在正在调查,@PPL 但是你解决了你的问题但是如果你需要键盘关闭就像苹果原生消息应用程序(向下拖动关闭)那么你应该实现这个***.com/questions/50293919/… 【参考方案1】:

只需使用 POD 将 this 库添加到您的项目中即可。它会自动完成。你不必做任何其他事情。

像这样添加 pod

pod 'IQKeyboardManagerSwift'

在 AppDelegate.swift 中,只需导入 IQKeyboardManagerSwift 框架并启用 IQKeyboardManager。

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

var window: UIWindow?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

  IQKeyboardManager.shared.enable = true

  return true
 

如需参考,请查看此网址,https://github.com/hackiftekhar/IQKeyboardManager

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @mag_zbc 请立即查看。【参考方案2】:

这里是解决方案,创建发送按钮视图的底部布局约束参考

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!
@IBOutlet weak var sendbuttonView: UIView!

    override func viewDidLoad() 
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    

    override func viewWillDisappear(_ animated: Bool) 
        NotificationCenter.default.removeObserver(self)
    

    @objc func handleKeyboardNotification(_ notification: Notification) 

    if let userInfo = notification.userInfo 

        let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue

        let isKeyboardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow

        bottomConstraint?.constant = isKeyboardShowing ? -keyboardFrame!.height : 0

        UIView.animate(withDuration: 0.5, animations:  () -> Void in
            self.view.layoutIfNeeded()
        )
    

Demo example

【讨论】:

我能知道登录菜单连接到哪里吗?? 是 UIView 吗? 不错!成功了!【参考方案3】:

斯威夫特 4.2

在 viewDidLoad() 中

NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name:UIResponder.keyboardWillChangeFrameNotification, object: nil)

方法

@objc func keyboard(notification:Notification) 
        guard let keyboardReact = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else
            return
        

        if notification.name == UIResponder.keyboardWillShowNotification ||  notification.name == UIResponder.keyboardWillChangeFrameNotification 
            self.view.frame.origin.y = -keyboardReact.height
        else
            self.view.frame.origin.y = 0
        

    

【讨论】:

【参考方案4】:

试试下面的代码

//Declare a delegate, assign your textField to the delegate and then include these methods

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    return YES;



- (BOOL)textFieldShouldEndEditing:(UITextField *)textField 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];

    [self.view endEditing:YES];
    return YES;



- (void)keyboardDidShow:(NSNotification *)notification

    // Assign new frame to your view 
    [self.view setFrame:CGRectMake(0,-110,320,460)]; //here taken -110 for example i.e. your view will be scrolled to -110. change its value according to your requirement.



-(void)keyboardDidHide:(NSNotification *)notification

    [self.view setFrame:CGRectMake(0,0,320,460)];

【讨论】:

【参考方案5】:

您可以通过将 View 向上移动 constraint 这里 actionBarPaddingBottomConstranit is Constraint connect to your Input View Bottom constraint Check image

在 ViewDidload 中:

 override func viewDidLoad() 
        super.viewDidLoad()
         self.keybordControl()
    

扩展:

extension ViewController

    func keybordControl()
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

    


    @objc func keyboardWillShow(notification: Notification) 
        self.keyboardControl(notification, isShowing: true)
    



    @objc func keyboardWillHide(notification: Notification) 
        self.keyboardControl(notification, isShowing: false)
    



     private func keyboardControl(_ notification: Notification, isShowing: Bool) 

        /* Handle the Keyboard property of Default, Text*/

        var userInfo = notification.userInfo!
        let keyboardRect = (userInfo[UIKeyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue
        let curve = (userInfo[UIKeyboardAnimationCurveUserInfoKey]! as AnyObject).uint32Value

        let convertedFrame = self.view.convert(keyboardRect!, from: nil)
        let heightOffset = self.view.bounds.size.height - convertedFrame.origin.y
        let options = UIViewAnimationOptions(rawValue: UInt(curve!) << 16 | UIViewAnimationOptions.beginFromCurrentState.rawValue)
        let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey]! as AnyObject).doubleValue


        var  pureheightOffset : CGFloat = -heightOffset

        if isShowing 
           if #available(ios 11.0, *) 
               pureheightOffset = pureheightOffset + view.safeAreaInsets.bottom
            
        
        self.actionBarPaddingBottomConstranit?.update(offset:pureheightOffset)

        UIView.animate(
            withDuration: duration!,
            delay: 0,
            options: options,
            animations: 
                self.view.layoutIfNeeded()

        ,
            completion:  bool in

        )

    

【讨论】:

非常感谢您的帮助! 你的回答很好,我应该用这个代码extension UIViewController而不是extension ViewController 是检查更新的答案【参考方案6】:

在 ViewDidLoad 中调用下面的方法:

func keyboardSettings()
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
        self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
        let swipeDown = UISwipeGestureRecognizer(target: self.view , action : #selector(UIView.endEditing(_:)))
        swipeDown.direction = .down
        self.view.addGestureRecognizer(swipeDown)
    

然后添加以下方法进行键盘配置:

@objc func keyboardNotification(notification: NSNotification) 

        if let userInfo = notification.userInfo 
            if let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
                if let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue

                    let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
                    let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
                    let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

                    if (endFrame.origin.y) >= UIScreen.main.bounds.size.height 
                        self.const_ViewMessage_Bottom?.constant = 0.0
                     else 
                        self.const_ViewMessage_Bottom?.constant = endFrame.size.height
                    

                    UIView.animate(withDuration: duration,
                                   delay: TimeInterval(0),
                                   options: animationCurve,
                                   animations:  self.view.layoutIfNeeded() ,
                                   completion: nil)
                
            
        
    

self.const_ViewMessage_Bottom 是带有文本框的 UIView 的底部约束。

【讨论】:

【参考方案7】:

具有一个可在所有 ViewController 中使用的扩展。创建一个空的 swift 文件,将这段代码复制到文件中

import UIKit

extension UIViewController 

    func keyboardCheck() 
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    

    @objc func keyboardWillShow(notification: NSNotification) 
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue 
            if self.view.frame.origin.y == 0 
                self.view.frame.origin.y -= keyboardSize.height
            
        
    

    @objc func keyboardWillHide(notification: NSNotification) 
        if self.view.frame.origin.y != 0 
            self.view.frame.origin.y = 0
        
    


然后调用ViewDidLoad Usage里面的函数:

override func viewDidLoad() 
        super.viewDidLoad()

       self.keyboardCheck()
    

【讨论】:

以上是关于当键盘出现Swift时,使用文本字段和按钮向上移动视图的主要内容,如果未能解决你的问题,请参考以下文章

当键盘出现并启用滚动时,TextField 向上移动

出现键盘时移动文本字段会覆盖(Swift)中的顶部文本字段

键盘出现多次时,滚动视图不会向上移动

Swift,iOS - 单击以显示文本字段时按钮向上移动?然后搬回去?

当使用 Swift 出现键盘时如何向上移动 UIViewController 的内容

使用 Swift 使用键盘移动视图