UIStackview `fillProportionally` distribution issue
我有一个容器堆栈视图,它还有其他2个stackview,可以将它们分别称为stackview 1和stackview2。Stackview 2有一个带有某些标签的自定义
我的问题是与stackview 1,它有2个安排的子视图。此
在堆栈视图1中添加了自定义视图1和自定义视图2。在另一个容器堆栈视图中添加了堆栈视图1和堆栈视图2。
我的问题是,即使我为
如果我在
在我的
内
1 2 3 4 | override var intrinsicContentSize: CGSize { let size = CGSize.init(width: 100, height: 100) return size } |
屏幕截图显示了此行为。
但是如果我基于
在我的
内
1 2 3 4 | override var intrinsicContentSize: CGSize { let size = textView.intrinsicContentSize return size } |
屏幕截图显示了此行为。
我想要
根据文档,
为什么自定义视图1甚至在覆盖其固有内容大小后仍具有零高?
我希望这两个自定义视图都显示在堆栈视图1内。
我被困在这里,不胜感激。
所以,我不完全确定这会给您想要的东西,但是请尝试一下。
点击
全部通过代码-没有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | 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)\ " } s +="Line \\(nLines)" descView.myNonScrollTextView.text = s } } |