Swift 嵌套堆栈视图

Posted

技术标签:

【中文标题】Swift 嵌套堆栈视图【英文标题】:Swift Nested Stack Views 【发布时间】:2017-10-12 12:34:53 【问题描述】:

来自 android 背景的现在尝试通过简单的登录视图示例来理解 ios 中的 UIStackView,但因输出失真而感到困惑。以下是我的详细信息:

我的登录视图文件:

import UIKit
import SnapKit

class LoginView: UIView 

    let loginStackView = UIStackView();

    let emailStackView = UIStackView()
    let emailImageView = UIImageView()
    let emailTextView = UITextView();

    let passStackView = UIStackView()
    let passImageView = UIImageView()
    let passTextView = UITextView();

    let loginButton = UIButton();
    let loginButton2 = UIButton();

    override init(frame: CGRect) 
        super.init(frame: frame)
        loadUI();
    

    required init?(coder: NSCoder) 
        super.init(coder: coder)
    

    private func loadUI()

        self.addSubview(loginStackView);

        emailStackView.axis = .horizontal
        emailStackView.distribution = .equalSpacing
        emailStackView.translatesAutoresizingMaskIntoConstraints = false
        emailStackView.addArrangedSubview(emailImageView);
        emailStackView.addArrangedSubview(emailTextView);

        passStackView.axis = .horizontal
        passStackView.distribution = .equalSpacing
        passStackView.translatesAutoresizingMaskIntoConstraints = false
        passStackView.addArrangedSubview(passImageView);
        passStackView.addArrangedSubview(passTextView);

        loginStackView.axis = .vertical
        loginStackView.distribution = .fill
        loginStackView.alignment = .fill
        loginStackView.spacing = 10
        loginStackView.translatesAutoresizingMaskIntoConstraints = false
        loginStackView.addArrangedSubview(emailStackView);
        loginStackView.addArrangedSubview(loginButton);
        loginStackView.addArrangedSubview(passStackView);
        loginStackView.addArrangedSubview(loginButton2);
        loginStackView.snp.makeConstraints(make) -> Void in
            make.center.equalToSuperview();
        

        emailImageView.image = UIImage(named: "sample");
        emailImageView.snp.makeConstraints(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(50)
        

        emailTextView.snp.makeConstraints(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(200)
        


        passImageView.image = UIImage(named: "sample2");
        passImageView.snp.makeConstraints(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(50)
        


        passTextView.snp.makeConstraints(make) -> Void in
            make.height.equalTo(50)
            make.width.equalTo(200)
        

        loginButton.setTitle("Login", for: .normal);
        loginButton.snp.makeConstraints (make) in
            make.height.equalTo(50)
            make.width.equalTo(250)
        

        loginButton2.setTitle("Login2", for: .normal);
        loginButton2.snp.makeConstraints (make) in
            make.height.equalTo(50)
            make.width.equalTo(250)
        


    


然后我像这样在登录视图控制器中使用这个类:

let superview = self.view;

let loginView = LoginView();
superview?.addSubview(loginView);
superview?.backgroundColor = UIColor.lightGray;
loginView.backgroundColor = UIColor.red;

loginView.snp.makeConstraints(make) -> Void in
make.height.equalTo(superview!);
make.width.equalTo(superview!);

对于上面的代码,我的输出是这样的:

我的查询:

    为什么 passStackView 之前的视图没有显示? 为什么 loginView 不能全屏显示(限制在 loginStackView 上假设将 loginStackView 放入 loginView 的中间)

只有在使用单个堆栈一切正常时,嵌套堆栈视图才会发生这种情况。请让我知道我在这里缺少什么。

这是我所期待的:

【问题讨论】:

你在所有修改后尝试self.addSubview(loginStackView)吗? 尝试设置更多的约束,例如here 【参考方案1】:

你真的只是错过了两个设置:

    loginView.snp.makeConstraints(make) -> Void in
        make.height.equalTo(superview!);
        make.width.equalTo(superview!);

        // you also need to set position,
        // this will center the view
        make.centerX.equalTo(superview!);
        make.centerY.equalTo(superview!);
    

请注意,您还有一个“内置”superview 方法,因此可以这样写:

    loginView.snp.makeConstraints(make) -> Void in
        make.width.equalToSuperview()
        make.height.equalToSuperview()
        make.centerX.equalToSuperview()
        make.centerY.equalToSuperview()
    

强烈推荐给您...我知道很多人使用 SnapKit 是为了方便,您可能会发现学习如何自动布局和约束起作用。当您遇到这种情况时,只需了解它的基础知识就会大有帮助。

无论如何,它的价值。

【讨论】:

就是这样,我认为只是让宽度和高度等于超级视图会占用整个屏幕,因为它适用于单个堆栈视图。我会认真注意您对自动布局的建议。谢谢

以上是关于Swift 嵌套堆栈视图的主要内容,如果未能解决你的问题,请参考以下文章

嵌套堆栈视图:以编程方式附加子堆栈视图时,子堆栈视图不在其父堆栈视图内

无法满足嵌套堆栈视图的约束

如何解决嵌套堆栈视图的布局问题?

如何控制嵌套在另一个堆栈视图中的 UIStackViews 的相对宽度?

使用 xamarin.ios c# 以编程方式添加嵌套的堆栈视图

尝试以编程方式使用嵌套的 Stack 视图制作网格