Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UIStackview“按比例填充”分配问题_Ios_Swift_Uistackview - Fatal编程技术网

Ios UIStackview“按比例填充”分配问题

Ios UIStackview“按比例填充”分配问题,ios,swift,uistackview,Ios,Swift,Uistackview,我有一个容器堆栈视图,它有两个其他堆栈视图,我们称它们为stackview 1和stackview 2。Stackview 2有一个带有一些标签的自定义UIView。 我的问题是stackview 1,它有两个排列的子视图。此视图的轴是垂直的。这些子视图是自定义的UIView。这些自定义视图可能包含文本或图像,并且这些自定义视图的高度不是预定义的,它们基于内容(即基于文本的高度) 自定义视图1和自定义视图2添加到stackview 1中。堆栈视图1和堆栈视图2添加到另一个容器堆栈视图中 我的问题

我有一个容器堆栈视图,它有两个其他堆栈视图,我们称它们为stackview 1和stackview 2。Stackview 2有一个带有一些标签的自定义
UIView

我的问题是stackview 1,它有两个排列的子视图。此视图的轴是垂直的。这些子视图是自定义的
UIView
。这些自定义视图可能包含文本或图像,并且这些自定义视图的高度不是预定义的,它们基于内容(即基于文本的高度)

自定义视图1和自定义视图2添加到stackview 1中。堆栈视图1和堆栈视图2添加到另一个容器堆栈视图中

我的问题是,即使我在
按比例填充
分布中为这些自定义视图返回
intrinsicContentSize
(基于文本视图的
intrinsicContentSize
),我也无法同时显示这两个自定义视图(在stackview 1中)

如果我在
intrinsicContentSize
中为customview返回一个常量
width
height
,则这两个视图都会正确显示

在我的
自定义视图中

override var intrinsicContentSize: CGSize {
    let size = CGSize.init(width: 100, height: 100)
    return size
   }  
  override var intrinsicContentSize: CGSize {
       let size = textView.intrinsicContentSize
       return size
       }
截图显示了这种行为

但是,如果我根据
UITextView
(customView的子视图,我已禁用textview的滚动)的
intrinsicContentSize
返回大小,则仅显示customView 2,而不显示另一个视图(customView 1)

在我的
自定义视图中

override var intrinsicContentSize: CGSize {
    let size = CGSize.init(width: 100, height: 100)
    return size
   }  
  override var intrinsicContentSize: CGSize {
       let size = textView.intrinsicContentSize
       return size
       }
截图显示了这种行为

我希望
按比例填充
行为,但我无法使其按我希望的方式工作,即同时显示两个视图(自定义视图1和自定义视图2)。
根据文档
按比例填充
使用
intrinsicContentSize
按比例填充视图。但是,为什么即使在我重写了
intrinsicContentSize
var之后,这种方法在我的情况下仍然不起作用呢

为什么自定义视图1在覆盖其固有内容大小后仍具有零高

我希望这两个自定义视图都显示在堆栈视图1中


我被困在这里,因此我非常感谢您的帮助。

根据我的经验,
UIStackView
.filly
属性是自动布局中最容易被误解的元素之一

所以,我不完全确定这会给你你想要的,但是试一下

点击
文本
按钮将更改“描述”文本,点击
高度
按钮将更改“容器”视图的高度,因此您可以看到不同文本量下的外观

报告
按钮将打印视图的最终高度和比例

全部通过代码-无
@IBOutlet
@IBAction
连接-因此,只需从新的视图控制器开始,并将其自定义类分配给
ControllStackViewController

class ProportionalHeightView: UIView {

    let myNonScrollTextView: UITextView = {
        let v = UITextView()
        v.isScrollEnabled = false
        v.setContentHuggingPriority(.required, for: .vertical)
        return v
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    func commonInit() -> Void {

        let padding: CGFloat = 0.0
        addSubview(myNonScrollTextView)
        myNonScrollTextView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            myNonScrollTextView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding),
            myNonScrollTextView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding),

            // if we want the text top-aligned
            //myNonScrollTextView.topAnchor.constraint(equalTo: topAnchor),

            // if we want the text vertically=sentered
            myNonScrollTextView.centerYAnchor.constraint(equalTo: centerYAnchor),
        ])

    }

    override func layoutSubviews() {
        super.layoutSubviews()
        myNonScrollTextView.sizeToFit()
        invalidateIntrinsicContentSize()
    }

    override var intrinsicContentSize: CGSize {
        return myNonScrollTextView.bounds.size
    }
}

