swift 当键盘显示快捷键时移动按钮

r3i60tvu  于 11个月前  发布在  Swift
关注(0)|答案(5)|浏览(147)

在一个UIViewController中,我有几个文本字段,一个按钮位于UIViewController的底部。对于按钮,我设置了一个常量为0的底部约束。然后我从底部约束到UIViewController创建了一个出口。
当我运行我的代码时,按钮不会向上移动。我在stackoverflow上看到建议我应该添加UIScrollView,但这意味着,我必须删除UIViewController上的所有对象,将UIScrollView放在UIViewController上,然后再次将我的对象放在UIViewController上。

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

// When tapping outside of the keyboard, close the keyboard down
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.view.endEditing(true)
}

// Stop Editing on Return Key Tap. textField parameter refers to any textfield within the view
func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

// When keyboard is about to show assign the height of the keyboard to bottomConstraint.constant of our button so that it will move up
func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        if let keyboardSize: CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            bottomConstraint.constant = keyboardSize.size.height
            view.setNeedsLayout()
        }
    }
}

// When keyboard is hidden, move the button to the bottom of the view
func keyboardWillHide(notification: NSNotification) {
    bottomConstraint.constant = 0.0
    view.setNeedsLayout()
}

字符串


的数据

u2nhd7ah

u2nhd7ah1#

解决这个问题的典型方法是用这样的代码移动键盘:
在ViewController类中:

func keyboardWillShow(notification: NSNotification) {

        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            if view.frame.origin.y == 0{
                let height = keyboardSize.height

                self.view.frame.origin.y += height
            }

        }

    }

    func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            if view.frame.origin.y != 0 {
                let height = keyboardSize.height
                self.view.frame.origin.y -= height
            }

        }
    }

字符串
在ViewDidLoad方法中:

NotificationCenter.default.addObserver(self, selector: Selector("keyboardWillShow:"), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
  NotificationCenter.default.addObserver(self, selector: Selector("keyboardWillHide:"), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

请阅读:您试图解决问题的方法是不允许的。在上面的代码中,如果您将view更改为按钮变量名称,按钮将向上弹出,然后回落。这是因为自动布局和编程布局不能一起工作,它是一个或另一个。解决此问题的方法是通过编程创建该按钮(使用CGRect),然后使用上面的代码在键盘按下时仅移动该按钮。(通过将view更改为按钮变量名称来实现。

func keyboardWillShow(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if view.frame.origin.y == 0{
            let height = keyboardSize.height
            self.yourBtn.frame.origin.y += height
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if view.frame.origin.y != 0 {
            let height = keyboardSize.height
            self.yourBtn.frame.origin.y -= height
        }
    }
}


要以编程方式创建按钮,您可以使用类似于以下内容的代码:

myButton.frame = CGRect(...)

cunj1qz1

cunj1qz12#

补充瑞安的答案以上,这可以做到所有与自动布局,而不需要框架和CGRect。

  • 斯威夫特5号酒店,纽约**

在你的视图中,像往常一样约束你的按钮,但是在键盘隐藏/显示时添加一个对约束的引用以进行修改:

var bottomButtonConstraint = NSLayoutConstraint()

bottomButtonConstraint = yourButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -12)
bottomButtonConstraint.isActive = true

字符串
在ViewController的viewDidLoad()中:

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

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


在ViewController中:

@objc private func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        self.yourCustomView.bottomButtonConstraint.constant -= keyboardSize.height
    }
}

@objc private func keyboardWillHide(notification: NSNotification) {
    self.yourCustomView.bottomButtonConstraint.constant = -12
}

txu3uszq

txu3uszq3#

你需要添加(viewDidLoad)观察者来调用你的函数:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillHide), name: UIKeyboardDidHideNotification, object: nil)

字符串

alen0pnh

alen0pnh4#

考虑使用这个pod:https://cocoapods.org/pods/IQKeyboardManager在AppDelegate.swift中,只需导入IQKeyboardManagerSwift框架并启用IQKeyboardManager。
导入IQKeyboardManagerSwift
@UIApplicationMain class AppDelegate:UIResponder,UIApplicationDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  IQKeyboardManager.shared.enable = true

  return true
}

字符串
}

gzjq41n4

gzjq41n45#

