Autoscaling on iOS - ios

Hey my iOS app is very simple and instead of messing with the auto-layout feature of Xcode is there a way to just programmatically size the screen for each resolution. I am using the storyboard feature of Xcode, but I can't seem to figure this out. I googled it quite extensively, the only thing I found was Editor > Resolve Auto Layout Issues > Reset to...
That works well, except it always squishes my images. I try to set a forced height on them and then everything goes crazy!
So Is there any techniques that shrink everything in the view by 10% vertically?
Thanks, Krkto
-BTW screen is a UIView
-edit- also When I set the autolayout to "Reset to suggested contraints in..." and I call a animation that scrolls the view up, it scrolls the assets up slowly, while the background goes up in a normal fashion.

Here is how I would do it with AutoLayout.
Setup your view in IB / Storyboard
Setup the constraints
Since you want to scale subviews - set their height and width constraints.
So - Width constraint:
Do this by
ctrl + drag inside the UIView from left to right (Or visa versa)
When you stop dragging a pop up will show with two options: choose Width.
So the same for height - just ctrl + drag from within the UIView you want to scale, top to bottom or bottom to top and when the pop up shows, click height.
Now that your constraints are set - find them in the left panel that shows all your UIView objects for your IB / Storyboard. They will be in the same UIView you made them in.
Now, ctrl + drag them to your view controller - these will create NSLayoutConstraint `IBOutLets
Example:
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
Now - when you want to update the height constraint (and width) - in code, do something like this:
self. heightConstraint.constant = 10; // new Size
[self.view layoutSubviews]; //Causes setNeedsDisplay to be called on all subviews in UIView
That's all there is to it. You could put this code inside a UIView animation and it will animate nicely, too. Just use some simple math to calculate the size to whatever % you want.
If you look in IB / Storyboard - you will see where the constraints in the left side of Xcode are shown, it will give you there current constant value.
Example:
Hope this helps.

What your missing is constraints. raywenderlich on autolayout
This tutorial provides what I believe your looking for.

It looks like what #krtko really wanted was to turn off Auto-Layout, Size Classes and put the app into auto-scale mode. For simpler screens this is just an easier way to handle the four screen sizes than Auto Layout. The "struts and springs" (Autoresizing) function can still be used to define what happens as the screen real-estate grows or shrinks (particularly in the case of iPhone 4 / iPhone-on-iPad mode).
The key is to use the UILaunchImages key in info.plist and specify images for only 320x480 and 320x568. This throws app into a mode where the 6 and 6+ sizes are automatically displayed as an iPhone 5 scaled up. You lose the benefits of high resolution, but gain a lot of time not having to play with AutoLayout and deliver lots of image files in all the resolutions. Great for MVPs and quick prototypes.
https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW28
Note that in this environment, the Assistant Editor / Preview function does not work properly; it shows what the view would look like if rendered through the usual scaling mechanisms, not the automatic scaling that is used when compiled. The simulator will show the correct layout.

Related

Swift: Programmatically change size of a button in runtime

I use two buttons in a camera app to track the zoom of said camera. My goal is to reduce the height & width of 1x if 2x is selected and vice-versa but it doesn't seem to work.
I tried button.frame.size.height = 8 button.frame.size.width = 8 and the height & width always remain the same. I even tried 500 to see if it would make a difference and it didn't.
I also tried button.size(CGFloat) to no avail...
I should probably mention that those buttons are nested in a StackView and the app is built on Storyboards. Also, the app is designed to be used on iOS 13+.
Thanks in advance!
UIStackView is using Auto Layout for arranging its subviews. Therefore, direct modifications of the button's frame will have no effect because Auto Layout will anyway recalculate all frames according to the active constraints on the next layout pass.
Since you're using a storyboard, here's how to solve it:
Open the storyboard, select your button and create a width and a height constraint for it.
Create IBOutlets for each of these constraints in your view controller. For the sake of the example let's say you name it buttonWidthConstraint and buttonHeightConstraint.
Whenever you want to change the size of the button, do this:
buttonWidthConstraint.constant = 8
buttonHeightConstraint.constant = 8

What should I do to make generic size of all UI controls in iOS?

I was trying to practice Auto Layout in iOS, and I started with very simple UI. Please see image for understanding my problem.
All the text files are in middle of screen (I have deliberately kept on guide line), still you can see in preview, controls are not fully shown. I have not chosen specific size. Size is 'Inferred' still I am not able to see all the controls on UI.
I tried both adding and removing Auto Layout, but no luck. What should I do to create generic UI which will work with all the sizes of iPhone and iPad.
This image is without use of Auto Layout.
After enable autolayout and size classes you have to apply autolayout constraints.
Autolayout is a detail topic. Few basic things when applying autolayout is:
UI element need four constraints.
position x
Position y
height
width
So you will select first label (Number 1). Then press control and drag to superview. You will be provide options. Select Leading space (This will handle x position)
This is the way you can press control and drag:
http://www.appcoda.com/wp-content/uploads/2014/07/auto-layout-login-trailing.gif
Go to size inspector. You can see the constraint.
Press edit and change its value to 25(for test).
similarly control and drag again to superview and select Top space. (This will set y position for label)
This is simple way for the above taken from AppCoda
http://www.appcoda.com/wp-content/uploads/2014/07/auto-layout-control-drag.gif
You can change the value of these constraints according to your need.
UILabel and uitextfield get width and height from their content size. So don't need width and height constraints.
Now when you preview on any device this label will be stick on top left side of screen.
So this is a complete mechanism. You have to apply constraint to every ui element.
Below is a link to very comprehensive tutorial by
http://www.raywenderlich.com/115440/auto-layout-tutorial-in-ios-9-part-1-getting-started-2
At start this tutorial tried to create three views using autolayout. At the end it shows very similar scenario like yours by applying constraints to button and labels.
The problem here is that your constraints are not set correctly to work with every size of iPhone and iPad. You are setting the leading edge constraint to be a fixed size from your view controller's view to the subviews.
The simplest way to solve this issue would be to have a container view that you center in the view controller's view and then use constraints to set 'Center X Alignment Constraint' and 'Center Y Alignment Constraint' to set the container view's center to that of the view controller and then add your subviews to the container view.
As a side note auto layout has a reputation of being hard to learn, you have to put the time in to learn it, I would start with Apple's Auto Layout Guide.

How can I get my UICollectionView to be the same width as my device when using Auto Layout?

I created a UICollectionView in the storyboard editor and added it to my (custom) ViewController. Like every view controller in storyboard, it says the size is 600x600 and so the UICollectionView, which takes up the whole view, is also 600x600.
This is not correct though, as I am writing an iPhone app and so the real dimensions should be 320x568!
Because of this, when I add items to my collection, they are placed off the right side of the screen. For example, I first add a cell with an image in of size 160x213. It is left justified and it takes up exactly the left half of the screen. When I add the next image, there is a huge gap and it appears on the left side, partly cut off. The third image I would expect to appear below the first, but it doesn't appear at all. I believe it is off the right side of the screen. This implies that the size of the UICollectionView is 600x600 and not 320x568.
I should mention that I've tried everything I could think of to fix this. For example:
I tried adjusting the size of the collection view:
self.photoCollection.frame = CGRectMake(0, 0, 320, 568);
I tried unchecking "Use Size Classes" in the storyboard editor.
It seems to work if I uncheck "Use Auto Layout" but I would like to use auto layout. How do I get this work?
You can set the "Simulated Metrics" of the view in your storyboard like this below. Personally, I prefer using 3.5/4-inch to construct my layout, as with auto layout, i only need to add some constraints to elements and iOS will automatically support the 4.7 and 5 inch screen size.
I think you should google for some "Auto Layout" tutorials, and I don't think its too hard for you to pick up :D. For instance, if you want to set the collection view frame equal to your view frame. You can do it like this
Feel free to ask any follow up question if your have any, Cheers!

ios - UIScrollview w/ autolayout on Xcode 6

I have been struggling for days with this implementation, and even though I have tried to do every tutorial I found on the web, I still cannot make things work the way I want.
Basically, I am trying to put my login form in a scrollview, so that it takes the whole screen at first (and on all iPhones / iPads), and if the keyboard appears everything should move. The problem IS, my view doesn't take the whole screen... Either it is too large, or too high, even though in Interface Builder everything seams correct (from layout to constraints). Below and image of the layout I want to achieve (I am using an universal storyboard, with Size Classes and Autolayout enabled):
http://img4.hostingpics.net/pics/829115app.png
Can someone point me out on achieving this layout ?
Thanks in advance.
I would suggest pinning top, leading and trailing spaces of your scroll view to its superview. And set a bottom space constraint less or equal to the keyboard's height if you set it to 0, the scroll view won't be able to resize.
With your form layout set vertical center constraints and top space to superview constraints for your top label being more or equal than the distance you set in the IB, and then you can set relative space constraints between each of the components.
Hope I answered your question.
Edit: Just the provided project and got it working. I think the problem is caused by it being a containerView inside a scrollView. And both the container and the scrollViews content view adapt to the size of its subviews. Because of that, setting relative constraints won't help.
What I did was to set an explicit size (screen's size) to the containerView and setting setTranslatesAutoresizingMaskIntoConstraints(true) to it.
I modified your project and uploaded it here

Xcode IB Storyboards orientation and container views

In an IOS 6 iPad app, I have a container view controller with multiple container views. Currently I have locked my app to landscape and works fine but I'd like to support portrait as well. Everything is set up using auto layout and constraints via Interface builder. If possible I'd like to keep one storyboard for consistency, maintainability etc.
The layout is this: Header, Left-side menu, two content panes (side by side in landscape) and a foot pane, I have all panes resizing except the content. When rotating from landscape to portrait I'd like one content pane to slide below the other (currently it blows off the screen), and both to stick to the edges of the container view.
In HTML5/CSS3 this would be easy to do but I'm stuck in IB, any help/ideas would be great!
Thanks!
EDIT:
Solution -
Following #Charles A.'s suggestion, I linked the NSLayoutConstraints to IBOutlets and manipulated spacing/priority in code. Where I really struggled was using Height and Width constraints. If you moved anything, Interface Builder would delete or override these with Leading/trailing & Top/Bottom constraints. I finally gave in and got rid off all height & width constraints, and used only leading/trailing/top/bottom.
2 things I figured out: Constraints have milestones(one at priority #750 for instance) so if you pragmatically change priority from 749 to 750, you will get:
Mutating a priority from required to not on an installed constraint (or vice-versa) is not supported.
But if you changed from 750 to 800 you are fine.
Also, after manipulating constraints, I needed to call:
[self updateViewConstraints]
I had found a post that suggested [parent updateViewConstraints], which didn't work, the one above did!
Anyway, I hope this helps others in this spot since there's not much out there.
It's hard to answer the question specifically without knowing how your layout constraints are setup to handle your two content views. Having said that, I would probably go about this UI by having my layout constrained similar to this (I'll use the visual format to describe, I'm assuming that the superview is the parent of the two content views in this case):
|-[contentViewOne]-0-[contentViewTwo(==contentViewOne)]-|
If the constraints are setup as above in the storyboard, you could create an IBOutlet of type NSLayoutConstraint* and connect it to the horizontal space constraint between the two content views (the one that specifies a constant value of 0, in my case above). When you animate from landscape to portrait, just set it's constant value to the negative width of contentViewOne. This should have the desired affect. You'll obviously also have to set it back to 0 when rotating from portrait to landscape.
It's worth noting that I assume your content views are equal width. If they're not you would potentially also need to make an outlet for a width constraint on the one sliding under in order to temporarily set it to the same width as the one covering it.
There are many potential ways to address this layout using autolayout. What I've described above is just one such way. It comes down to what makes sense given the layout you already have.

Resources