Autoarrange subviews in a zoomed UIView - ios

I'm trying to zoom in and out an UIView, and rearrange it content to look similar for both states: zoomed and normal.
This picture shows the default state (the view that I'm going to zoom has orange color and has 5 UIImageViews) :
When I press "Zoom in" button I change orange view frame:
_page.frame = self.view.bounds;
And I'm getting the following result:
But the goal that I want to achieve is something similar to this (same result if I would scale the view):
It means that I must change frames for each subview, but it could be complicated when view would have many objects on it.
What I'm asking for are some hints or methods how can I get desired result without accessing subviews.

There are be hacks to do this, but the proper way would be to use auto layout. You don't have to access any subviews and will be able to do it in the storyboard/IB.
If you use auto layout, you can actually create constraints which will pin the following attributes of the subviews:
Pin the top subview's top space and leading space to the container
Pin the all but the last subviews' vertical distance to its nearest neighbour and leading space to container
Pin the last subview's top vertical space to its nearest neighbour and bottom space to container and leading space to container
Set constraints for height and width but set the priority to low

In addition to setting the frame (which just changes the size of the view) you want to change the transform (scale the view) Try something like:
_page.transform = CGAffineTransformMakeScale(2.0, 2.0)
You'll probably want to calculate the scale factor based on the old view size and the new size.

Related

Fix objects inside subview into place

How can I fix objects inside a view to a position? What I mean is: I have a subview which includes multiple elements for example an image and a textfield. Those subviews mustn't change their aspect ratio. I know I can set that via auto-layout. But how can I set that all the elements in the subview stick relative to their position inside of that subview? So that if I resize the subview (while remaining in their aspect ratio) the content of it will look the same just up- or downscaled?
Thank you!
UPDATE: This is how it looks like. The white area in the middle is the 'subview', and the textfield together with the labels the 'content':
Now if the screen size of the device changes it looks like that:
I have a constraint saying that the 'subview' should keep its aspect ratio. And I just want the 'content' to resize accordingly.
If I try to auto-layout the textfields and labels to 'subview' I get many weird errors. Isn't there any easier method? I mean it's just resizing and not some complex UI changes.
I haven't tried but, if you are scaling your view then inner views are will scale in ratio of the outer view.
But if your plan is to stretch outer view from the corners may be this layout setting can be help full.
Inside the storyboard you have an option to give something the same height or width as the parentView if you ctrl + pull to it.
Then it will say x equal to parent y = 1 whewre 1 is 100% of size, size it down to for example 95% and the align the views in the center, left or right or wherever you would like.

Need help to set autolayout

Am new to iOS & am facing it very difficult to set autolayout. Watched many videos to learn, but all of them giving solution to a specific problem. No video covers all base rules to set an UI object into it's place & with proper flow.
I came from Corona Background & used to set UI programatically very well. Am thinking here same way, but I think apple made it so difficult or people are not able to explain me properly.
Please see 2 images attached in this question & tell me rules to apply to achieve this UI. I request you people to please explain in the general manner so that my other screen can be completed using same rules.
Image 1: http://i.stack.imgur.com/MPE47.png
Image 2: http://i.stack.imgur.com/qEiCm.jpg
A really helpful guideline is
Every element should be able to figure out its position (x and y) and size (width and height).
Ensure that every element only has one way to figure out its position and size.
Remember that the autolayout of all the elements can influence each other.
The most used layout constraints are:
Top The space between the top of the view to another view.
Trailing The space between the right edge of the view to another view.
Leading The space between the left edge of the view to another
Bottom The space between the bottom edge of the view and another view
Width Assign a fix width to a view (Note that it can also be a percentage - aspect ratio)
Height Assign a fix width to a view (Can also be a percentage)
Center Horizontally Always align the view relative to the horizontal center of another view
Center Vertically Always align the view relative the the vertical center of another view
For example in your second image, say the yellow bar is a UIView called titleView.
Set the position of titleView by setting the top layout constraint to the container view. y position is set.
Set the leading constraint to the container view. x position is set.
Set the trailing constraint to the container view. The view's width will now stretch with the screen size. Thus width can now be determined.
Set height to 50. Height is set.
Now... If you also set the width of this view, it will cause the layoutConstraints to break, because you have redefined the width constraint. Some of the constraints will then be ignored.
Another example of how layoutConstraints might influence each other. Lets look at determining the y positions of the second image.
Say titleView has a top constraint to the container + height of 50.
currentCampaignView has a top constraint to the bottom of titleView. (Use vertical spacing) + equal height to titleView. (y + height can be calculated)
the 5 buttons have equal heights. Top buttons have Top space to Bottom of currentCampaignView. Centre buttons have Top space to bottom of top buttons. Bottom button have Top space to bottom of centre buttons.
startCampaignView has equal height to currentCampaignView. Top constraint to bottom of bottom button and Bottom constraint to container view.
Note that because views and buttons have equal heights, all are considered when determining the height. Thus it is very important that they are all interlinked and that the entire height that can be used is specified. In this case it is specified by the first element titleView that has a Top Constraint to the Container view (of which the height should be known) and the last element, startCampaignView, that has a Bottom constraint to the Container view. Because all the views in between are linked on y position and height, the view can work out what each view's height and y position should be.
One more example. (Your first image)
topLeftButton Set the top constraint to Superview. (y), Set the leading constraint to Superview (x), Set height = 100 (height), Set equal width to topRightButton (Note that we do not quite have the width yet, because the width of topRightButton can not be determined)
topRightButton Set the top constraint to Superview. (y), leading constraint to topLeftButton (will be used for x), Set trailing constraint to superview. Now the width of both buttons can be determined, because we have an external startX + endX and we know the two buttons touches each other and are equal widths. Thus the available space will be split to get the width of the two buttons.

AutoLayout Equal Heights hides Subviews

I have a UIView buttonView and gave it an equal heights constraint to the super UIView with a 0.4 multiplier. The frame is adjusted correctly but the subviews of buttonView are not visible. However, when I click on the position where the buttons are supposed to be then the actions triggers.
This does not happen when I change the buttonViews constraint to be a fixed height.
I can get more into details if you want but has anyone run into something similar?
EDIT
There should be two buttons where the white space underneath the label is. When I click on the white space the timer runs but the button is not visible.
I took a look at the project and the issue I saw in a couple places was that auto layout and manual frame transformations are both used, which can be tricky. A couple specific things I saw that you will probably need to modify in order for the view to adapt and render correctly at different sizes / orientations:
1) The CustomAudioLearn view loads a view from a xib and adds it as a subview. However, it does not set constraints on this subview to make sure that the subview always hugs the edges of the parent view. So changing the size of the CustomAudioLearn view through auto layout in the storyboard results in the the xib-based subview always staying the same size. You should either add constraints to the subview or override layoutSubviews() in CustomAudioLearn and include self.customView.frame = self.bounds and self.customViw.layoutIfNeeded() in there. Also, I would suggest removing the line self.customView.translatesAutoresizingMaskIntoConstraints = false
2) Similarly, the RecordButtonView sets its corner radius on awakeFromNib(), but after layout happens, that's no longer the right radius. So you should again consider overriding layoutSubviews() or similar location to adjust the radius every time the layout is updated.
3) Lastly, the superview of the RecordButtonView in the storyboard is set to a height constraint of 70 with a priority of 1000. If you want the RecordButtonView to expand for the space available, you should reduce the priority of that height constraint so that the proportional width of the RecrodButtonView and the 1:1 aspect ratio take priority in determining the height of the superview. Otherwise, it will always be 70 points, or there will be conflicting constraints.
The problem was that I set the rounded corners to half of my frame's width. The radius got so big that it completely hide the view. I changed it so that after the bounds are set I change the corner radius. Sorry for confusion but thanks for any help!

