iOS: how to adjust positions of UI elements one by one properly by IB when some of them may change size? - iphone

For example, on a UIView, from left to right there are three buttons:,button1,button2,button3.
When button 1 become wider, such as its width become twice as its original width, is there any interface builder way that can make button2&3 move right automatically?
sorry for I didn't make my question clear.
I mean such kind of size change: I push button1, then I change it's frame in my code, not caused by the change of text in butotn1. I want button2&3 to move right automatically, keeping the width of the gap between button 1 and 2 unchanged.
Thanks everyone.

IB can be used only for initional positioning of views.
True, you can also define autoresizing masks of the views but that's about it.
Any additional laying out should be done in code.

I could be wrong, but I don't know of any way you can do this in IB. It's pretty straight forward in code though, just link the buttons to some IBOutlets and check the sizes of the images of the buttons (myUIImage.size), then adjust the frames of the buttons (do it in viewWillAppear).
Seen your edit - if you're adjusting its size using code, adjust its position too.

If your buttons are in a row at the bottom of the screen, consider using a UIToolBar. Its UIBarButtonItem objects automatically adjust to fit each other's width changes. For more generic cases, you'll need to recalculate positions and sizes as in Franklyn Weber's answer.

Yes - by using autoresizing masks. If you allow the margins to be flexible (no red lines connecting the frame to the superview's frame) and allow flexible width and height, the buttons will size and move proportionally.

Related

What anchors to use for UITextView?

If I set the leading/trailing, top/bottom anchors, my UITextView appears; if I set leading/trailing, top anchor + height, then it appears too. But if I leave one anchor out, my UITextView doesn't appear at all. Why is this? I'd assume it would spill out? For example, if I didn't specify a bottom anchor, I'd assume it would overflow to the bottom. But I don't think it appears at all - what exactly is happening here?
It's very simple. You must specify, for every view, all four aspects:
horizontal position
vertical position
horizontal size
vertical size
That's all there is to it. If you omit one of those, then your specifications are incomplete ("ambiguous") and the view is, if you're lucky, not drawn.
Some view types, such as a UILabel or a UIButton or a UIImageView, supply one or both of the size aspects internally based on their contents. So for those view types you might be able to omit specifying that aspect yourself. But a UITextView is not one of those; it's all entirely up to you.

How to create stack views with constraints to the parent view's margins in Interface Builder?

I want to have a horizontal stack view, or other view, constrain to the width of the view's margins.
I first add my interface elements.
(Image 1)
When I put them in a stack, they resize to (what I understand) are their intrinsic content sizes? Okay.
(Image 2)
At this point, the items turn red if selected. When I click the "update frames" button in the Interface Builder they get bigger and bigger. Until they extend right off the screen. What is going on? Why would updating frames make them grow beyond the confines of the screen?
(Image 3)
Okay... maybe I can ctrl-drag between the stack and the view now and pick constraints based on the view's margins, right? Maybe that will fix it...
let's constrain our stack so it will resize the way I want.
Weird thing is, it doesn't matter if I click and drag from the view to the stack or from the stack to the view... either way I end up with constraints that seem to describe the REVERSE of what I want.
Not what I meant!
I want to use the View's margins to define the Stack View's width, not the other way around! Also, they added 67.5 for some reason.
Thankfully there's a place to reverse these and remove the 67.5, right? I click on the constraint and make the changes...
(Image 6)
And now I'm in pretty good shape. I think. I mean it looks terrible, but at least they're in a stack... how do I set a minimum value for the label?
(Image 7)
Thanks for any commentary. Humor and poking fun at a newbie is welcome. Images reduced to 2 because I don't have reputation.

How do I position a label and a button on an image so that even if the image is scaled they are at the same place on the image?

I have an almost complete app. I want to use auto layout but even though I have searched a lot about this subject I could not find an answer that I could use. I can get it to show correctly on one screen size but not on another... Here is my question
How do I put the necessary constraints so that even if the counter is scaled for the different sized devices,the label and the button are at the same place on the image? (the image is a png image)
I would really be glad if you can answer or direct me to an answer that shows how to do a similar thing.
This is what I want
And this is what happens if I try doing it with auto layout and on a different screen size.
This is not the same image that I am using in my app but it will give you an idea.)
Thanks again
Edit:
Thanks for the answers but as pointed out in the comments, 1st answer does not provide a way to scale the image for different screen sizes.
Second answer provides a way but I could not understand the 2nd part of the answer.I need a little bit more detail. I would be glad if there is anyone out there who can help me on this issue.
I am still struggling with this issue. If I follow the 2nd answer Xcode says I need X position,width for the first filler view and Y position,height for the 2nd filler view.I am stuck at this point. I am not sure what value to give to these views.
You have to add constraints with respect to the image view. I have created a small project with your image. This should help you get started.
https://1drv.ms/u/s!Aq8sK_MQLIL9gxMl-lBOMHkToudU
Because the image size will change on different screen sizes, you can't set constant constraints. What you need is proportional constraints.
Set your UILabel and UIButton to have the width and height proportional to the UIImageView width and height respectively.
To do that: Click on your UILabel
and Ctrl Drag it over the UIImageView, selecting Equal Widths and Equal Heights.
Let's say your UILabel has a width of 100px and your UIImageView has a width of 500px. Edit the constraints that you have just set, and set the multiplier to be 100:500
This will make sure that any modifications on the UIImageView width, will affect the UILabel width accordingly. Do the same for height constraint.
Repeat same steps for UIButton.
The top/bottom/trailing/leading constraint cannot be set proportional to the UIImageView size unfortunately, but you can have filler views - transparent views that can mimic the layout constraints.
You will need two filler views: one for top constraint:
(set its height to be proportional to the UIImageView height)
and one for leading constraint
(set its width to be proportional to the UIImageView width)
I can make a small video for you if this is not clear enough.

Unable to add oversized button in UIToolbar

I have a UIToolbar in IB with a custom UIBarButtonItem that is set to an image. The image height is larger than the UIToolbar height. The image does not load for some reason. Attached is a screenshot.
You should avoid using subviews that are larger than the parent view - even if it does work and draws the view outside of the bounds, you cannot always count on it because the clipping is skipped for performance reasons and depending on the drawing order the overlapping part of the subview might be covered later. Second problem is that only the part within the frame of the superview is able to handle the touch events.
As to why you don't see your image, it's probably a different problem, I doubt it has something to do with it going outside the frame. Post your code to get more feedback ;)

issue with rotation and uilabels with size set using NSString's sizeWithFont

I have a few UILabels in my view with their height set using sizeWithFont:.
I set the autoreszingMask to flexible width and height, however on rotate the width changes (am assuming because self.view's width changes and its set with a width relative to self.view) but the height of it doesn't change to fit the content again. This results in a large white space at the top and bottom.
Just wondering how I would go about re-sizing the UILabel on rotation? Is there any automatic way of doing this, or is there a way of getting all UILabels and re-doing sizeWithFont when the device is rotated?
The UILabels are subviews of UIView heirarchies used as headers for sections in my UITableView.
Thanks
Tom
You should really send sizeToFit to any UIView, especially UILabel, instead of forcing some arbitrary size on them.
The best approach is usually to first set the maximum width and current height, then send sizeToFit, then adjust the width again if necessary. In case of multiline labels it looks like the most foolproof way to avoid layout bugs.
The problem was having a flexible left and right margin on a slightly offset uilabel.
If the label isn't centered then you need to choose left or right and set the flexible margin for one of those.