当键盘出现时,UITextField 跳转到 UIImageView 之上

问题描述 投票:0回答:1

问题涉及 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;
    }
}
ios swift uiscrollview uikit
1个回答
0
投票

问题似乎与显示键盘时调整滚动视图框架有关。您应该调整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)
}
© www.soinside.com 2019 - 2024. All rights reserved.