class TitleView: ProportionalHeightView {

    override func commonInit() {
        super.commonInit()
        myNonScrollTextView.font = UIFont.systemFont(ofSize: 22.0, weight: .bold)
        myNonScrollTextView.backgroundColor = .cyan
        backgroundColor = .blue
    }

}
class DescView: ProportionalHeightView {

    override func commonInit() {
        super.commonInit()
        myNonScrollTextView.font = UIFont.systemFont(ofSize: 17.0, weight: .regular)
        myNonScrollTextView.backgroundColor = .yellow
        backgroundColor = .orange
    }

}

class ProportionalStackViewController: UIViewController {

    var titleView: ProportionalHeightView = {
        let v = ProportionalHeightView()
        v.myNonScrollTextView.font = UIFont.systemFont(ofSize: 22.0, weight: .bold)
        v.myNonScrollTextView.backgroundColor = .cyan
        v.backgroundColor = .blue
        return v
    }()
    var descView: ProportionalHeightView = {
        let v = ProportionalHeightView()
        v.myNonScrollTextView.font = UIFont.systemFont(ofSize: 16.0, weight: .regular)
        v.myNonScrollTextView.backgroundColor = .yellow
        v.backgroundColor = .orange
        return v
    }()

    let containerView: UIView = {
        let v = UIView()
        v.backgroundColor = .white
        return v
    }()

    let proportionalStackView: UIStackView = {
        let v = UIStackView()
        v.axis = .vertical
        v.distribution = .fillProportionally
        return v
    }()

    let changeTextButton: UIButton = {
        let b = UIButton()
        b.backgroundColor = .gray
        b.setTitle("Text", for: .normal)
        return b
    }()
    let changeHeightButton: UIButton = {
        let b = UIButton()
        b.backgroundColor = .gray
        b.setTitle("Height", for: .normal)
        return b
    }()
    let reportButton: UIButton = {
        let b = UIButton()
        b.backgroundColor = .gray
        b.setTitle("Report", for: .normal)
        return b
    }()
    let btnStack: UIStackView = {
        let v = UIStackView()
        v.distribution = .fillEqually
        v.spacing = 20
        return v
    }()

    var nLines = 0

    var containerH = NSLayoutConstraint()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .systemTeal

        btnStack.translatesAutoresizingMaskIntoConstraints = false
        proportionalStackView.translatesAutoresizingMaskIntoConstraints = false
        containerView.translatesAutoresizingMaskIntoConstraints = false

        // add a horizontal stack view with buttons at the top
        btnStack.addArrangedSubview(changeTextButton)
        btnStack.addArrangedSubview(changeHeightButton)
        btnStack.addArrangedSubview(reportButton)

        view.addSubview(btnStack)

        // set text for titleView
        titleView.myNonScrollTextView.text = "Pleasanton Panthers"
        descView.myNonScrollTextView.text = "A one stop destination for all the Panthers fans! Experience our new futuristic techology-enabled fan experience an much more!" // "Single line"

        proportionalStackView.addArrangedSubview(titleView)
        proportionalStackView.addArrangedSubview(descView)

        containerView.addSubview(proportionalStackView)
        view.addSubview(containerView)

        // respect safe area
        let g = view.safeAreaLayoutGuide

        containerH = containerView.heightAnchor.constraint(equalToConstant: 240.0)

        NSLayoutConstraint.activate([

            // buttons stack 20-pts from top / leading / trailing
            btnStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            btnStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            btnStack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),

            // container view 20-pts from bottom of buttons, 20-pts from leading / trailing
            containerView.topAnchor.constraint(equalTo: btnStack.bottomAnchor, constant: 20.0),
            containerView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            containerView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),

            // container view height
            containerH,

