Why are items in stack view taking too much space in Swift - ios

I made a profile area where it has some buttons and information about the person like followers and their posts:
But I was advised to make using multiple horizontal/vertical stackviews as it (a) is easier to manage for different sized screens and (b) is easier to constrain as a whole in the view. I made the exact copy and all the items (like the textViews or images) are taking up so much more space than they need to which makes the whole thing so much bigger, then when I try and space stuff out or in, everything just either goes on top of one another or it gets bigger. Could someone explain this behaviour? Here's the same thing just using the stackviews:
As you can see in the picture, the '#username' textview is taking up so much space bother horizontally and vertically and I cannot even change that in the inspector as it just defaults back. The stack view hasn't got any constraints on it at all at the moment so no constraints are acting on it either.

Related

Stack button fail

Swift 2.2 Xcode 7.3.1. iOS 9. Storyboard. I have 7 rows of four labels across. I was intending to select each row to place it in a stack. Saw this technique in Hagerty's iTunes U (Stanford). Each time I select a row and press the button to add the four across to a stack, it makes these huge rectangles... They have a width of 127,000,000. I keep trying different things, adding all suggested constraints, getting rid of all contstraints, etc.
Any idea what I am doing wrong? TIA
Sorry, I'm apparently not allowed to add images as yet here... The rectangles on the View Controller are all UILabels. When I select a row of them and press the Stack button, next to pin, etc., it appears to make one wide rectangle, all 4 on top of each other, this last time is was 27,216,026 pixels across. I think the comment about not using "suggested" constraints is probably a clue... there certainly seem to be more than necessary. There are also some where I tried to delete a constraint where the constraint item appears to be dimmed. There are one or two where the dimmed one, and an exact copy of the dimmed are both there...
There are no images on the view... the only button is up top, a "Back" button.
Someone gave me the clue. It turns out that there are some bugs in the constraints setup, especially when using "suggested" constraints. I deleted all the constraints, then added just the minimum needed, made sure they were all perfect, and I got one row to work properly. Now I can do the others.
After I do this enough times I am sure it will make sense, there is probably one constraint mechanism that doesn't work as it should - an Xcode bug. One adds size constraints both in the size inspector, and potentially the constraint mechanism, and sometimes they do not match. Those things have to be fuddled with until they do... and then Stacking works...

Change constrains depending on screen size

I tried to solve this at my own, but I just really can not understand auto layout. I also searched here for a solution, but I could not find anyone with this similar problem (although I see a lot of people struggling with auto-layout). I want to make an app in landscape mode what is supported by every iPhone 5 and higher. I set up some constrains, with this as result:
How it should be
Above is the correct image on how it should be on every device. Can I set it relative to a screen size? I tried changing values with the multiplier, but that did not worked out well.
How it is on bigger screens
Here you can see how it is now. Because the values are absolute and not relative, I think it not changes... By the way, I am using " compact height" for building my landscape apps for iPhone, is that correct? Or is this the cause of this big trouble?
Here's a quick run through that might be more applicable to your needs than the general tutorials...
Create your elements on the storyboard and lay them out in roughly the right place:
Select items 1-4 and hit the stack view button, then select items 5-8 and do the same, Xcode is very good at guessing what you want so you'll get two vertical stack views, like this:
Select them both, hit the stack view button again and you'll get a horizontal stack view that contains your two vertical stack views:
Then select this stack view and the header and press the stack view button one last time to put them in another vertical stack view:
How you just need to adda few constraints to the outer stack view and then tweak the settings of each stack view. In this case, I've pinned the outer stack view 20 from the view edges, set the outer stack view to fill proportionally and everything else to fill equally, plus I've set the vertical stack views to centre alignment. You can play with all of these settings to get a result that you find pleasing:
This will now scale perfectly for any size screen:
I've just used labels for speed, but the same rules apply for images or whatever.
Hope that helps, stick with the tutorials and keep practicing until you figure it out, it will save you lots of time in the long run.

Best approach to showing or hiding dynamic content in iOS

I've been doing iOS for a while now, but when it comes to dynamically hiding / showing elements, I'm a bit lost.
Coming from Android, I'm used to being able to simply set views to visibility gone, but this doesn't exist on iOS.
So let's say I have the following scenario:
Basically I want to have a table, but the table should not fill the entire view controller. Instead it should leave place for optionally either a button, a multiline label, or possibly both at the bottom (if visible, these should be fixed, not scroll).
One way to solve this would be to use auto layout and modify constraints, like adding a zero height constraint. But that would make iOS kill one of the other constraints, which would make it hard to change it again. For the label, I wouldn't always want to have a height constraint, because it could be multiline, and should take the size it needs.
Maybe it's easier to skip autolayout here and modify frames instead, I don't know.
My question is: What approach would be best here?
Is there some other way of doing this I haven't thought of, or do I have to try to do what I described above?
I'm not primarily looking for code (code can be ok), but I'm more interested in a description of how it can be done.
I'd like to support iOS 7.
This problem had a variety of solutions, and opinion based, but I'm facing such questions a lot, when I don't know what to choose and what would be the "right thing".
So, I my opinion, the best solution here is using autolayout, you need to set height of label manually, but you have a few methods for this, at least you can play with it and if you don't succeed ask question about it. Using frames, you'll face same problem of calculating height, right? But with auto layout, you only need to set height, vertical space to 0, when you need to hide message.
You can also use constrains with priority lower 1000, and remove completely constraints from message (button, label) if you don't need it at all anymore.
For example, taking your layout image, you can make UIView with subviews: button, label. Top constraint connect to the UITableView, other constraints to the sides.Label and button will calculate the view's height. The only question here is label height.
So in ios assuming that the background of both these objects is opaque only the front most view in the Heirarchy will be visible and interactable, An easy solution would be to change the different frames of these two things you need and make sure they are in the back of your view heirachy, and when you need them to appear use view.bringSubviewToFront(mySubview) and view.pushSubviewToBack(mySubview) to make it disappear again. View obviously would be referring to main view of your view controller.

