我创建了一个meme生成器应用程序,以更好地学习Swift和Xcode。当用户与可能被键盘阻碍的文本字段进行交互时,我正在学习移动视图。我有这个功能,但有一个例外。当用户输入底部文本字段的文本时,所需的功能是让视图向上滑动。无论用户与哪个文本字段进行交互,视图都会向上滑动。
如何仅将此功能分配给底部文本字段?这是我的源代码:
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate {
@IBOutlet weak var imagePickerView: UIImageView!
@IBOutlet weak var cameraButton: UIBarButtonItem!
@IBOutlet weak var topText: UITextField!
@IBOutlet weak var bottomText: UITextField!
let memeTextAttributes:[String:Any] = [
NSAttributedStringKey.strokeColor.rawValue: UIColor.black,
NSAttributedStringKey.foregroundColor.rawValue: UIColor.white,
NSAttributedStringKey.font.rawValue: UIFont(name: "HelveticaNeue-CondensedBlack", size: 30)!,
NSAttributedStringKey.strokeWidth.rawValue: -5.0]
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
subscribeToKeyboardNotifications()
}
override func viewDidLoad() {
super.viewDidLoad()
// Diable camer a button if camera ource isn't available
cameraButton.isEnabled = UIImagePickerController.isSourceTypeAvailable(.camera)
topText.delegate = self
bottomText.delegate = self
topText.textAlignment = .center
bottomText.textAlignment = .center
topText.defaultTextAttributes = memeTextAttributes
bottomText.defaultTextAttributes = memeTextAttributes
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
unsubscribeFromKeyboardNotifications()
}
// MARK: Delegate Methods
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
imagePickerView.image = image
self.dismiss(animated: true, completion: nil)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.dismiss(animated: true, completion: nil)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.text = ""
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.topText.resignFirstResponder()
self.bottomText.resignFirstResponder()
return true
}
// MARK: Move the keyboard up when the bottom textfield is tapped
@objc func keyboardWillShow(_ notification:Notification) {
view.frame.origin.y = 0 - getKeyboardHeight(notification)
}
func getKeyboardHeight(_ notification:Notification) -> CGFloat {
let userInfo = notification.userInfo
let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
return keyboardSize.cgRectValue.height
}
func subscribeToKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
}
func unsubscribeFromKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
// MARK: Move view down when keyboard is dismissed
@objc func keyboardWillHide(_ notification: Notification) {
view.frame.origin.y = 0
}
// MARK: IBActions
@IBAction func pickAnImageFromAlbum(_ sender: Any) {
let pickerController = UIImagePickerController()
pickerController.delegate = self
pickerController.sourceType = .photoLibrary
present(pickerController, animated: true, completion: nil)
}
@IBAction func pickAnImageFromCamera(_ sender: Any) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true, completion: nil)
}
}
答案 0 :(得分:2)
你可以试试这个
//make a global textField to keep reference
var currentTappedTextField : UITextField?
//use this method to get tapped textField
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
currentTappedTextField = textField
return true
}
// now move view only when textfield is bottom
@objc func keyboardWillShow(_ notification:Notification) {
if(currentTappedTextField == bottomText){
view.frame.origin.y = 0 - getKeyboardHeight(notification)
}
}
答案 1 :(得分:1)
在scrollview中添加视图。 使用
pod 'IQKeyboardManagerSwift'
它会自动处理。在app delegate中写下这段代码:
IQKeyboardManager.sharedManager().enable = true
IQKeyboardManager.sharedManager().keyboardDistanceFromTextField = 30.0
如果您想要一个文本字段:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == toptextField {
IQKeyboardManager.sharedManager().enable = false
}
else {
IQKeyboardManager.sharedManager().enable = true
}
return true
}
答案 2 :(得分:1)
UIKeyboardDidShow
通知并获取键盘的结束帧。使用结束帧的负高度作为底部约束的常量。UIKeyboardWillHide
中执行相同操作,并将底部约束常量设置为原始常量值答案 3 :(得分:0)
您只需在viewDidLoad中观察键盘通知:
override func viewDidLoad() {
super.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)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
并声明选择器方法以更改视图约束:
@objc
func keyboardWillShow(_ notification: Notification) {
if let keyboardHeight = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
yourViewBottomConstraint.constant = keyboardHeight.cgRectValue.height + constantHeight
UIView.animate(withDuration: 0.25, animations: {
self.view.layoutIfNeeded()
})
}
}
@objc
func keyboardWillHide() {
yourViewBottomConstraint.constant = constantHeight
UIView.animate(withDuration: 0.25, animations: {
self.view.layoutIfNeeded()
})
}
不要忘记实现UITextFieldDelegate:
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
}
}