Переместить вид, когда определенное текстовое поле выбрано быстро
Я создал приложение-генератор мемов, чтобы лучше изучить 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)
}
}
4 ответа
Вы можете просто попробовать это
//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)
}
}
Добавить представление в scrollview. использование
pod 'IQKeyboardManagerSwift'
Это будет автоматически обрабатывать это. В приложении делегат напишите этот код:
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
}
Подход без использования внешней структуры:
- Используйте ограничение снизу от текстового поля до родительского представления.
- Отрегулируйте постоянное значение в зависимости от того, показана клавиатура или скрыта.
шаги:
- Создайте нижнее ограничение от вашего текстового поля до родительского представления.
- Установите постоянную ограничения в начальное желаемое значение
- Добавить сохранить ограничение как свойство в контроллере представления
- соблюдать
UIKeyboardDidShow
Уведомление и получить конец кадра клавиатуры. Используйте отрицательную высоту конечного кадра в качестве константы нижнего ограничения. - Аналогичным образом сделайте то же самое в
UIKeyboardWillHide
и установите нижнюю константу ограничения в исходное значение константы
Вам просто нужно наблюдать уведомление клавиатуры в вашем 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
}
}