How to correctly use constraints when both UITableView and UIImageView are presented on the same view controller

Suppose that I have the following view controller and this is how I want to see it on all iPhone:
If I run it on iPhone 6 it has the following look:
Here you can notice that UITableView not fit the whole screen and UIImageView doesn't placed at the bottom of the screen.
How can I achieve the required behavior via constraints in XCode 6? I thought that I need the following constraints:
Leading space and top space to container margin for UITableView
Bottom space and trailing space to container margin for UIImageView
Vertical Spacing between UITableView and UIImageView
But it doesn't work as expected even after auto-resolve constraints issues:
Thanks in advance.
Ok, a few things here:
Each view needs enough constraints to define it's x and y position, and it's width and height unambiguously. To start with, go back to Interface builder and delete all of your constraints and lay out the view as you would like it to look. You want to have control over every constraint added, don't let IB automatically resolve the issues, as in all likely hood it won't do what you want.
Do you have an image that is the size you want it to be on screen, once you've factored in #2x, #3x etc? If so, then your job will be easier, as the width and height of the image view can be defined by the width and height of the image (ie the image view's intrinsic content size).
In order to use Autolayout effectively, you need to think about your view holistically, and think about how you want your views to behave when the screen size changes, be clear in your head about the behaviour.
To achieve the layout you want, I would do the following:
Constrain the tableview's leading, top and trailing edges to the superview, with a constant value of 0. This means it can get wider and thinner with the device, it will stretch horizontally, but always stick to the top. This has defined the tableview's x and y position, as well as it's width (height still to go, but keep reading...)
Constrain the image view to match the horizontal centre of it's superview (x position defined) and constrain it's bottom edge to the superviews bottom edge (y position defined). If've you've got the right sized asset, then that will take care of the width and height too. If not, you could go ahead give it explicit width and height constraints.
Now we can constrain the tableview's bottom edge to the top of the image view, with a constant of 0 (ie touching). Note we haven't give the table view an explicit height constraint, so as the device screen grows vertically, the table view will stretch vertically.
Autolayout is hard at first. I'd recommended lots of reading to get over the initial hump, really get to know what a constraint is doing, it's limitations, and the way in which the system parses constraints to translate them into frames. This book is really good, and really helped me learn:
http://www.amazon.co.uk/Auto-Layout-Demystified-Mobile-Programming/dp/0321967194
Best of luck
First make sure you have selected the correct size class. The 'Compact Width | Regular Height' size class must be selected in the Interface Builder. Now add the Trailing space,Leading Space, Top space and Bottom space constraints to the table view. For the image view set the view mode to Aspect fit and add the constraints : Align Center Y ,Top space,Bottom space, Leading space, Trailing space and Aspect Ratio .

iOS: Frame and picture autolayout

Say I have two UIViews. One is a UIImageView of a frame, and one is a UIImageView of a picture. I want the picture to stay inside the frame regardless of screen size using autolayout. The picture is NOT a subview of the frame - they're just two imageviews that I want to remain superimposed in the right proportions.
I can't pin the heights, because I want them to change when rotating (for arguments sake say I pinned the frames bottom to the bottom of the main view). I can't make the heights equal, because they're not, the picture should be smaller. I can pin the horizontal spacing, but that will just make sure the picture's x,y are right, but not height and width.
I want it so that if for whatever reason I change the frames size (via transform, for example), the picture will follow.
Can I do this in autolayout, or is coding required?
You can make constraints pinning the centerX and centerY of the two views to be the same. Then you can make constraints to specify the width and the height. It depends on how big your frame is. You might try
picture.width = frame.width - 20
or
picture.width = 0.8 * frame.width
(and do something similar for the height).
If you want them both to rotate, you need to either set the rotation transform on both views (not recommended) or put them both in the same superview and set the rotation transform on that superview (recommended). Remember, if a view has a transform set then you can't make a constraint that goes from within that view to something outside that view. They are like separate worlds.

Resources