带有 AutoLayout 的 UIScrollView 不滚动

UIScrollView with AutoLayout does not scroll

我一遍又一遍地看到同样的问题,每个人都得到了相同的答案; “您需要将最后一个视图的 bottomAnchor 设置为等于滚动视图的 bottomAnchor,以便它展开”。

好吧,我做到了,滚动视图滚动(我看到滚动条移动)但视图不滚动!这是代码;

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    
    setupConstraints()
}

fileprivate func setupConstraints() {
    setupScrollViewConstraints()
    setupLogoImageViewConstraints()
    setupUsernameTextFieldConstraints()
    setupPasswordTextFieldConstraints()
    setupShowAndHideButtonConstraints()
    setupForgotPasswordButtonConstraints()
    setupLoginButtonConstraints()
    setupAccountLabelConstraints()

    let signInWithAppleButton = setupSignInWithAppleButton()
    setupLoginWithFacebookButtonConstraints(signInWithAppleButton)

    setupSignUpButtonConstraints()
    setupTermsOfUseButtonConstraints()
}

fileprivate func setupScrollViewConstraints() {
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        scrollView.topAnchor.constraint(equalTo: self.view.topAnchor),
        scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
        scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
        scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor)
    ])
}

fileprivate func setupLogoImageViewConstraints() {
    logoImageView.translatesAutoresizingMaskIntoConstraints = false
    
    if #available(iOS 11.0, *) {
        NSLayoutConstraint.activate([
            logoImageView.topAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.topAnchor, constant: 16),
            logoImageView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
            logoImageView.widthAnchor.constraint(equalToConstant: 112),
            logoImageView.heightAnchor.constraint(equalToConstant: 112)
        ])
    }
    else {
        NSLayoutConstraint.activate([
            logoImageView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16),
            logoImageView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
            logoImageView.widthAnchor.constraint(equalToConstant: 112),
            logoImageView.heightAnchor.constraint(equalToConstant: 112)
        ])
    }
}

fileprivate func setupUsernameTextFieldConstraints() {
    usernameTextField.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        usernameTextField.topAnchor.constraint(equalTo: logoImageView.bottomAnchor, constant: 16),
        usernameTextField.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        usernameTextField.widthAnchor.constraint(equalToConstant: self.view.frame.width / 1.4),
        usernameTextField.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupPasswordTextFieldConstraints() {
    passwordTextField.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        passwordTextField.topAnchor.constraint(equalTo: usernameTextField.bottomAnchor, constant: 8),
        passwordTextField.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        passwordTextField.widthAnchor.constraint(equalToConstant: self.view.frame.width / 1.4),
        passwordTextField.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupShowAndHideButtonConstraints() {
    showAndHideButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        showAndHideButton.leadingAnchor.constraint(equalTo: passwordTextField.trailingAnchor, constant: -30),
        showAndHideButton.trailingAnchor.constraint(equalTo: passwordTextField.trailingAnchor),
        showAndHideButton.centerYAnchor.constraint(equalTo: passwordTextField.centerYAnchor),
        showAndHideButton.heightAnchor.constraint(equalToConstant: 20)
    ])
}

fileprivate func setupForgotPasswordButtonConstraints() {
    forgotPasswordButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        forgotPasswordButton.topAnchor.constraint(equalTo: passwordTextField.bottomAnchor),
        forgotPasswordButton.leadingAnchor.constraint(equalTo: passwordTextField.leadingAnchor),
        forgotPasswordButton.trailingAnchor.constraint(equalTo: passwordTextField.trailingAnchor),
        forgotPasswordButton.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupLoginButtonConstraints() {
    loginButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        loginButton.topAnchor.constraint(equalTo: forgotPasswordButton.bottomAnchor, constant: 20),
        loginButton.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        loginButton.widthAnchor.constraint(equalToConstant: 210),
        loginButton.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupAccountLabelConstraints() {
    accountLabel.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        accountLabel.topAnchor.constraint(equalTo: loginButton.bottomAnchor, constant: 40),
        accountLabel.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        accountLabel.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupSignInWithAppleButton() -> UIControl? {
    if #available(iOS 13.0, *) {
        let signInWithAppleButton = ASAuthorizationAppleIDButton(type: .default, style: .white)
        
        signInWithAppleButton.addTarget(self, action: #selector(loginWithApple(_:)), for: .touchUpInside)
        signInWithAppleButton.cornerRadius = 12
        
        scrollView.addSubview(signInWithAppleButton)
        
        signInWithAppleButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            signInWithAppleButton.topAnchor.constraint(equalTo: accountLabel.bottomAnchor, constant: 8),
            signInWithAppleButton.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
            signInWithAppleButton.widthAnchor.constraint(equalToConstant: 210),
            signInWithAppleButton.heightAnchor.constraint(equalToConstant: 45)
        ])
        
        return signInWithAppleButton
    }
    
    return nil
}

fileprivate func setupLoginWithFacebookButtonConstraints(_ signInAppleButton: UIControl?) {
    facebookButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        facebookButton.topAnchor.constraint(equalTo: signInAppleButton?.bottomAnchor ?? accountLabel.bottomAnchor, constant: 8),
        facebookButton.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        facebookButton.widthAnchor.constraint(equalToConstant: 210),
        facebookButton.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupSignUpButtonConstraints() {
    signUpButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        signUpButton.topAnchor.constraint(equalTo: facebookButton.bottomAnchor, constant: 8),
        signUpButton.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        signUpButton.widthAnchor.constraint(equalToConstant: 210),
        signUpButton.heightAnchor.constraint(equalToConstant: 45)
    ])
}

fileprivate func setupTermsOfUseButtonConstraints() {
    termsButton.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
        termsButton.topAnchor.constraint(equalTo: signUpButton.bottomAnchor, constant: 8),
        termsButton.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
        termsButton.widthAnchor.constraint(equalToConstant: 210),
        termsButton.heightAnchor.constraint(equalToConstant: 50),
        termsButton.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor)
    ])
}

这个问题让我抓狂了好几天!我错过了什么?

您的 logoImageView 被限制在错误的地方...

// constrain Top to scrollView contentLayoutGuide Top
//logoImageView.topAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.topAnchor, constant: 16),
logoImageView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 16),