I am designing one of my view in my
MainView
I am plan to have a smaller View instance in my MainView. What I need to do is:
When the app is running on iPhone, the view size should be square and its width is equal to the screen's with. When the app is running on iPad, the width should be 1/3 of the screen's width.
So how to define different width ratio on iPhone and iPad. How to approach this? Can I do this in storyboard file or I have to do this by code? Thanks in advance.
In your storyboard file you will need to create variations for traits. There is a button in the lower right hand side of the storyboard inspector that says "Vary for Traits", using this you can set constraints to have different constant values depending on the device size(iPad/iPhone).
In this case you can pin the leading and trailing edges of the smaller view to the sides of the parent view, and for the iPhone vary the trait to be equal to zero, while the iPads space can be set to 10 points(however many points of space you want).
Creating adaptive UI's can be and is a rather complex subject, so if you have no experience, like #Zack Leonidas Hamblen said check out that article and read up to get a better understanding on what is happening and how to use it efficiently.
You can set your constraints in Storyboard, create an #IBOutlet for the constraint and do something like:
if UIDevice.current.userInterfaceIdiom == .pad {
// set the width constraint = 1/3 of the screen width
} else {
// set constraint = screen width
}
Related
I have created an app which is working fine in iphone devices , i have tried auto layout and constraints so that it would work same on iphone devices on the ipad , but the problem is its okay to look in iphone but in ipad devices distance seems too wide . for example if i have set constraints distance which is 8 its okay in iphone devices but its seems to wide in ipad device. also is there a way we can image or buttons or components would resize bigger so that will fit to the ipad? is there a good practice or the best way in setting the design that would also work on ipad. Thank You . as you have seen in the image below the distance of those numbers and possitions is how its looks on i phone. the screenshot was take in an ipad . that is how its looks on an ipad . i manage to sets contraints to button start , skip , and asnwer but i wanna resize all to ipad including the questions and the rest of the buttons with numbers as you have seen in the image i want make it big and make it equal to center.
To simplify things, Apple recommends a new paradigm. Rather than considering your layout in terms of the many device types, resolutions, multitasking modes, and device orientation, you should focus instead on adjusting your layout to two types of widths (called compact and regular) and two types of heights (also compact and regular). These distinctions are called size classes. You can then use these size classes to define or adjust your layout.
Please refer.
You can make use of AspectRatio for setting constraints using storyBoard
Static distance value 8 is okay for iPhone but very less in iPad , So to solve you need to provide distance according to screen Size
Steps
1) Drag a View in ViewController and set it Horizontally & vertically entered in container
2) Set Equal Width and Height with screen Size (ViewController)
3) Now select the Height Parameter and check for the multiplier its set to 1
4) Vary the multiplier value as per requirement
Now output will be same as on iPhone and iPad with equal looks
Spacing
1) Drag a Label to set spacing and Add it centre horizontaly with the View Added before
2) Set Top Space to View added for label as shown Below
3) Now select the Top Constraint added and vary its multiplier again to set spacing between them according to viewScreen size
Selecting Top Constraint looks like with multiplier 1
After Varying Multiplier / Label Moved Down
Output
Let's say in Storyboards you have a skipButton pinned to the bottom of the screen (your not changing the bottom pin so I didn't include it), it's 44 points in height, is 8 points from the left side of the screen, and is is 8 points from the right side of the screen. That's fine for iPhones but on the iPad you want the button to be 50 points in height, 100 from the left side of the screen, and 100 points from the right side of the screen.
Inside the view controller you need to make an outlet for those constraints of type NSLayoutConstraint and there is a constant property on it that you can use to change the constant that you set inside Storyboard (see code example below).
In case you don't know how to make the constraint connection all you do is select the constraint inside Storyboard, open the Assistant Editor, then cntrl+drag the constraint to the view controller and name it whatever you want to name it. It's the same exact process as if you was connecting a button or label or imageView the only difference is your using a constraint.
Every app has a property where you can find out which type of device is currently being used: UIDevice.current.userInterfaceIdiom Apple -Type of Device Being Used
Inside viewDidLoad you find out what type of device the user is using and then you change the constraints to whatever size is suitable to you for iPads:
// skipButton is type UIButton (look at what's next to the name skipButton). You are not changing the button you are changing the constraint on the button.
#IBOutlet weak fileprivate var skipButton: UIButton! // the main focus here are the constraints for the saveButton. I just added this here to show that the saveButton is inside this vc. Your focus is changing the below constraints that help position and size the saveButton and not the saveButton itself
// ***VERY IMPORTANT*** YOU HAVE TO CONNECT THESE CONSTRAINTS via STORYBOARD (look at the 3 pics below). You do it the same way you would have connected the skipButton above. The difference is you grab the constraint that is on skipButton that you made in storyboard. The skipButton is already connected. These are the constraints that are on it and are completely different from the skipButton itself.
// the constraints are of type NSLayoutConstraint (look at the name next to skipButtonLeadingConstraint). This is what you want to change. This and the UIButton above are two completely different things
#IBOutlet weak var skipButtonLeadingConstraint: NSLayoutConstraint! // in Storyboard left constraint is set at 8 points from left side of vc
#IBOutlet weak var skipButtonTrailingConstraint: NSLayoutConstraint! // in Storyboard right constraint is set at 8 points from right side of vc
#IBOutlet weak var skipButtonHeightConstraint: NSLayoutConstraint! // in Storyboard height is set at 44 points
override func viewDidLoad() {
super.viewDidLoad()
// if the user is using an iPad then change the constraints to the below sizes which would make the saveButton's width smaller and also it's height taller. If the user is using anything other then an iPad then it will automatically use the Storyboard constraints and automatically ignore the below code
if UIDevice.current.userInterfaceIdiom == .pad{
// when using an iPad left constraint is now set at 100 points from left side of vc
skipButtonLeadingConstraint.constant = 100
// when using an iPad right constraint is now set at 100 points from right side of vc
skipButtonTrailingConstraint.constant = 100
// when using an iPad height constraint is now set at 50 points high
skipButtonHeightConstraint.constant = 50
}
}
Below is how to add the skipButtonLeadingConstraint in Storyboard. You can grab it inside the Document Outline under the Skip Button's Constraints (it's highlighted in blue)
1st select the constraint in the Document Outline:
2nd drag the connection to the view controller and name it skipButtonLeadingConstraint:
3rd complete the connection:
I have a tableView with static cells. The cell contains an ImageView which fills it completely. And I have another smaller ImageViews atop. I position this ImageViews with constraints. I have a question about resizing the constraints.
How can I set different constraint constants for different devices sizes without programming if/else loops. Is there a way to set it in the storyboard? I have a leading constraint to parent layout for example with an constant value of 10. This is okay for the iPhone 5 screen, but on an iPhone 6/ 6 plus screen it should be higher than 10.
iPhone5 Autolayout
iPhone6 Autolayout
Very easy. You can change constants values for difference size classes in Storyboard. I am giving u a few steps after which you will be able to grasp it.
First we create constants as you can see on this view
Next we select the constant we want to change the value in other size classes.
Now comes the tricky part. In the attribute inspector after selecting the constant, you can see the value of the constant. Right beside you can see the PLUS (+) sign, left of the "constant".
Click on it and select your size class that you want.
Here i have selected Regular Height Regular Width i.e for iPad sizes.
Next we give it a new value. So the constant, which normally is of value 61, will function as 10 when rendered in a size class of iPad size classes.
Here is the output --
iPhone 4:
iPad Air:
As you can see, the same constants has different value in runtime corresponding to different size classes.
Hope my explanation helped you.
Without writing a single line of Code!
Once my junior developer asked me the same question that how can I differentiate between iPhoneSE and iPhone6 for some constraint at that time there was only one solution that was writing some thing like
if device == iPhoneSE {
constant = 44
} else if device == iPhone6 {
constant = 52
}
To overcome this issue I created a library Layout Helper so now you can update constraint for each device without writing a single line of code.
Step 1
Assign the NSLayoutHelper to your constraint
Step 2
Update the constraint for the device you want
Step 3
Run the app and see the MAGIC
Finally, I`ve found the solution which works in my case.
I put the transparent view and added Align Center X/Y to Superview(background image) with the needed offset in the way which it suits my frame for posters(on the background image)- Constraints for the transparent view
Then I attach Equal width/height to my Superview(background image) for that transparent view and change multiplier in equal width(manually I picked 0.61)
After that, I landed my 1 poster. I also centered both vertically and horizontally with offset and used this set of constraints- Proportional width to Superview, Aspect ratio.
And the last I disposed my second poster with this constraints- Leading space to Poster1, Align CenterY to Poster1(with the offset in my case) and Equal width/height. Constraints for the Poster 1/2
As the result, I have really adaptive Autolayout which works almost great on iPhones 5-6-6+
You can use BayKit for this job.
What is BayKit:
Calculates the global offset for all screen sizes by depending on given screen size and given offset.
How to use BayKit:
Usage is very easy, just import BayKit and set constant value with BayKit like this:
import BayKit
class MyViewController: UIViewController {
lazy var box = UIView()
let magicOffset = BayKit()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(box)
box.translatesAutoresizingMaskIntoConstraints = false
box.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: magicOffset.offseter(scaleFactor: 1.0,
offset: 24, direction: .horizontal, currentDeviceBound: BayKit.DeviceList.iPhone5.screenWidth)).isActive = true
}
}
As you can see this line calculating offset for all screen sizes:
magicOffset.offseter(scaleFactor: 1.0, offset: 24, direction: .horizontal, currentDeviceBound: BayKit.DeviceList.iPhone5.screenWidth)
Offseter Features:
scaleFactor: You can set if you want bigger or smaller then given offset(for default set 1.0).
offset: Preferred constant in tested device.
direction: Which direction are you looking for,i.e. (for width, leading, trailing use .horizontal,for height, top, bottom use .vertical)
currentDeviceBound: Find your best fit device and set as a main device with this. BayKit will calculate constraints with depending on your best fit screen!
Example Result:
I've been working on a project that supports multiple screen sizes for iOS. Thanks to Storyboard and auto layout technology, I could be able to handle some constraint automatically based on device screen size. But in some cases, I couldn't figure out how to deal with auto constraint when I apply constant constraint in Storyboard. For example, lets say I put a button in view controller on Storyboard and set constraints (Tailing/Leading space as 44 and Top space as 50). This button surely expand its width based on device screen size but I also want to change top space proportional to its screen size. Assume base top space 50 is set for iPhone 4 screen size (320/480), then I would like to increase it as device screen height increases. The way I manage this for now is, check screen size and change its constraint constant respectively which is 50 * (568/480) (i.e. I want to keep same ratio). I wonder if there is a way to do this trick on storyboard. I would appreciate any advices.
Is it possible to create a constraint specifically for iPhone 4s and 5s without affecting iPhone 6?
Please see image above:
The scrollview's height is with equal height with the content view. I changed the multiplier to make it 40% of the actual height of the cell.
The cell is a fix height, the same height as the main window.
If you can see on the preview on the left, there is really no space for 5s and 4s devices. So I wonder on how to approach this design issue.
Please try to use aspect ratio for all views with window view. It will calculate screen size and it will align automatically to satisfy your constraint. I had the same problem, i overcame by setting aspect ratio.
please look this, link http://mathewsanders.com/designing-adaptive-layouts-for-iphone-6-plus/
Unfortunately you cannot do this. The solution of your problem is changing the constant of a constraint. So I suggest you detect user's device see here how to do it and change the constraint value something like this:
-(void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
if (IS_IPHONE_6) {
self.verticalConstraintOfButtonToTop.constant = 22;
} else if (IS_IPHONE_5) {
self.verticalConstraintOfButtonToTop.constant = 17;
}
}
or you can create separate storyboard and use it.
Also you can use Size Classes to create universal storyboard for iPhone and iPad or portrait / landscape modes.
I don't really understand your question. Perhaps this will help:
Constraints are like other IB items in that they can be IBOutlets. Just ctl drag from a constraint in the IB object outline to the associated view controller. In the view controller you can adjust its values in code depending on the device type.
Hope this helps.
For my 1) portrait only 2) deployment target iOS7/iOS8 app, I have in my design UIButtons which have variable heights, for iPhone 5, iPhone 6 and iPhone 6+. I am trying to use auto layout for this. (Not using size classes though).
Using auto layout how can I specify variable height for UIButton for these 3 screen sizes. The buttons look fine on iPhones 5* models, but thinner on iphone 6/6+. Now in auto layout I can say height >= or = or <= say 55), but how do I specify 44 for iphone5, 55 for iphone6, 66 for iphone6+?
Is this something that I can achieve using only auto layout or do I need to manupulate (frames) it in code? What is the point of me using auto layout then?
In addition to frames my designs also specify different font sizes. How do I go about this. Any best known methods for this, Stack-O friends .. ??
You are correct to ask "what is the point of auto-layout if I have to manipulate frames directly"? Thankfully, you don't have to.
An easy way of doing it is specifying the height in relation to a view of standard height (think a view that fits the whole screen).
For example, we can set our button's height to equal half the height of the view.
This way, the button is always going to scale with the view, either upwards or downwards (size-wise). Auto-layout will guarantee that the relation between them will always be 1/2.
Now the button will be half the size of its superview, regardless of size.
It sounds like you need to be modifying the height constraints constant value.
In your xib/storyboard, create an outlet to your view/controller for the height constraint.
At runtime, probably in viewDidLoad, you will work out which device you're on, and then just change the constant of the height constraint.
CGFloat height;
// if iPhone 5
// height = 44
// else..........
self.buttonHeightConstraint.constant = height;
This will automatically trigger a flag that tells AutoLayout to recalculate frames and layout the view again.
I managed this by adding a Height-Constraint to the UIButton. Make an Outlet and you can set the Height in your UIViewController subclass with _myConstraint.constant = 55;