I want to add several multiline Labels to an UIStackView
.
But I always end up my Labels being truncated. As seen in this Screenshot
But I like to have it more as shown here (my faked Screenshot)
Here is my Code. First I create the parent/master StackView, put it into an ScrollView (which is tucked to the screen)
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()
while makeLabel
and makeButton
are just helper functions
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
}
The createHeaderStackView
method is to configure my StackView to put inside a StackView with all my header stuff.
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
}
so to make a long story short: What is needed to adjust my stackviews, so each stackview and therefore label is shown in full glorious size? I tried to compress and hug everything, but it didn't seem to work. And googling uistackview uilabel multiline truncated seems to be a dead end, too
I appreciate any help, regards Flori
You have to specify the dimensions of the stack view. The label will not "overflow" into the next line if the dimensions of the stack view is ambiguous.
This code is not exactly the output you'd want, but you'll get the idea:
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)
})
}
As per I know If you are using this inside UITableViewCell then each rotation you have to reload tableView. You can use stackView.distribution = .fillProportionally it will work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With