I have a few UIStackView
that I add programmatically and I want them to have a other Axis
when the app is in say Regular Width and Any Height
.
It this even possible, like it is in the interface builder?
All I bump into on Google is willTransitionToTraitCollection
, but not what I need.
To make it easier to understand what I need:
for i in numberOfItems {
let stackView = UIStackView()
stackView.append... // add views in this new stack view
// here is where I need help:
stackView.axis = horizontal
stackView.addSomething... stackView.axis = vertical if regular width and any height.
existingStackView.append.... stackView
}
Edit:
I found a other way to do, but I get some strange behaviour on iPhone 6+ when I rotate it around. Git repo: https://github.com/bjaskj/iOSStackViewConstraints
class MyStackView: UIStackView {
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Regular {
axis = UILayoutConstraintAxis.Horizontal
} else {
axis = UILayoutConstraintAxis.Vertical
}
}
}
ViewController:
@IBOutlet weak var mainStackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
addElement("Name", description: "Saint Petersburg")
addElement("Native name", description: "Санкт-Петербург")
addElement("Country", description: "Russia")
addElement("Federal district", description: "Northwestern")
addElement("Economic region", description: "Northwestern")
addElement("Established", description: "May 27, 1703")
}
func addElement(title:String, description:String) {
let labelTitle = UILabel()
labelTitle.backgroundColor = UIColor.redColor()
labelTitle.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
labelTitle.text = title
labelTitle.textColor = UIColor.whiteColor()
let labelDescription = UILabel()
labelDescription.backgroundColor = UIColor.blueColor()
labelDescription.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
labelDescription.text = description
labelDescription.textColor = UIColor.whiteColor()
let stackHolder = MyStackView()
stackHolder.axis = .Vertical
stackHolder.distribution = .FillEqually
stackHolder.addArrangedSubview(labelTitle)
stackHolder.addArrangedSubview(labelDescription)
stackHolder.spacing = 8
mainStackView.addArrangedSubview(stackHolder)
}
What happens when I rotate iPhone 6+
is this:
But what I expect and get if I start the app in rotated position:
Each of the elements has it's own intrinsicContentSize so it should be possible for the UIStackView to provide its own intrinsicContentSize . The documentation states that the spacing is used as a minimum spacing. The intrinsicContentSize.
Overview. Stack views let you leverage the power of Auto Layout, creating user interfaces that can dynamically adapt to the device's orientation, screen size, and any changes in the available space. The stack view manages the layout of all the views in its arrangedSubviews property.
Update:
Ok, so it seems like you have two questions:
1) How do I add the appropriate stackview.axis depending on the size class when I add my stackviews to the scene:
for i in numberOFItems {
let stackView = UIStackView()
if view.traitCollection.verticalSizeClass == .Unspecified && view.traitCollection.horizontalSizeClass == .Regular {
stackView.axis = .Vertical
} else {
stackView.axis = .Horizonal
}
stackView.addArrangedSubview(arrayOfViews[i])
}
2) How to make that stackview change from horizontal to vertical axis when the phone orientation is changed:
You'll nee to have a an array of stackviews that you've initialized. Then you'll need to step through the stackviews in the delegate method and change their orientation.
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
var axis
if view.traitCollection.verticalSizeClass == .Compact {
axis = UILayoutConstraintAxis.Horizontal
} else {
axis = UILayoutConstraintAxis.Vertical
}
for stackView in stackViewArray {
stackView.axis = axis
}
}
The view has a traitCollection that includes verticalSizeClass and horizontalSizeClass. These can have the values of .Compact, .Regular, and .Unspecified.
The method traitCollectionDidChange should tell you whenever a size class is modified (i.e. when the phone is turned).
If this still does not answer your question, please try rewriting your question so it's easier to understand
Also, there is no way that I am aware of to set these properties once and be done with it, you have to take care of both cases.
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