问题涉及 UIImageView 中 UITextField 的布局行为。 UIImageView 位于 UIScrollView 中。目标是将文本字段定位在图像视图的顶部,并且当键盘出现时,文本字段应保持在原位,而不会跳过图像视图。
但是,当显示键盘时,文本字段不会停留在图像视图顶部的原始位置,而是向上移动,越过图像视图。现在,如果您关闭键盘,这个问题就会消失。当我们知道正在显示键盘时,我尝试移动整个滚动视图,但这似乎不起作用,或者我无法正确实现它。任何帮助都会很棒!谢谢!
import UIKit
import NotificationCenter
import Foundation
class ZoomImage: UIViewController {
var x: CGFloat = 100
var y: CGFloat = -400
var keyboardHeight: CGFloat = 0.0
private let textField: UITextField = {
let ut = UITextField()
ut.textColor = .white
ut.placeholder = "Testing"
ut.backgroundColor = .none
ut.frame = CGRect(x: 20, y: 20, width: 200, height: 30)
return ut
}()
// create scrollView
private let scrollView: UIScrollView = {
let sv = UIScrollView()
sv.backgroundColor = .blue
return sv
}()
// create imageView
private var imageView: UIImageView = {
let v = UIImageView()
v.isUserInteractionEnabled = true
v.backgroundColor = .red
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
registerObservers()
setup()
}
func registerObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)),
name: UIResponder.keyboardWillShowNotification,
object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
keyboardHeight = keyboardSize.size.height
}
}
deinit {
// Unsubscribe from keyboard notifications
NotificationCenter.default.removeObserver(self)
}
func setup() {
// Allows us to have this view be the delegate of the textfield
self.textField.delegate = self
// Allows us to have this view be the delegate of the scrollview
scrollView.delegate = self
// add Scrollview to view
self.view.addSubview(scrollView)
// Defining imageView
let image = UIImage(named: "test.png")!
imageView.image = image
imageView.contentMode = .scaleAspectFit
// add UIImageView to scroll view
scrollView.addSubview(imageView)
imageView.addSubview(textField)
imageView.translatesAutoresizingMaskIntoConstraints = false
textField.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false
// respect safe-area
let safeG = view.safeAreaLayoutGuide
// Zoom range
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 10.0
// constraints
NSLayoutConstraint.activate([
scrollView.frameLayoutGuide.leadingAnchor.constraint(equalTo: safeG.leadingAnchor, constant: 0),
scrollView.frameLayoutGuide.trailingAnchor.constraint(equalTo: safeG.trailingAnchor, constant: 0),
scrollView.frameLayoutGuide.bottomAnchor.constraint(equalTo: safeG.bottomAnchor, constant: 0),
scrollView.frameLayoutGuide.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 0),
imageView.leadingAnchor.constraint(equalTo: self.scrollView.contentLayoutGuide.leadingAnchor, constant: 0),
imageView.trailingAnchor.constraint(equalTo: self.scrollView.contentLayoutGuide.trailingAnchor, constant: 0),
imageView.bottomAnchor.constraint(equalTo: self.scrollView.contentLayoutGuide.bottomAnchor, constant: 0),
imageView.topAnchor.constraint(equalTo: self.scrollView.contentLayoutGuide.topAnchor, constant: 0),
imageView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
imageView.heightAnchor.constraint(equalTo: scrollView.frameLayoutGuide.heightAnchor),
textField.leadingAnchor.constraint(equalTo: imageView.leadingAnchor, constant: self.x),
textField.bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: self.y),
])
}
}
// MARK: - Extensions
extension ZoomImage: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
}
extension ZoomImage: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
print("MOVE VIEW Down")
if self.scrollView.frame.origin.y == 0{
self.scrollView.frame.origin.y -= keyboardHeight
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("TextField should return method called")
textField.resignFirstResponder();
return true;
}
}
问题似乎与显示键盘时调整滚动视图框架有关。您应该调整scrollView的内容插入以适应键盘,而不是直接修改框架,而不改变其子视图的框架。
class ZoomImage: UIViewController {
// ... (your existing code)
override func viewDidLoad() {
super.viewDidLoad()
registerObservers()
setup()
}
func registerObservers() {
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)
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
keyboardHeight = keyboardSize.height
adjustScrollViewContentInset(showing: true)
}
}
@objc func keyboardWillHide(notification: NSNotification) {
adjustScrollViewContentInset(showing: false)
}
func adjustScrollViewContentInset(showing: Bool) {
var contentInset = scrollView.contentInset
contentInset.bottom = showing ? keyboardHeight : 0
scrollView.contentInset = contentInset
scrollView.scrollIndicatorInsets = contentInset
}
// ... (your existing code)
}