微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的StackView无法正常工作?元素完全移位

如何解决为什么我的StackView无法正常工作?元素完全移位

嘿,我的StackView什么都不做,有两个问题: 首先是当我转过模拟器或更换设备时,VC上的元素已完全移位,因此StackView并未执行应做的工作! 第二件事是StackView覆盖了导航栏,我不知道如何使其可见。 有人可以帮我吗?

import UIKit


class RegisterViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
    
    let stackView = UIStackView()
    
    
    var profilePicture = UIButton()
    var profileIcon = UIImage()
    let usernameTextField = UITextField()
    let emailTextField = UITextField()
    let passswordTextField = UITextField()
    let signInButton = UIButton()
    
    
   
    

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Create an Account"
        view.backgroundColor = .white
        
        
        
        
        
        // SetUp StackView:
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.alignment = .center
        stackView.distribution = .fillEqually
        stackView.spacing = 50
        view.addSubview(stackView)
       
        
        // SetUp Stack View Constraints:
       
        stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 20).isActive = true
        stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
               
        
        //Add Elements
        
        stackView.addArrangedSubview(profilePicture)
        stackView.addArrangedSubview(usernameTextField)
        stackView.addArrangedSubview(passswordTextField)
        stackView.addArrangedSubview(signInButton)
        
        
    
    
// MARK: - Set-Up View-Elements
    
    
    // SetUp ProfileIcon:
        profileIcon = UIImage(named: "characteer")!
        profilePicture.setimage(profileIcon,for: .normal)
        profilePicture.imageView?.contentMode = .scaleAspectFill
        let cornerRadius: CGFloat
         cornerRadius = 75 // half of widht/height
        profilePicture.layer.cornerRadius = cornerRadius
        profilePicture.layer.masksToBounds = true
        profilePicture.layer.borderWidth = 1
        profilePicture.layer.borderColor = UIColor.white.cgColor
        profilePicture.addTarget(self,action: #selector(handleSelectedPhoto),for: .touchUpInside)
        
        
        view.addSubview(profilePicture)
        
       profilePicture.translatesAutoresizingMaskIntoConstraints = false
       profilePicture.heightAnchor.constraint(equalToConstant: 150).isActive = true
       profilePicture.widthAnchor.constraint(equalToConstant: 150).isActive = true
       profilePicture.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        profilePicture.topAnchor.constraint(equalTo: view.topAnchor,constant: 110).isActive = true
        
     
        
        // SetUp UsernameTextfield:
    usernameTextField.backgroundColor = .white
    usernameTextField.attributedplaceholder = NSAttributedString(string: "Username",attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
    usernameTextField.textAlignment = NSTextAlignment.center
    usernameTextField.layer.cornerRadius = 8
    usernameTextField.layer.borderWidth = 1
    usernameTextField.layer.borderColor = UIColor.lightGray.cgColor
    self.view.addSubview(usernameTextField)
    let username = usernameTextField.text
    
    usernameTextField.translatesAutoresizingMaskIntoConstraints = false
    
    usernameTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 20).isActive = true
    usernameTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20).isActive = true
    usernameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
    usernameTextField.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    
        
    
