0

在过去几周与程序化动态 UI 元素作斗争后,我决定尝试一下 UIstackView。我希望自定义 UIView 类根据我要删除的用户输入以不同的高度占据堆栈视图,动态添加视图。

我发现 stackViews 的“单元格”高度基于 UI 元素的内在内容大小。然而,UIViews 没有。我进行了广泛搜索,发现我需要用一个可以显式设置宽度和高度的函数来覆盖视图的 intrisicContentsize 函数。然而结果是非常不可预测的,我敢肯定有一些小事情我只是不知道 dat 会导致这种奇怪的行为。由于我是该语言的新手并且有很多陷阱,我只是将代码粘贴到这里,希望您能够发现我做错了什么。

我已经阅读了ofc的文档,很多文章,它们都指向了似乎对我不起作用的覆盖功能。

这是我的 mainViewController 类;

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

var bv = BackButtonView(frame: CGRect.zero, image: UIImage(named: "backArrow.png")!)

var redView : UIView  = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .red
    return view
}();

var blueView : UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .blue
    return view
}();

let stack : UIStackView = {
    let stack = UIStackView();
    stack.translatesAutoresizingMaskIntoConstraints = false;
    stack.axis = .vertical
    stack.distribution = .fillProportionally;
    stack.spacing = 8
    return stack;
}();

override func viewDidLoad() {
    let view = UIView(frame: UIScreen.main.bounds)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .white
    self.view = view
    self.view.addSubview(stack)
    createLayout()
    bv.intrinsicContentSize
    stack.addArrangedSubview(bv)
    print(bv.frame)
    print(bv.intrinsicContentSize)
    stack.layoutIfNeeded()
    stack.addArrangedSubview(redView)
    stack.addArrangedSubview(blueView)

}

private func setConstraints(view: UIView) -> [NSLayoutConstraint] {
    return [
        view.heightAnchor.constraint(equalToConstant: 50),
    ]
}

private func createLayout() {
    stack.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    stack.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    stack.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    stack.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true

}
}

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = MyViewController()

现在这是我的自定义 UIClass,它给我带来了所有这些麻烦:

import UIKit

public class BackButtonView : UIView {


public var size = CGSize(width: 10, height: UIView.noIntrinsicMetric)
override open var intrinsicContentSize: CGSize {
     return size
}

var button : UIButton;

public init(frame: CGRect, image: UIImage) {
    button = UIButton()
    super.init(frame : frame);
    self.translatesAutoresizingMaskIntoConstraints = false;
    self.backgroundColor = .black
    self.addSubview(button)
    setupButton(image: image);
    print(button.intrinsicContentSize)
}
let backButtonTrailingPadding : CGFloat = -18

lazy var buttonConstraints = [
    button.heightAnchor.constraint(equalToConstant: 50),
    button.widthAnchor.constraint(equalToConstant: 50),
    button.centerYAnchor.constraint(equalTo: self.centerYAnchor),
    button.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: backButtonTrailingPadding),
]
private func setupButton(image: UIImage) {
    self.button.translatesAutoresizingMaskIntoConstraints = false;
    self.button.setImage(image, for: .normal);
    self.button.contentMode = .scaleToFill
    NSLayoutConstraint.activate(buttonConstraints)

}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

struct anchors {
    var topAnchor = NSLayoutConstraint()
    var bottomAnchor = NSLayoutConstraint()
    var leadingAnchor = NSLayoutConstraint()
    var trailingAnchor = NSLayoutConstraint()
}

}

您可以看到 size 属性中的指定宽度被忽略。在上述条件下,这是输出

这里的高度相等 如果我现在将自定义 UIClass 的 intrisiContentSize 高度更改为其他任何值,则会发生这种情况:

    public var size = CGSize(width: UIView.noIntrinsicMetric, height: 10)
override open var intrinsicContentSize: CGSize {
     return size
}

结果: 在此处输入图像描述

请帮我弄清楚发生了什么和没有发生什么

最终屏幕应如下所示:

在此处输入图像描述

4

0 回答 0