我知道我有点迟到了,但由于上一次回答是在2年前,我想我可以为这个问题提供更多的价值。我的例子适用于Swift 5.5+,但应该也适用于较低版本。
在我的场景中,我需要某种更通用,但可配置的解决方案,这将允许我在项目中的任何UIViewController类中移动键盘和控件间距的视图。
这里有一些步骤,你需要做,以便它的工作:

第一步:

为视图底部约束创建outlet,并为键盘和源视图定义自定义间距:

@IBOutlet weak var <<yourViewName>>BottomConstraint: NSLayoutConstraint! // Your view's bottom constraint, that should be connected to safe/area or superview

private let <<yourViewName>>BottomSpacing: CGFloat = 56 // Spacing between view and safe area/superview when keyboard is hidden
private let <<yourViewName>>KeyboardSpacing: CGFloat = 22 // Spacing between active keyboard and your view

字符串
第二步:**
在我们的视图控制器中注册观察者,它将跟踪键盘的显示/隐藏(您可以根据需要在viewDidLoadinit中调用此方法)请注意,您必须手动删除观察者,即在旧版本的Swift中的deinit

private func addKeyboardObservers() {
    // Notifications for when the keyboard show/hides
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.keyboardWillShow),
                                           name: UIResponder.keyboardWillShowNotification,
                                           object: nil)
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.keyboardWillHide),
                                           name: UIResponder.keyboardWillHideNotification,
                                           object: nil)
}


第三步:**
将以下代码添加到UIViewController类中。以下代码将作为NotificationCenter观察者的结果被调用:

@objc private func keyboardWillShow(_ notification: NSNotification) {
    moveViewWithKeyboard(notification: notification,
                         keyboardWillShow: true,
                         viewBottomConstraint: <<yourViewName>>BottomConstraint,
                         activeKeyboardToViewSpacing: <<yourViewName>>KeyboardSpacing,
                         hiddenKeyboardToViewSpacing: <<yourViewName>>BottomSpacing)
}

@objc private func keyboardWillHide(_ notification: NSNotification) {
    moveViewWithKeyboard(notification: notification,
                         keyboardWillShow: false,
                         viewBottomConstraint: <<yourViewName>>BottomConstraint,
                         activeKeyboardToViewSpacing: <<yourViewName>>KeyboardSpacing,
                         hiddenKeyboardToViewSpacing: <<yourViewName>>BottomSpacing)
}


第四步:
拼图的最后一部分,方法,得到键盘的大小,计算间距和相应的移动视图。
通常,在我的项目中,我有一个名为UIViewController+Keyboard.swift的文件,其中包含extensionUIViewController中的代码。您还可以添加其他代码,对应于键盘管理,当用户点击时隐藏它,如下所示:

extension UIViewController {

func hideKeyboardWhenTappedAround() {
    let tap = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
    tap.cancelsTouchesInView = false
    view.addGestureRecognizer(tap)
}

@objc
func dismissKeyboard() {
    view.endEditing(true)
}

func moveViewWithKeyboard(notification: NSNotification,
                          keyboardWillShow: Bool,
                          viewBottomConstraint: NSLayoutConstraint,
                          activeKeyboardToViewSpacing: CGFloat,
                          hiddenKeyboardToViewSpacing: CGFloat) {
    
    guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }
    let keyboardHeight = keyboardSize.height
    let keyboardAnimationDuration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
    let keyboardAnimationCurve = UIView.AnimationCurve(rawValue: notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! Int)!
    
    // Modifying spacing constants
    if keyboardWillShow {
        let safeAreaExists = self.view?.window?.safeAreaInsets.bottom != 0
        // Default value in case something goes wrong with bottom spacings
        let bottomConstant: CGFloat = 20
        viewBottomConstraint.constant = keyboardHeight + (safeAreaExists ? 0 : bottomConstant) + activeKeyboardToViewSpacing
    } else {
        viewBottomConstraint.constant = hiddenKeyboardToViewSpacing
    }
    
    // Animating the view the same way the keyboard animates
    let animator = UIViewPropertyAnimator(duration: keyboardAnimationDuration, curve: keyboardAnimationCurve) { [weak self] in
        self?.view.layoutIfNeeded()
    }
    
    animator.startAnimation()
} }


在完成所有这些步骤后,你应该有了所需的可重用的行为和可配置的间距。希望对你有帮助!

相关问题