Embedding lots of views into a uiscrollview and have constraints match up? Is this possible?

So, here's the basic idea. I have a view with tons of subviews, they all use AutoLayout. I need them all to scroll up to be seen, so I go to embed in uiscrollview and... everything is off. This app isn't using size classes, just one Any Any type.
I went to embed in a view instead and also, the constraints do not adjust for the new view, and its 20 extra width/height in pixels.
I'm betting this is like Scrolling Right on your air to view asset catalog imgs, it's simply impossible, but wanted to ask. If it is impossible, shouldn't this be a bug report. I'm used to embedding, then editing, and tearing down/rebuilding xibs, but with all the hype around it, I keep thinking this new feature should make it easier, not harder, so I think I'm missing something basically.
I did search and there's lots of questions from people who haven't embedded anything before, but I didn't see anything for 2 or so views already being in the new embed + NSLayoutConstraints now getting completely wiped, it's relatively complex so me, not knowing the design, has to go memorize all 40 or so relations and remake it, or maybe just trust the "set frames to new view", but that probably won't turn out right since I have to make the view 20 pixels smaller each side, to counterbalance embeds
Thanks for any help. Shortcuts, tools welcome.
I figured this out. I was like "Well, I'll just embed the main View Controller's view into a subview", but nope, that's not allowed.
So I copied and pasted the head view into itself, deleted the originals, then embedded that one-layer-deep into a UIScrollView and manually set the size back and origin back to 40 pixels less each side, and 0,0 for x, y.
I have to re-hook up all the outlets but this is much easier than anticipated.
As a side note, it's still impossible to view [right side of] asset catalog on an air (without toggling off all sidebars), but it's not impossible to quickly do keyboard add/edits.
To answer the question, yes its possible. Use autolayout with scrollviews you need to have a content view set inside the scroll view which has the same size and width of the scrollview. With constraints bounding its size left, right, top and bottom.
Then add the subviews to the content view. This will make the scrollview height much easier to manage.

Laying out subviews in a UITableViewCell dynamically

This is the most complicated UI related problem I've come across yet. I've been trying to find a solution for literally weeks but no avail. Let em explain.
In this app I'm working on, I need to display a certain list. It's actually a schedule. Here's how it should look like,
The fields circled by red circles don't change. To explain what change means I have to show you this.
Its a set of filters which the user can show/hide certain fields and the ones that are circled in the first image are static ones. They can't be toggled on and off.
Now the problem arises with the ones that can be toggled. Here's what it looks like if you turn off the Show Actions flag.
A new label with a blue background replaces the bottom one you can see in the first image.
Here's another one where you disable Show Time option and the time labels are gone (yes it affects only for some. Its expected).
If this filter list were an option list, it would have been easy. Just create a custom cell for each option and you're good to go. But unfortunately the user is able to toggle multiple filters! For example the user can turn off both Show Actions and Show Time and it'd look like the last image but the bottom label would have the blue label in the third image.
To top it all off, the cells' height is dynamic. In iOS 8 creating self resizing cells are easy enough from the IB when you could just add auto layout constraints and done.
But it seems to me that creating these cells from the IB isn't an available option to me. Simply because there are way too many filter combinations a user can make. So the cell's subviews need to adjust to it.
My question is how can I create a dynamic cell like that? My best guess is through code, right? I haven't written my UI in code before so I tried creating a test project to familiarize myself with it. But the problems I'm facing is setting fixed frame sizes makes the dynamic nature obsolete. And how can I move a view to fill up a removed view's space (Last image. Time labels are gone so the name and the id labels move to the left to fill that space).
I know this question is a little too broad. I'm not asking for a straight answer either. I'd really appreciate some pointers, or even a better suggestion on how to approach this because I'm truly at the rock bottom on this issue.
Thank you.
It's hard to give you any precise help since your question is so broad. First, I would recommend watching the 3 videos on Auto Layout from the WWDC 2012 (sessions 202, 228, and 232).
To answer your one example, how to move a view to replace a view that's removed. You would need to make two left edge constraints from the view with the text (Kund Alof...). One with a constant of 0 to the time label with a priority of 1000 (that's the default), and another to the left edge of the cell, also with a constant of 0, but with a lower priority, say 900. As long as the time label is present, the constraint to it will determine the position of the text label, but when it's removed, the lower priority constraint to the left edge will take over and move the label over to the left edge.

Resources