【问题标题】:Why isn't scrollView working? Constraints are set correctly i think为什么滚动视图不起作用?我认为约束设置正确
【发布时间】:2021-05-13 06:58:17
【问题描述】:

我的展示:

为什么滚动视图不起作用?我正确设置了约束,我不明白错误是什么,请告诉我! 我使用代码排版屏幕,查看了许多文章和教程,但我仍然不明白为什么 scrollView 不起作用。是不是我用错了scrollView里面的元素?

我的代码:

import UIKit

class LoginViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.navigationBar.isHidden = true
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(imageView)
        contentView.addSubview(textFieldForLogin)
        contentView.addSubview(textFieldForPassword)
        contentView.addSubview(buttonLogin)
        buttonLogin.addTarget(self, action: #selector(getter: buttonLogin), for: .touchUpInside)
        
        // Keyboard
        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)
        
        setupContraints()
    }
    
    let scrollView: UIScrollView = {
        let scroll = UIScrollView()
        scroll.toAutoLayout()
        return scroll
    }()
    
    let imageView: UIImageView = {
        let image = UIImage(named: "logo.png")
        let imageView = UIImageView(image: image)
        imageView.toAutoLayout()
        return imageView
    }()
    
    let contentView: UIView = {
        let view = UIView()
        view.toAutoLayout()
        return view
    }()
    
    let textFieldForLogin: UITextField = {
        let textField = UITextField()
        textField.placeholder = "Email or phone"
        textField.textColor = .black
        textField.font = UIFont.systemFont(ofSize: 16)
        textField.tintColor = .cyan
        textField.autocapitalizationType = .none
        textField.textAlignment = .left // стоит textAlignment = .left + какой-то еще отступ
        
        textField.layer.borderColor = UIColor.lightGray.cgColor
        textField.layer.borderWidth = 0.5
        textField.layer.cornerRadius = 10
        textField.layer.backgroundColor = UIColor.systemGray6.cgColor
        textField.toAutoLayout()
        textField.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
        return textField
    }()
    
    let textFieldForPassword: UITextField = {
        let textField = UITextField()
        textField.placeholder = "Password"
        textField.textColor = .black
        textField.font = UIFont.systemFont(ofSize: 16)
        textField.tintColor = .cyan
        textField.autocapitalizationType = .none
        textField.textAlignment = .left // стоит textAlignment = .left + какой-то еще отступ походу должен быть потому что с макетом не сходится
        textField.isSecureTextEntry = true
        
        textField.layer.borderColor = UIColor.lightGray.cgColor
        textField.layer.borderWidth = 0.5
        textField.layer.cornerRadius = 10
        textField.layer.backgroundColor = UIColor.systemGray6.cgColor
        textField.toAutoLayout()
        textField.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
        
        return textField
    }()
    
    @objc let buttonLogin: UIButton = {
        let button = UIButton(type: .system)
        
        let image = UIImage(named: "blue_pixel")
        button.setBackgroundImage(image, for: .normal)
        button.toAutoLayout()
        button.setTitle("Log In", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.clipsToBounds = true
        button.layer.cornerRadius = 10
        
        return button
    }()
    
    @objc func buttonLoginAction(sender: UIButton!) {
        let profileVC = ProfileViewController()
        navigationController?.pushViewController(profileVC, animated: true)
    }
    
    func setupContraints() {
        NSLayoutConstraint.activate([
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),

            contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            
            
//            scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
//            scrollView.widthAnchor.constraint(equalTo: view.widthAnchor),
//            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
//            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
//
//            contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
//            contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
//            contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
//            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            
            imageView.topAnchor.constraint(equalTo: contentView.safeAreaLayoutGuide.topAnchor, constant: 120),
            imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            imageView.widthAnchor.constraint(equalToConstant: 100),
            imageView.heightAnchor.constraint(equalToConstant: 100),
            
            textFieldForLogin.topAnchor.constraint(equalTo: imageView.topAnchor, constant: 220),
            textFieldForLogin.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            textFieldForLogin.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
            textFieldForLogin.heightAnchor.constraint(equalToConstant: 50),
            
            textFieldForPassword.topAnchor.constraint(equalTo: textFieldForLogin.topAnchor, constant: 50),
            textFieldForPassword.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            textFieldForPassword.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
            textFieldForPassword.heightAnchor.constraint(equalToConstant: 50),
            
            buttonLogin.topAnchor.constraint(equalTo: textFieldForPassword.topAnchor, constant: 66),
            buttonLogin.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            buttonLogin.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
            buttonLogin.heightAnchor.constraint(equalToConstant: 50),
            buttonLogin.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) // аспирант попросил добавить
        ])
    }
    
    @objc func keyboardWillShow(notification: NSNotification) {
       let keyboardHeight = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
       print(keyboardHeight)
    }

    @objc func keyboardWillHide(notification: NSNotification) {
       let keyboardHeight = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
       print(keyboardHeight)
    }
}


extension UIView {
    func toAutoLayout() {
        self.translatesAutoresizingMaskIntoConstraints = false
    }
}

【问题讨论】:

  • 尝试删除contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),,如果这不能解决,请尝试向 contentView 添加高度约束,这应该可以解决问题。通常不建议应用高度约束,但由于您对内部组件的所有间距/高度进行了硬编码,因此可能不需要高度约束,因为内容视图将能够获得隐式高度,因此只需将底部约束删除到滚动视图应该做
  • scrollView 到底是怎么回事?另请参阅How to Ask

标签: ios swift autolayout scrollview


【解决方案1】:

尝试将centerXAnchor设置为contentView而不是widthAnchor,所以添加这一行:

contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor)

而不是这个:

contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)

另外,设置相对于contentView 而不是父视图的子视图约束:

imageView.topAnchor.constraint(equalTo: contentView.safeAreaLayoutGuide.topAnchor, constant: 120),
imageView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
imageView.widthAnchor.constraint(equalToConstant: 100),
imageView.heightAnchor.constraint(equalToConstant: 100),

textFieldForLogin.topAnchor.constraint(equalTo: imageView.topAnchor, constant: 220),
textFieldForLogin.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
textFieldForLogin.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
textFieldForLogin.heightAnchor.constraint(equalToConstant: 50),

textFieldForPassword.topAnchor.constraint(equalTo: textFieldForLogin.topAnchor, constant: 50),
textFieldForPassword.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
textFieldForPassword.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
textFieldForPassword.heightAnchor.constraint(equalToConstant: 50),

buttonLogin.topAnchor.constraint(equalTo: textFieldForPassword.topAnchor, constant: 66),
buttonLogin.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
buttonLogin.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
buttonLogin.heightAnchor.constraint(equalToConstant: 50),
buttonLogin.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)

【讨论】:

    猜你喜欢
    • 2020-02-23
    • 2020-05-31
    • 1970-01-01
    • 2018-01-10
    • 2017-09-19
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多