            // constrain stack view 20-pts from top/bottom/leading/trailing to container
            proportionalStackView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 20.0),
            proportionalStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -20.0),
            proportionalStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 20.0),
            proportionalStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -20.0),

        ])

        changeTextButton.addTarget(self, action: #selector(changeText), for: .touchUpInside)
        changeHeightButton.addTarget(self, action: #selector(changeHeight), for: .touchUpInside)
        reportButton.addTarget(self, action: #selector(report), for: .touchUpInside)

        [titleView, titleView.myNonScrollTextView, descView, descView.myNonScrollTextView].forEach {
            v in
            // un-comment next line to clear background colors
            //v.backgroundColor = .clear
        }
    }

    @objc func report() -> Void {

        let titleTextH = titleView.myNonScrollTextView.frame.size.height
        let descTextH = descView.myNonScrollTextView.frame.size.height

        let titleViewH = titleView.frame.size.height
        let descViewH = descView.frame.size.height

        let tRatio = titleTextH / descTextH
        let vRatio = titleViewH / descViewH

        print("text heights:\t", titleTextH, descTextH)
        print("view heights:\t", titleViewH, descViewH)
        print("Text view ratio: \(tRatio) view ratio: \(vRatio)")

    }

    @objc func changeHeight() -> Void {
        if containerView.frame.origin.y + containerView.frame.size.height > view.frame.size.height - 20 {
            containerH.constant = 220
        }
        containerH.constant += 20
    }

    @objc func changeText() -> Void {
        nLines += 1
        if nLines > 10 {
            descView.myNonScrollTextView.text = "A one stop destination for all the Panthers fans! Experience our new futuristic techology-enabled fan experience an much more!" // "Single line"
            nLines = 0
            return
        }
        var s = ""
        for i in 1..<nLines {
            s += "Line \(i)\n"
        }
        s += "Line \(nLines)"
        descView.myNonScrollTextView.text = s
    }

}
类比例权重视图:UIView{
让myNonScrollTextView:UITextView={
设v=UITextView()
v、 IsScrolEnabled=false
v、 setContentHuggingPriority(.必选,用于:。垂直)
返回v
}()
重写初始化(帧:CGRect){
super.init(frame:frame)
commonInit()
}
必需初始化?(编码器:NSCoder){
super.init(编码器:编码器)
commonInit()
}
func commonInit()->Void{
让填充:CGFloat=0.0
addSubview(myNonScrollTextView)
myNonScrollTextView.translatesAutoresizingMaskIntoConstraints=false
NSLayoutConstraint.activate([
myNonScrollTextView.leadingAnchor.constraint(等式:leadingAnchor,常量:padding),
myNonScrollTextView.trailingAnchor.constraint(等式:trailingAnchor,常量:-填充),
//如果我们想让文本顶部对齐
//myNonScrollTextView.topAnchor.constraint(等式:topAnchor),
//如果我们希望文本垂直=senter
myNonScrollTextView.centerYAnchor.constraint(相等于:centerYAnchor),
])
}
覆盖func布局子视图(){
super.layoutSubviews()
myNonScrollTextView.sizeToFit()
InvalidateIntriseContentSize()无效
}
重写变量intrinsicContentSize:CGSize{
返回myNonScrollTextView.bounds.size
}
}
类标题视图:比例八视图{
重写func commonInit(){
super.commonInit()
myNonScrollTextView.font=UIFont.systemFont(尺寸:22.0,重量:粗体)
myNonScrollTextView.backgroundColor=.cyan
背景颜色=.blue
}
}
类描述视图:比例权重视图{
重写func commonInit(){
super.commonInit()
myNonScrollTextView.font=UIFont.systemFont(尺寸:17.0,重量:普通)
myNonScrollTextView.backgroundColor=.yellow
背景颜色=.橙色
}
}
类:UIViewController{
变量标题视图:比例权重视图={
设v=proportalheightview()
v、 myNonScrollTextView.font=UIFont.systemFont(尺寸:22.0,重量:粗体)
v、 myNonScrollTextView.backgroundColor=.cyan
v、 背景颜色=.blue
返回v
}()
变量描述视图:比例权重视图={
设v=proportalheightview()
v、 myNonScrollTextView.font=UIFont.systemFont(尺寸:16.0,重量:普通)
v、 myNonScrollTextView.backgroundColor=.yellow
v、 背景颜色=.橙色
返回v
}()
让containerView:UIView={
设v=UIView()
v、 背景颜色=白色
返回v
}()
让比例堆栈视图:UIStackView={
设v=UIStackView()
v、 轴=垂直
v、 分布=按比例填充
返回v
}()
让changeTextButton:UIButton={
设b=UIButton()
b、 背景颜色=.灰色