gpt4 book ai didi

ios - UIStackView,2 个标签 : Change Axis based on size

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:10:48 25 4
gpt4 key购买 nike

我在水平 UIStackView 中嵌入了两个标签。其中一个标签可能变得太大,因此其中一个被截断。

或者,它们的大小按某种比例拆分并且垂直增长。

我想要实现的是,如果标签不合适,让 UIStackViewaxis 更改为 vertical

请引用下面的两张图:

图 1:标签排成一行,使用了水平轴。
图 2:其中一个标签是多行的。使用垂直轴。

使用 UICollectionViewFlowLayout 时的行为类似。

Example StackView behavior

最佳答案

试一试。你只需要测量文本,你必须有一个用另一个堆栈 View 包裹的堆栈 View 。

import UIKit

class ViewController: UIViewController {

var stackView : UIStackView?
var outerStackView : UIStackView?
var label1 = UILabel()
var label2 = UILabel()

var heightAnchor : NSLayoutConstraint?
var widthAnchor : NSLayoutConstraint?
var button : UIButton?

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
createStackView()
createLabelsAndAddToStack()

button = UIButton(frame: CGRect(x: 20, y: self.view.frame.height - 60, width: self.view.frame.width - 40, height: 40))
button?.backgroundColor = .green
button?.setTitleColor(.black, for: .normal)
button?.setTitle("Toggle Text", for: .normal)
button?.addTarget(self, action: #selector(toggleText), for: .touchUpInside)
button?.setTitleColor(.gray, for: .highlighted)
self.view.addSubview(button!)
}

func createStackView(){

outerStackView = UIStackView(frame: CGRect(x: 20, y: 20, width: self.view.bounds.width - 40, height: 100))
outerStackView?.axis = .vertical
outerStackView?.distribution = .fill
outerStackView?.alignment = .center
outerStackView?.translatesAutoresizingMaskIntoConstraints = false

self.view.addSubview(outerStackView!)

outerStackView?.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 40).isActive = true
outerStackView?.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -40).isActive = true
outerStackView?.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true


stackView = UIStackView(frame: CGRect(x: 20, y: 20, width: self.view.bounds.width - 40, height: 100))
stackView?.alignment = .center
stackView?.spacing = 20
stackView?.distribution = .fillEqually
stackView?.axis = .horizontal
outerStackView?.addArrangedSubview(stackView!)

heightAnchor = stackView?.heightAnchor.constraint(equalTo: outerStackView!.heightAnchor)
widthAnchor = stackView?.widthAnchor.constraint(equalTo: outerStackView!.widthAnchor)

}

func createLabelsAndAddToStack(){
label1 = UILabel(frame: .zero)
label1.textColor = .black
label1.font = UIFont.systemFont(ofSize: 17)
label1.text = "Label 1"
label1.numberOfLines = 0
stackView?.addArrangedSubview(label1)

label2 = UILabel(frame: .zero)
label2.font = UIFont.systemFont(ofSize: 17)
label2.textColor = .green
label2.text = "Label 2"
label2.numberOfLines = 0
stackView?.addArrangedSubview(label2)

}

func adaptStackView(){

self.outerStackView?.layoutIfNeeded()
self.stackView?.layoutIfNeeded()
//let maxWidth = label2.frame.width
//if you want it to be the max it could be
let maxWidth = (self.outerStackView!.frame.width - stackView!.spacing)/2
let height = label2.font.lineHeight

if let label1Text = label1.text{
//lets measure
if label1Text.width(withConstraintedHeight: height, font: label1.font) > maxWidth{
outerStackView?.axis = .horizontal
outerStackView?.distribution = .fill

stackView?.axis = .vertical
stackView?.distribution = .fill
stackView?.alignment = .leading

widthAnchor?.isActive = true
heightAnchor?.isActive = true

}else{
outerStackView?.axis = .vertical
outerStackView?.distribution = .fill

stackView?.alignment = .center
stackView?.axis = .horizontal
stackView?.distribution = .fillEqually

stackView?.removeConstraints(self.stackView!.constraints)
widthAnchor?.isActive = false
widthAnchor?.isActive = false
}

UIView.animate(withDuration: 0.5) {
self.view.layoutIfNeeded()
}
}
}

@objc func toggleText(){
if label1.text == "Label 1"{
label1.text = "This is some longer text to test everything out to see how we are doing"

}else{
label1.text = "Label 1"
}
adaptStackView()
}

}

extension String{
func width(withConstraintedHeight height: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
let boundingBox = self.boundingRect(with: constraintRect, options: [.usesLineFragmentOrigin], attributes: [.font: font], context: nil)

return ceil(boundingBox.width)
}
}

stackgif

关于ios - UIStackView,2 个标签 : Change Axis based on size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50144261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com