I'm adding labels to a stackview and I'm having trouble getting them to add to the top of the stackview rather than the middle.
I'm trying to accomplish this with the following code:
let textLabel = UILabel()
textLabel.textColor = .white
textLabel.widthAnchor.constraint(equalToConstant: self.stkCombatStackView.frame.width).isActive = true
textLabel.text = "This is a test"
textLabel.textAlignment = .left
stackview.addArrangedSubview(textLabel)
I want the labels to be added from top to bottom, how can I do this? without the weird spacing?
I have the spacing in the inspector set to 1
(I also have the stackview nested in a scrollview in the storyboard but i can't seem to scroll the stackview at all)
I'm adding labels to a stackview and I'm having trouble getting them to add to the top of the stackview rather than the middle.
You should probably call insertArrangedSubview(_: at:) instead of addArrangedSubview(). The insert... method lets you specify the index at which to insert the new view.
I want the labels to be added from top to bottom, how can I do this? without the weird spacing?
Are you sure you're using the right tool for the job? A stack view is good for containing a heterogeneous list of views in a fixed space, and it moves and/or resizes the views in the list to fill the view evenly. Take a look at the Distribution values: you can either fill up the stack view by resizing the contents in a couple different ways, or you can spread the contents evenly across the height (or width) of the stack view. There's no option for just listing the contained views and leaving extra space at the bottom, which seems to be what you want.
Some options you could consider:
use a UICollectionView: Collection views are incredibly flexible, letting you lay out a list of items in any conceivable geometry; the provided layout manager will surely work for your needs, but if you don't like it you can write a layout manager of your own or use someone else's. UICollectionView is a subclass of UIScrollView, so scrolling is easy.
use a UITableView: A table view gives you a vertical list of (usually, but not necessarily, similar) cells that can contain anything you want, and that top to bottom behavior that you're looking for is inherent in the way a table works. UITableView is also a UIScrollView subclass.
roll your own: It's not that hard to create a view that simply contains a list of other views and lays them out according to any algorithm you like; if a table or collection won't work for your needs (which seems unlikely), writing your own container will work better than trying to force UIStackView into submission.
Related
I'm taking the cs193p online course to learn ios development. Yet I'm confronted with a problem when I tried to add spacing constraint between two stack views. (The one with blue buttons(view1) and the one with labels(view2) )
I want the view1 to expand while keeping view2 unmodified. But it turned out that view2 always expand, even if I set the content hugging priority of view 2 higher than that of view1. How could I solve this problem?
Unless you've given your labels an explicit width, their width will be set by their intrinsic content size. The hugging priority for the labels is low, so the labels are free to grow to fill their container. So, the containing stack view will always be hugging its content since the labels can grow. You need to restrict the growth of the labels' widths in order for the hugging priority of the stack view to have any effect.
The solution is to either give your labels an explicit width constraint, or even easier to set their hugging priorities to be high as well. This will keep the labels from growing and will allow the stack view to hug the label's minimum size. Finally, Auto Layout will choose to expand view1 instead.
I am trying to get a layout working where I have 9 squares set 3 x 3 and on all device sizes, they are square.
I have tried endless ideas to make it work but can't seem to get it to stay squares on all devices.
I attached below, a picture showing the results and current constraints on the top left corner square.
Any help would be awesome!
The best approach would be use the stackView. The advantage will be you do not have to deal with the much constraints. So select the first rows three view horizontally then click on the Embed in Stack button whose axis should be horizontal inside your storyboard. Follow the same for second and third rows. Also inside stackview you can mention the spacing you want.
So now you have three stackView for all the three rows. After that select all three stackView then click on the Embed in Stack button and whose axis should be vertical and you can mention the spacing you want.
So advantage of doing that is you do not have to worry about the constraints. Finally you only have to apply the constraint on your main stackView which hold all your child stackView
While I totally agree that UIStackView is a great option, you can also add Aspect Ratio constraints (with a Multiplier of 1) to your squares and ensure that they remain squared (as nothing about your current layout demands that your views should be squares).
If you want your 9 squares to remain in the center of the superview, I recommend adding them to an invisible intermediate view and center that within the superview.
I've yet to find an answer for this anywhere and I'm not sure if it's possible, but I'm trying to right align a horizontal UIStackView, so that if subviews are hidden they move towards the right side not the left. Either programmatically (in Swift) or using the Interface Builder
UIStackViews align according to the user's text direction, i.e. left aligned for English and other Roman script languages, or right aligned for languages such as Hebrew.
In my opinion, changing this for layout reasons may be a misuse of the text direction APIs, and a bit of a hack, but with that in mind:
You can change the direction for a particular view in interface builder, using the Semantic drop down, which has options for 'Force Left-to-Right' and 'Force Right-to-Left', which will change the direction they pop to but also the order they are shown in. So you will have to reverse the order of the elements in your stack view
Or you can do it in code, using the view's semanticContentAttribute
stackView.semanticContentAttribute = .forceRightToLeft
What worked best for me was putting my horizontal stackview inside a vertical stackview and set the vertical one's alignment to leading
Unlike the other answers, the solution is actually fairly simple. What you need is to add a trailing constraint that pins the stack view to the trailing edge of its superview and then also add a leading constraint that pins it to the leading edge of the superview.
The trick, however, is changing the leading stackview constraint relation from equal to greater than or equal.
That will allow the leading edge of the stack view to snap over to the intrinsic width of the contents of the stackview, effectively pinning everything to the trailing edge.
Vertical stack views are similar. Pin the top with equals, and pin the bottom with less than or equal.
So:
stackView.leadingAnchor.constraint(greaterThanOrEqualTo: parent.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true
stackView.distribution = .equalSpacing
I had a horizontally oriented UIStackView containing two UIViews; hiding one of the views led to the other spreading full-width. Adding a width constraint to the remaining view resulted in keeping the desired width, but it shifted to the right.
TL;DR
Add a hidden UIView to the stack view which shows when the other is hidden for spacing.
I would like the Subtitle-style cells in my iOS 8 table view to resize automatically in height to allow subtitle content of any number of lines. And, I would like to accomplish this without using custom cells, if possible. That is, I would like to use the "canned" prototype cells that are available when dragging a new TableViewController to the story board.
I have found that this is easy to do with Basic-style cells: that is, prototype cells with Style set to "Basic" so that there is just one label in the cell -- "Title", by default. This is the label that is accessible by cell.textLabel!.text in code. If I set that textLabel's number of lines to 0, and add the two lines below to viewDidLoad(), then the cell heights resize automatically:
tableView.estimatedRowHeight = 144.0
tableView.rowHeight = UITableViewAutomaticDimension
All without having to define a custom cell or muck around with auto-layout or constraints. (In fact, I find it's not possible to add constraints to a canned prototype cell.)
But if I change the cell Style to "Subtitle," so that there are two labels in the cell -- textLabel and detailTextLabel in code -- then the cells do not automatically resize in height, even after setting both (or either) line numbers to 0 and playing around with different estimatedRowHeight values.
Am I missing something, or is it not possible to automatically resize cell height without a custom cell?
Thank you!
or is it not possible to automatically resize cell height without a custom cell?
Yes, it is not possible. And the reason is the reason that you gave. The automatic-resizing-cell-height feature depends upon internal constraints. But, as you have rightly said:
it's not possible to add constraints to a canned prototype cell.
However, note that you can accomplish what you want without supplying a cell subclass (though personally I like supplying one). You can just design your cell, constraints and all, right there in the prototype cell — the Custom prototype cell.
I have this interface with multiple UILabels.
On view loading i populate white labelled values with some data from a db.
The problem is, some of that fields are potentially too long for the interface, so i'd like to compute the total height of one label once the text is word wrapped and reposition the 2 labels below (shifting the Y coordinate) accordingly to the previous label's height.
All of this should go inside a UIScrollView to let the user scroll those labels vertically.
Any chance i can do this easily with some control i still don't know, or do i have to do it manually?
Thanks
You'll need to use the NSString UIKit Additions to compute the height you need to set on your UILabel, and then adjust the other controls appropriately.
Specifically, I think you want to use sizeWithFont:forWidth:lineBreakMode: to get the rect for your UILabel.
Alternatively, you could use a UIWebView and display the information as HTML. I don't know if it's necessarily less work, but you'll get a layout that automatically adjusts to the size of its contents.