I am using an extension to identify the device. I have a UIImage that appears too large on an iPhone 5S. I want to scale the constraint depending on the device. I want it to be like that:
if modelName == "Simulator" {
cell.eventsImageViewWidthContraint = Original * 0.8
}
What is the right code to change the constraint size (at the moment 360), to about 0.8 this size.
It looks like you're constraining the width of the ImageView to be a constant at the moment. There are 2 options I'd suggest as an alternative to using a constant. I'll assume you're using Interface Builder.
Constrain the left and right edges to a certain distance from the containing view.
Constrain the width to be a ratio of the width of the containing view. This can be accomplished by ctrl+dragging from the image view to its containing view and choosing "Aspect Ratio." You can fine tune what dimensions you're enforcing a ratio on by clicking the constraint in Interface Builder and adjusting values in the Size Inspector.
You can also try Size Classes to change the dimensions of views based on the general size of the screen.
If you are using code follow the advice above. If you are looking for an easy solution in code get the frame of the size view and calculate using those numbers. For example:
yourView.bounds.width = 0.5 * yourRootView.bounds.width
This code sets the width of a view to half the width of its root view
Related
I am working to have my buttons height and position adapt to screen size changes like the pictures shown above. The buttons themselves will remain clear and only serve as a simple way to handle taps that trigger the segues to different screens. My goal is to make it so that as the image stretches across different screen sizes, I would like the buttons to keep equal height and width and position with the windows. I know that if the windows had properties I could simply make the buttons have an equal size and width to them and be done, but as I mentioned the image is static and it has to stay that way for the time being. I've tried creating constraints for the buttons and that has only proven to be a headache and I don't know if stack views will help me here either, I know this is fairly complex, but I'm ok with that I just need some direction.
UPDATE: In an effort to follow the instructions LGP listed properly I started from step 1. As I mentioned in the comments, I believe it's simply the ratio and the constraints conflicts since when I remove one or two it works fine, but then how do I set the constraints so it fills the entire screen and maintains the ratio of the picture? Also shown are the constraint conflicts for the image view an it isn't showing the aspect ratio of the parent container view either
If you want to do it in interface builder it is not too hard. You should use spacer views and proportional sizes to position the buttons. That way, whatever size your background will have, all the elements will follow.
1. Create a container that has the same proportions as you image. Add a regular UIView and set an Aspect Ratio constraint with a multiplier of 852:568. This is the dimension of your background photo, 852 x 568 pixels, but the actual values don't matter, as long as the aspect ratio is the same. (Don't forget to also tie up the container view to however you want it in your view controller. See the UPDATE below on how to do this.)
2. Place the background image in the container. Add an image view as a child to the container. Set the constraints to touch all four edges of the container. Set the Image property to you image, and set Content Mode to Aspect Fit.
3. Add the first spacer view. Add a regular UIView to the container view (see leftmost, white view below) and set the constraints as follows:
height = 1 (not important, I used 10 in the image)
Top space to Superview = 90 (not important)
Leading space to Superview = 0
Width equal to Superview with multiplier dw:cw <- This makes it proportional! dw is the distance from the left edge to the first window/button, and cw is the width of the container. If your container is 375 wide, and your distance to the first button is 105, the multiplier will be 105:375.
4. Add the second space view. This is the vertical spacer, going from top to first button. Set it up similar as the first spacer, except make the height proportional to the containers height, and the width fixed.
5. Add the first button. Constrain its left and top edges to the spacers, then make its width and height proportional to the container.
6. Add the remaining spacers and buttons. They are all the same. Just remember where to make them proportional. All buttons are constraint to the single vertical spacer.
Finally, you should make the spacer views hidden. You can easily try it within your Storyboard by selecting different devices.
I chose to add everything on iPhone 8, but it is not really important. Here is what it looks like when I change to iPad Pro 12.9" and iPhone SE. Note how the buttons are positioned correctly. The spacer move around a little because they have partly fixed distances, but it works fine anyway.
UPDATE: Here is how to constrain the container view in the view controller's view to make the container fill the whole view and still keep its aspect ratio.
First, set the image view's (the one you added in step 2 above) Content Compression Resistance Priority to 200 for both Horizontal and Vertical. This will allow the image to compress rather then expand if it has a choice.
Second, Add the following constraints to you container:
Align Center X to Superview
Align Center Y to Superview
Equal Width to Superview >= 0
Equal Height to Superview >= 0
852:568 Ratio to View <- This you should already have!
Now the container will always center on screen, it will always fill at least the entire screen, but will also allow it to fill beyond in both X and Y.
UPDATE 2: If you want to ignore the photo's aspect ratio, and always fill the screen with the photo, you just add constraints for the container view to each side to its superview. Your container view's constraints should look like this.
In step 2 you will need to set the image's Content Mode to Scale to fill. The rest should be the same.
Use percentage based positions and size. Identify the positions of windows in percentage basis, and create the origin in x and y dimension by multiplying the percentage to the width and height of the screen. I am assuming that you are using ScaleToFill as content mode of the ImageView.
Similarly for calculating size, identify the width and height of the ImageView on percentage basis, and multiply the values in percent with the total width and height of the screen.
For example, to calculate the position of Window one-
Suppose, window1.x in percentage basis is 25% & total image view width is 400 (for example), than window1.x pixel position will be-
window1X = (25 * 400) / 100 = 100
Suppose, window1.y in percentage basis is 25% & total image view height is 300 (for example), than window1.y pixel position will be-
window1Y = (25 * 300) / 100 = 75
Suppose, width is 7% of image views width, than width in pixel will be -
window1Width = (7 * 400) /100 = 28
Suppose, height is 12% of image views height, than height in pixel will be -
window1Height = (12 * 300) /100 = 36
window1.frame = CGRectMake (window1X, window1Y, window1Width, window1Height)
Same approach for other windows, to calculate their positions(size will be same as window 1)
This approach will work across all screen resolutions, since it uses percentage based calculations & ScaleToFill as content mode for image view.
I am a beginner, I am trying to do an autolayout. I am trying to make the label 'HRIS' and 'Please login to continue' to be proportional to the screensize (its superview), I can do it for the login button and the image leaf as the picture above, we can see that the login button and leaf image are proportional.
for the image leaf, I do equal width with 0,1 multiplier to the superview, and then I also add 'aspect ratio' to make it proportional.
but when I apply the same way to the label, it doesn't work, as we can see the label size still the same for iphone 4s and iphone 8, maybe it is because the instrinsict content size (the font size itself) that makes it like that. I tried to apply this way, but it seems the size is still the same
I want to make it little bit smaller for iphone 4s, I also can't modify using size classes since it is in the same class
so what I have to do to make label proportional to the superview (screen size / background) ?
You can do it by setting both proportional width of the label and allow it to scale down the point size.
Set the label width to proportional width like this. It is just a regular same width constraint that you edit.
Then allow your label to scale down the point size like this. This is a property of your label.
Set different font size using variations...
Simply set up a constraint for your label's width to be equal the view's width with your desired multiplier. In my example I used a multiplier of 0.5:
I have created an orange circle using a UIView100 height and 100 width with a radius of 50. This was done in the 4 inch setup.
When i move up to the 4.7inch or higher the circle becomes distorted.
What do i do so that the circle doesn't get distorted when displayed on larger devices?
So I guess you used Xcode's “Reset to Suggested Constraints” option, like this:
When you do that, Xcode guesses what constraints you want. Unfortunately, in your case, it guessed wrong. It did create the centering constraints you wanted, but it did not create the width and height constraints you wanted. Instead it created leading edge and top edge constraints, like this:
So when you load your scene on a larger device, in order to satisfy those constraints, auto layout has to make the view larger, like this:
To fix this, you need to delete the edge constraints:
And add width and height constraints:
So your final constraints on the subview look like this:
With these constraints, when you load your scene on a larger device, the subview will stay centered and not change size:
I'm betting you used a fixed corner radius to make a circular UIView (which would have a constraint for 1:1 aspect ratio too). Just make it so the radius of the corners is calculated somewhere where the right dimensions for the view can be known. viewDidLayoutSubviews is a good place as it'll take care of other resizes like screen rotation.
override func viewDidLayoutSubviews() {
self.circleView.layer.cornerRadius = self.circleView.frame.size.width / 2 // Assumes width == height because of 1:1 aspect ratio constraint
}
Alternatively don't make the size of your view depend on the width or height of the screen (i.e. remove constraints to the sides, center it and give it a fixed width and height)
I'm developing an app where I'm facing an issue to achieve one UI layout only for iPhone devices. This is the layout that I'd like to achieve:
I want to achieve overlapped views that layout should be same on every device from 5s to 7 plus.
The key is setting proportional constraints.
Start with adding a UIView to hold the 4 elements - background, man, woman and heart.
Add a UIImage for the background, and pin the edges to the edges of the view - that's the easy part.
Add a UIImage for the Man...
Set the Aspect Ratio to 1:1 to keep it square (well, round in this case).
Set the Height constraint equal to the Height of the "containing" view, but then set the multiplier to less than 1 to make it relative to the view. In this case, 0.6 is pretty close.
Set constraints for Centered Horizontally and Vertically... then set the Multipliers to keep the image left and above the centers. 0.64 on horizontal, and 0.9 on vertical work pretty good.
Add a UIImage for the Woman...
Set the Height and Width constraints equal to the Man image.
Set constraints for Centered Horizontally and Vertically... then set the Multipliers to keep the image right and below the centers. 1.4 on horizontal, and 1.2 on vertical work pretty good.
Add a UIImage for the Heart...
Set the Aspect Ratio to 1:1 (or whatever gives you the proper ratio for your heart image).
Set the Height constraint equal to the Height of the "containing" view, but then set the multiplier to less than 1 to make it relative to the view. In this case, 0.15 is pretty close.
Set constraints for Centered Horizontally and Vertically... then it will need a little adjustment o note Vertical 1.05 worked for me.
Now, you just need to set appropriate constraints for the "containing" view, and all the elements will scale and position themselves within it.
When you're all done, it should (hopefully) look like this:
I put the project up in a GitHub repo for you to look at: https://github.com/DonMag/AnotherLayoutExample
I have 4 views and I want them to occupy 40 %,15%,15%,20% and I want 2 % space among them and 2% space to top and bottom layout.
I am confused on what constraint to use and how to use ?
like can aspect ratio be used for this like that ?
If I could set it in px I can do easily ,but its percetage there it gets tricky
Is it possible if i set it in px it will get translated to percentage according to screen size
Regards,
Appu
You can use the Equal constraint and set the percentages in the multiplier.
Assuming you have 1 view controller and 1 view in it, control + click (or right click) and drag from view to view controller, and choose equal (width | height).
After that, go to the size inspector on the right side and click edit on the constraint you just added and change your multiplier.
Unrelated:
Aspect ratio is when you want to constrain the size of a view to a certain ratio (W:H). 1:1 would mean width is equal to height. 1:3 means height is 3 times your width.
Size classes is when you want to use different designs for different devices sizes. Read more on size classes here