我的键盘被解雇有问题。每次我在键盘上向下滑动,我都有这个空白的黑色背景,我想摆脱它。我不明白为什么它在那里。这与我的tableView连接。
What it looks like when I swipe Down
我将tableView上的keyBoard设置为Dismiss Interactively
// KeyBoard (move text box above keyboard)
//KeyBoard - exit when the view is touched
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
// Start Editing The Text Field
func textFieldDidBeginEditing(_ messageTextField: UITextField) {
moveTextField(messageTextField, moveDistance: -215, up: true)
}
// Finish Editing The Text Field
func textFieldDidEndEditing(_ messageTextField: UITextField) {
moveTextField(messageTextField, moveDistance: -215, up: false)
}
// Hide the keyboard when the return key pressed
func textFieldShouldReturn(_ messageTextField: UITextField) -> Bool {
messageTextField.resignFirstResponder()
return true
}
// Move the text field in a pretty animation!
func moveTextField(_ messageTextField: UITextField, moveDistance: Int, up: Bool) {
let moveDuration = 0.3
let movement: CGFloat = CGFloat(up ? moveDistance : -moveDistance)
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(moveDuration)
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
答案 0 :(得分:0)
在inputAccessoryView
的{{1}}中添加您的观点
UITextField
然后像这样设置yourtextField.inputAccessoryView = yourView
tableview
答案 1 :(得分:0)
黑色视图是ViewController后面的视图。在moveTextField
动画完成之前,由于隐藏了键盘,因此可以看到该视图,从而使黑色视图可见。
关闭动画块本身中的键盘,以使键盘与屏幕一起关闭。然后从moveTextField
调用touchesBegan
。您需要在以下代码中获得UITextField
(tf
)的引用。另外,不要忘记处理Return键。
//KeyBoard - exit when the view is touched
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if tf.isEditing {
moveTextField(tf, moveDistance: -215, up: false)
}
// self.view.endEditing(true)
}
// Start Editing The Text Field
func textFieldDidBeginEditing(_ messageTextField: UITextField) {
moveTextField(messageTextField, moveDistance: -215, up: true)
}
// Finish Editing The Text Field
func textFieldDidEndEditing(_ messageTextField: UITextField) {
// moveTextField(tf, moveDistance: -215, up: false)
}
// Hide the keyboard when the return key pressed
func textFieldShouldReturn(_ messageTextField: UITextField) -> Bool {
// messageTextField.resignFirstResponder()
if tf.isEditing {
moveTextField(tf, moveDistance: -215, up: false)
}
return true
}
// Move the text field in a pretty animation!
func moveTextField(_ messageTextField: UITextField, moveDistance: Int, up: Bool) {
let moveDuration = 0.3
let movement: CGFloat = CGFloat(up ? moveDistance : -moveDistance)
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(moveDuration)
if !up {
self.view.endEditing(true)
}
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
答案 2 :(得分:0)
我前段时间也遇到过类似的问题,并发现了以下方法。
首先为您的视图添加一个底部约束,并将其与VC类中的IBOutlet连接:
@IBOutlet weak var bottomConstraint: NSLayoutConstraint!
然后将通知添加到您的viewWillAppear重写函数。我相信您已经添加了手势识别器。无论如何,我在此答案的底部共享了手势识别器功能。
override func viewWillAppear(_ animated: Bool) {
//self.addGestureRecognizer()
// To move view when keyboard appears/hides
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChangeFrame(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
最主要的是下面的函数。我将其添加为扩展。这个想法是当键盘向下移动时用动画来改变约束。您会看到我为iPhone 4s使用了硬编码的值(我在iPhone 4s和iOS 9上使用此解决方案时遇到了问题)。因此,如果您不支持4s模型,则可以将其删除。
extension CheckoutViewController {
// Function to scroll view when keyboard appears/disappears
@objc func keyboardWillChangeFrame (notification: NSNotification) {
if let userInfo = notification.userInfo {
let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 1
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.bottomConstraint?.constant = 0.0
} else {
// Keyboard is opened
var constraintValue = endFrame?.size.height ?? 0
if UIDevice.current.modelName != "iPhone 4s" {
constraintValue = constraintValue - 35
}
self.bottomConstraint?.constant = constraintValue
}
UIView.animate(withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
}
}
不幸的是,目前我无法访问XCode,因此以代码为例。希望它能帮助您解决问题。
我使用的UIViewController的手势识别器扩展:
extension UIViewController {
func addGestureRecognizer() {
// Gesture recognizer To dismiss keyboard
let singleTap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
singleTap.cancelsTouchesInView = false
singleTap.numberOfTapsRequired = 1
self.view.addGestureRecognizer(singleTap)
}
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
self.view.endEditing(false)
}
}
答案 3 :(得分:0)
更好的解决方案
如果您已经看到ios的本机 Messaging应用,则可以通过交互手势关闭键盘。
这样,您的问题也将得到解决,因为我们没有将UIView
的textview / textfield和按钮(发送)添加到subview
,而是作为视图控制器的辅助视图添加
第1步:
转到Storybaord选择集合视图,然后在属性列表上将“键盘关闭”模式更改为“交互式关闭”
并使集合视图充满整个屏幕(不要为textField和send按钮添加空间)
第2步:
在视图控制器中,在顶部添加以下属性
var viewAcc: UIView?
var sendButton: UIButton!
var inputTextField: UITextField!
override var inputAccessoryView: UIView? {
return viewAcc
}
override var canBecomeFirstResponder: Bool {
return true
}
在ViewDidLoad方法中,为初始化视图添加以下代码,并添加textField和发送按钮
viewAcc = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
viewAcc?.backgroundColor = UIColor.white
inputTextField = UITextField (frame: CGRect(x:8, y:0, width:UIScreen.main.bounds.width, height: 44 ))
inputTextField.inputAccessoryView = nil
inputTextField.delegate = self as? UITextFieldDelegate
inputTextField.placeholder = "Enter message..."
viewAcc?.backgroundColor = .white
viewAcc?.addSubview(inputTextField);
let topBorderView = UIView()
topBorderView.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
viewAcc?.addSubview(topBorderView)
viewAcc?.addConstraintsWithFormat(format: "H:|[v0]|", views: topBorderView)
viewAcc?.addConstraintsWithFormat(format: "V:|[v0(0.5)]", views: topBorderView)
sendButton = UIButton(type: .system)
sendButton.isEnabled = true
sendButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
sendButton.setTitle("Send", for: .normal)
sendButton.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
sendButton.addTarget(self, action: #selector(handleSend), for: .touchUpInside)
viewAcc?.addSubview(sendButton)
inputTextField.translatesAutoresizingMaskIntoConstraints = false
sendButton.translatesAutoresizingMaskIntoConstraints = false
viewAcc?.addConstraint(NSLayoutConstraint(item: inputTextField, attribute: .left, relatedBy: .equal, toItem: viewAcc, attribute: .left, multiplier: 1, constant: 8))
viewAcc?.addConstraint(NSLayoutConstraint(item: inputTextField, attribute: .top, relatedBy: .equal, toItem: viewAcc, attribute: .top, multiplier: 1, constant: 7.5))
viewAcc?.addConstraint(NSLayoutConstraint(item: inputTextField, attribute: .right, relatedBy: .equal, toItem: sendButton, attribute: .left, multiplier: 1, constant: -2))
viewAcc?.addConstraint(NSLayoutConstraint(item: inputTextField, attribute: .bottom, relatedBy: .equal, toItem: viewAcc, attribute: .bottom, multiplier: 1, constant: -8))
viewAcc?.addConstraint(NSLayoutConstraint(item: sendButton, attribute: .right, relatedBy: .equal, toItem: viewAcc, attribute: .right, multiplier: 1, constant: 0))
viewAcc?.addConstraint(NSLayoutConstraint(item: sendButton, attribute: .bottom, relatedBy: .equal, toItem: viewAcc, attribute: .bottom, multiplier: 1, constant: -4.5))
现在运行该应用程序,您可以在底部看到textField和按钮,还可以看到完整的集合视图。您只需按住并向下滑动即可关闭键盘
希望对您有帮助
答案 4 :(得分:0)
从视图中创建一个底部约束,您希望根据键盘向上和向下推动该约束。让我们称之为viewBottomConstraint
。接下来,复制粘贴下面的代码,这是自解释的。
完成此操作后,在您的KeyboardViewPusher
中创建对UIViewController
实例的引用。并使用正确的值对其进行初始化。之后,您唯一要做的就是在KeyboardViewPusher
出现和消失时通知ViewController
实例。
仅此而已!
import UIKit
/// Be SURE to call didAppear() and disDisappear() at the right time in your viewcontroller.
open class KeyboardViewPusher {
/// Because of 2 things we need the actual viewControllersView:
/// 1. Because we need to call layoutIfNeeded() on this particular view to actually animate it
/// If we do this directly on property 'view', it doesn't animate (nice job Apple).
/// 2. To determine the safe area bottom constant (although we can get it also through the keyWindow).
/// But then we need to force unwrap stuff.
public unowned let viewControllerView: UIView
/// This is the view to push upwards.
public unowned let view: UIView
/// The bottom constant.
/// Make sure this is equal to view.bottomAnchor == viewControllerView.bottomAnchor
public unowned let viewBottomConstraint: NSLayoutConstraint
/// Start constant of viewBottomConstraint
/// We need this to properly animate it back when the keyboard will hide.
public let viewBottomConstraintConstant: CGFloat
private let defaultAnimationDuration: TimeInterval = 0.25
public init(viewControllerView: UIView, view: UIView, viewBottomConstraint: NSLayoutConstraint) {
self.viewControllerView = viewControllerView
self.view = view
self.viewBottomConstraint = viewBottomConstraint
viewBottomConstraintConstant = viewBottomConstraint.constant
}
/// Call this in the viewDidAppear() method in the viewController.
open func didAppear() {
addObserver()
}
/// Call this in the viewDidDisappear() method in the viewController.
open func didDisappear() {
removeObserver()
}
open func removeObserver() {
NotificationCenter.default.removeObserver(self)
}
open func addObserver() {
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)
}
@objc open func keyboardWillShow(_ notification: NSNotification) {
guard let keyboardHeight = notification.determineKeyboardHeight() else { return }
let maximumPushValue = -(keyboardHeight - viewControllerView.safeAreaInsets.bottom)
viewBottomConstraint.constant = maximumPushValue
UIView.animate(withDuration: notification.determineKeyboardAnimationDuration() ?? defaultAnimationDuration) {
self.viewControllerView.layoutIfNeeded()
}
}
@objc open func keyboardWillHide(_ notification: NSNotification) {
hide(animationDuration: notification.determineKeyboardAnimationDuration() ?? defaultAnimationDuration)
}
// When animation with a value of 0, it doesn't actually animates it but directly layouts the view.
// This doesn't negatively affect the performance.
open func hide(animationDuration: TimeInterval = 0) {
guard viewBottomConstraint.constant != viewBottomConstraintConstant else { return }
viewBottomConstraint.constant = viewBottomConstraintConstant
UIView.animate(withDuration: animationDuration) {
self.viewControllerView.layoutIfNeeded()
}
}
deinit {
removeObserver()
}
}
/// Helper extensions for the KeyboardViewPusher
public extension NSNotification {
public func determineKeyboardHeight() -> CGFloat? {
return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height
}
public func determineKeyboardAnimationDuration() -> TimeInterval? {
return userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval
}
}
我前一段时间编写了这段代码,并将其放在github:https://github.com/Jasperav/JVKeyboardViewPusher上。我认为您不能立即克隆该项目。复制粘贴上面的代码虽然具有相同的效果。