UIStackView 和截断的多行 UILabel

Posted

技术标签:

【中文标题】UIStackView 和截断的多行 UILabel【英文标题】:UIStackView and truncated Multiline UILabels 【发布时间】:2015-11-02 12:26:52 【问题描述】:

我想向UIStackView 添加几个多行标签。

但我的标签总是被截断。如本截图所示

但我更喜欢这里显示的内容(我的伪造截图)

这是我的代码。首先,我创建父/主 StackView,将其放入 ScrollView(隐藏在屏幕上)

    stackView = UIStackView()
    stackView.axis = .Vertical
    stackView.distribution = .Fill
    stackView.spacing = 2
    stackView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(stackView)
    NSLayoutConstraint.activateConstraints(stackConstraints)


    let s1 = createHeaderStackView()
    stackView.insertArrangedSubview(s1, atIndex: 0)

    let lbl2 = makeLabel()
    lbl2.text = "Second One"
    stackView.insertArrangedSubview(lbl2, atIndex: 1)

    scrollView.setNeedsLayout()

makeLabelmakeButton 只是辅助函数

func makeButton() -> UIButton 
    let btn = UIButton(type: .Custom)
    btn.backgroundColor = UIColor.lightGrayColor()
    return btn


func makeLabel() -> UILabel 
    let lbl = UILabel()
    lbl.font = UIFont.systemFontOfSize(18)
    lbl.setContentCompressionResistancePriority(1000, forAxis: .Vertical)
    lbl.setContentHuggingPriority(10, forAxis: .Vertical)
    lbl.preferredMaxLayoutWidth = scrollView.frame.width
    lbl.numberOfLines = 0
    lbl.textColor = UIColor.blackColor()
    lbl.backgroundColor = UIColor.redColor()
    return lbl

createHeaderStackView方法是将我的 StackView 配置为放入包含我所有标题内容的 StackView。

func createHeaderStackView() -> UIStackView 
    let lblHeader = makeLabel()
    lblHeader.text = "UIStackView"
    lblHeader.textAlignment = .Center

    let lblInfo = makeLabel()
    lblInfo.text = "This is a long text, over several Lines. Because why not and am able to to so, unfortunaltey Stackview thinks I'm not allowed."
    lblInfo.textAlignment = .Natural
    lblInfo.layoutIfNeeded()

    let lblInfo2 = makeLabel()
    lblInfo2.text = "This is a seconds long text, over several Lines. Because why not and am able to to so, unfortunaltey Stackview thinks I'm not allowed."
    lblInfo2.textAlignment = .Natural
    lblInfo2.layoutIfNeeded()

    let btnPortal = makeButton()
    btnPortal.setTitle("My Button", forState: .Normal)
    btnPortal.addTarget(self, action: "gotoPushWebPortalAction", forControlEvents: .TouchUpInside)

    let headerStackView = UIStackView(arrangedSubviews: [lblHeader, btnPortal, lblInfo, lblInfo2])
    headerStackView.axis = .Vertical
    headerStackView.alignment = .Center
    headerStackView.distribution = .Fill
    headerStackView.spacing = 2
    headerStackView.setContentCompressionResistancePriority(1000, forAxis: .Vertical)
    headerStackView.setContentHuggingPriority(10, forAxis: .Vertical)
    headerStackView.setNeedsUpdateConstraints()
    headerStackView.setNeedsLayout()
    //headerStackView.layoutMarginsRelativeArrangement = true
    return headerStackView

长话短说:调整我的堆栈视图需要什么,所以每个堆栈视图和标签都以完整的大小显示?我试图压缩并拥抱所有东西,但似乎没有用。谷歌搜索uistackview uilabel multiline truncated 似乎也是一个死胡同

感谢您的帮助, 问候弗洛里

【问题讨论】:

如***.com/questions/34386528/… 所示,关键是为您的堆栈视图设置一个固定宽度,以便让您的多行标签可以运行并成为多行。 @SpaceDog 恕我直言,它们的计划并不差,但它们的逻辑与其他控件不同,因此对于更复杂的布局需要不同的思维方式,尤其是因为它们的填充规则 【参考方案1】:

您必须指定堆栈视图的尺寸。如果堆栈视图的尺寸不明确,则标签不会“溢出”到下一行。

这段代码并不是你想要的输出,但你会明白的:

override func viewDidLoad() 
    super.viewDidLoad()
    let stackView = UIStackView()
    stackView.axis = .Vertical
    stackView.distribution = .Fill
    stackView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(stackView)
    let views = ["stackView" : stackView]
    let h = NSLayoutConstraint.constraintsWithVisualFormat("H:|-50-[stackView]-50-|", options: [], metrics: nil, views: views)
    let w = NSLayoutConstraint.constraintsWithVisualFormat("V:|-100-[stackView]-50-|", options: [], metrics: nil, views: views)
    view.addConstraints(h)
    view.addConstraints(w)
    let lbl = UILabel()
    lbl.preferredMaxLayoutWidth = stackView.frame.width
    lbl.numberOfLines = 0
    lbl.text = "asddf  jk;v ijdor vlb otid jkd;io dfbi djior dijt ioure f i;or dfuu;nfg ior mf;drt asddf  jk;v ijdor vlb otid jkd;io dfbi djior dijt ioure f infg ior mf;drt asddf  jk;v ijdor vlb otid jkd;io dfbi djior dijt ioure f i;or dfuu;nfg ior mf;drt "
    dispatch_async(dispatch_get_main_queue(), 
        stackView.insertArrangedSubview(lbl, atIndex: 0)
    )

【讨论】:

【参考方案2】:

据我所知,如果您在 UITableViewCell 中使用它,那么每次旋转都必须重新加载 tableView。 您可以使用 stackView.distribution = .fillProportionally 它会正常工作。

【讨论】:

【参考方案3】:

你应该在故事板上试试这个。 使 stackview 高度等于视图的 60% 或 70%。

将乘数设为 0.6 或 0.7。

【讨论】:

以上是关于UIStackView 和截断的多行 UILabel的主要内容,如果未能解决你的问题,请参考以下文章

UIStackView 和多行标签?

UITableViewCell 中的 UIStackView 与多行 UILabel

UITableViewCell 中带有多行标签的 UIStackView 高度不正确

UIStackView 中的多行 UILabel 问题

UIStackView 中的多行标签

如果需要,多行 UIStackView / 换行 Xamarin.iOS