// SetUpEmailTextfield:
    emailTextField.backgroundColor = .white
           emailTextField.attributedplaceholder = NSAttributedString(string: "Email",attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
           emailTextField.textAlignment = NSTextAlignment.center
           emailTextField.layer.cornerRadius = 8
           emailTextField.layer.borderWidth = 1
           emailTextField.layer.borderColor = UIColor.lightGray.cgColor
           self.view.addSubview(emailTextField)
           
           emailTextField.translatesAutoresizingMaskIntoConstraints = false
           emailTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 20).isActive = true
           emailTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20).isActive = true
           emailTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
           emailTextField.topAnchor.constraint(equalTo: usernameTextField.bottomAnchor,constant: 20).isActive = true
        
        ```

解决方法

我只为profilePicture和usernameTextField进行了设置,但对于其他设置却一样。代码的错误方面是关于约束的,您向对象添加了两个不同的视图。有解决办法。

    let stackView = UIStackView()
    
    
    var profilePicture = UIButton()
    var profileIcon = UIImage()
    let usernameTextField = UITextField()
    let emailTextField = UITextField()
    let passswordTextField = UITextField()
    let signInButton = UIButton()
    
    
   
    

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Create an Account"
        view.backgroundColor = .white
        
        
        
        
        
        // SetUp StackView:
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.alignment = .center
        stackView.distribution = .fillEqually
        stackView.spacing = 50
        view.addSubview(stackView)
       
        
        // SetUp Stack View Constraints:
       
        stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 20).isActive = true
        stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor,constant: 20).isActive = true
        stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -20).isActive = true
               
        
        //Add Elements
        
        stackView.addArrangedSubview(profilePicture)
        stackView.addArrangedSubview(usernameTextField)
        
        
    
    
// MARK: - Set-Up View-Elements
    
    
    // SetUp ProfileIcon:
       profileIcon = UIImage(named: "characteer")!
        profilePicture.setImage(profileIcon,for: .normal)
        profilePicture.imageView?.contentMode = .scaleAspectFill
        let cornerRadius: CGFloat
         cornerRadius = 75 // half of widht/height
        profilePicture.layer.cornerRadius = cornerRadius
        profilePicture.layer.masksToBounds = true
        profilePicture.layer.borderWidth = 1
        profilePicture.layer.borderColor = UIColor.white.cgColor
        //profilePicture.addTarget(self,action: #selector(handleSelectedPhoto),for: .touchUpInside)
        
        
       profilePicture.translatesAutoresizingMaskIntoConstraints = false
       profilePicture.heightAnchor.constraint(equalToConstant: 150).isActive = true
       profilePicture.widthAnchor.constraint(equalToConstant: 150).isActive = true
        
     
        
        // SetUp UsernameTextfield:
    usernameTextField.backgroundColor = .white
    usernameTextField.attributedPlaceholder = NSAttributedString(string: "Username",attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
    usernameTextField.textAlignment = NSTextAlignment.center
    usernameTextField.layer.cornerRadius = 8
    usernameTextField.layer.borderWidth = 1
    usernameTextField.layer.borderColor = UIColor.lightGray.cgColor
    let username = usernameTextField.text
    
    usernameTextField.translatesAutoresizingMaskIntoConstraints = false
        usernameTextField.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width-40).isActive = true
    usernameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
,

我认为您的约束存在问题。

profilePicture.centerXAnchor.constraint(equalTo:view.centerXAnchor).isActive = true profilePicture.topAnchor.constraint(等于:view.topAnchor,常数:110).isActive = true

试图居中显示在屏幕中央,但是它们在堆栈视图内部。此外,在这种情况下,您还必须给静态高度以堆叠视图。

,

您做错了很多事情……最好花一些时间来学习一些有关自动布局并使用UIStackView的教程。

首先,如果您将视图(图像视图,文本字段,标签,按钮等)添加到堆栈视图中, 请勿 也将这些视图的位置限制。这就是堆栈视图正在做的事情。

第二,添加视图后:

stackView.addArrangedSubview(profilePicture)

请勿 ,然后将其添加为子视图,如下所示:

view.addSubview(profilePicture)

这样做会从堆栈视图中删除 profilePicture

浏览一下您的代码-查看我进行了更改的注释:

class RegisterViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
    
    let stackView = UIStackView()
    
    var profilePicture = UIButton()
    var profileIcon = UIImage()
    let usernameTextField = UITextField()
    let emailTextField = UITextField()
    let passswordTextField = UITextField()
    let signInButton = UIButton()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Create an Account"
        view.backgroundColor = .white
        
        
        // SetUp StackView:
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.alignment = .center
        
        // distribution should be .fill  NOT  .fillEqually
        stackView.distribution = .fill
        
        stackView.spacing = 50
        view.addSubview(stackView)
        
        // SetUp Stack View Constraints:
        
        stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor,constant: 20).isActive = true
        stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        //Add Elements
        
        stackView.addArrangedSubview(profilePicture)
        stackView.addArrangedSubview(usernameTextField)
        stackView.addArrangedSubview(emailTextField)
        stackView.addArrangedSubview(passswordTextField)
        stackView.addArrangedSubview(signInButton)
        
        // MARK: - Set-Up View-Elements
        
        // SetUp ProfileIcon:
        //profileIcon = UIImage(named: "characteer")!
        profileIcon = UIImage(named: "pro1")!
        profilePicture.setImage(profileIcon,for: .normal)
        profilePicture.imageView?.contentMode = .scaleAspectFill
        let cornerRadius: CGFloat
        cornerRadius = 75 // half of widht/height
        profilePicture.layer.cornerRadius = cornerRadius
        profilePicture.layer.masksToBounds = true
        profilePicture.layer.borderWidth = 1
        profilePicture.layer.borderColor = UIColor.white.cgColor
        //profilePicture.addTarget(self,for: .touchUpInside)
        
        // NO - it's already in the stack view
        //view.addSubview(profilePicture)
        
        // Set Only Width and Height - position is managed by the stack view
        profilePicture.heightAnchor.constraint(equalToConstant: 150).isActive = true
        profilePicture.widthAnchor.constraint(equalToConstant: 150).isActive = true
        
        // SetUp UsernameTextfield:
        usernameTextField.backgroundColor = .white
        usernameTextField.attributedPlaceholder = NSAttributedString(string: "Username",attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
        usernameTextField.textAlignment = NSTextAlignment.center
        usernameTextField.layer.cornerRadius = 8
        usernameTextField.layer.borderWidth = 1
        usernameTextField.layer.borderColor = UIColor.lightGray.cgColor

        // NO - it's already in the stack view
        //  self.view.addSubview(usernameTextField)
        let username = usernameTextField.text
        
        // Set Only Width and Height - position is managed by the stack view
        usernameTextField.widthAnchor.constraint(equalTo: view.widthAnchor,constant: -40).isActive = true
        usernameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
        
        // SetUpEmailTextfield:
        emailTextField.backgroundColor = .white
        emailTextField.attributedPlaceholder = NSAttributedString(string: "Email",attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
        emailTextField.textAlignment = NSTextAlignment.center
        emailTextField.layer.cornerRadius = 8
        emailTextField.layer.borderWidth = 1
        emailTextField.layer.borderColor = UIColor.lightGray.cgColor

        // NO - it's already in the stack view
        //  self.view.addSubview(emailTextField)
        
        // Set Only Width and Height - position is managed by the stack view
        emailTextField.widthAnchor.constraint(equalTo: view.widthAnchor,constant: -40).isActive = true
        emailTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
        
        // SetUp PasswordTextfield:
        passswordTextField.backgroundColor = .white
        passswordTextField.attributedPlaceholder = NSAttributedString(string: "Password",attributes: [NSAttributedString.Key.foregroundColor: UIColor.lightGray])
        passswordTextField.textAlignment = NSTextAlignment.center
        passswordTextField.layer.cornerRadius = 8
        passswordTextField.layer.borderWidth = 1
        passswordTextField.layer.borderColor = UIColor.lightGray.cgColor

        // NO - it's already in the stack view
        //  self.view.addSubview(emailTextField)
        
        // Set Only Width and Height - position is managed by the stack view
        passswordTextField.widthAnchor.constraint(equalTo: view.widthAnchor,constant: -40).isActive = true
        passswordTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
        
        signInButton.setTitle("Sign In",for: [])
        signInButton.backgroundColor = .blue

        // Set Only Width and Height - position is managed by the stack view
        signInButton.widthAnchor.constraint(equalTo: view.widthAnchor,constant: -40).isActive = true
        signInButton.heightAnchor.constraint(equalToConstant: 50).isActive = true

    }

}

当然,使用该布局-您在50磅的元素之间指定了垂直间距,并且为每个元素设置了明确的高度,您可能会发现它在整个范围上都不“很合适”不同的设备/屏幕尺寸。

因此,正如您在上一个问题中向您指出的:Why is my VC displaced after changing the Simulator? AutoLayout-您可能想将堆栈视图的“分布”更改为“等间距”并添加一个底部约束:

    stackView.distribution = .equalSpacing
    stackView.spacing = 0

    stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor,constant: -20).isActive = true

这可能会或可能不会完全给您您想要的东西,但这是一个起点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。