首页 > 解决方案 > 为什么滚动视图不起作用?我认为约束设置正确

问题描述

我的显示:

在此处输入图像描述

为什么滚动视图不起作用?我正确设置了约束,我不明白错误是什么,请告诉我!我使用代码排版屏幕,查看了许多文章和教程,但我仍然不明白为什么 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
    }
}

标签: iosswiftautolayoutscrollview

解决方案


尝试将 设置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)

推荐阅读