I need to set the position of the buttons, labels and views depending on the device resolution.
How can i set buttons and another views dimensions as percentage in the Interface builder ?
No, you can't. Maybe there's another way to accomplish what you want, so you should elaborate on what it is that you're trying to do exactly.
If you only have 2 elements, Normal "Springs and Struct" should be enough in IB.
They exactly match the UIViewAutoresizing that are set on a UIView.
If it's not enough you will have to use IBOutlet and calculate their size and position in your viewDidLoad method using the "bounds.size" of their super view.
[[UIScreen mainScreen] applicationFrame] will return you the size of the screen in point.
It will give you the frame or your application root view in Screen coordinate system. So if you have a status bar your origin will be (0, 20).
But Again you should check the size of the super view inside which you are placing your element to determine the positioning of your element.
myView.superView.bounds.size.height * 0.8;
If you really really really want to know the resolution in pixel of the screen you are on (which is a very very very bad idea) a UIView have a property call contentScaleFactor, but unless you are doing some very low level drawing you should never concern yourself with this.
Related
There is a bug with my UIScrollView populated with xib files that does not accurately resize xibs to fit the view. As such, when scrolling there is a noticeable offset emanating from the right side of each presented xib element and the contexts of the next element bleed into the previous. It formats correctly on the iPhone 6, but no screen larger than it.
Given that there are no constants in my code and the dimensions should be retrieved from the view itself regardless of size (using view.frame.width and view.frame.height), I wonder if there's some larger point I'm missing about UIScrollView or wether or not it simply isn't the best solution to my problem. Is there another class for creating a sort of scrollable horizontal slide-show?
You need to add constraints in order to make it work correctly in different screen sizes.
I am adding views programatically. For example, I have a scrollView as a top-bar menu, I set its height to 60. (I am already using auto layout for placing these views)
This top-bar menu looks alright visually in an iPad. However, in an iPhone, it's kind of occupying too much space. Therefore, I am thinking to change the height to 45 for an iPhone.
What's the way to get the physical size of the screen? (not screen resolution) So I can make the height proportional to the physical size?
You can get this information accessing UIScreen singleton.
To get size use UIScreen.main.nativeBounds. Also you can get scale coefficient of screen UIScreen.main.nativeScale.
You may want to consider working with the frame property of the view of the current view controller.
self.view.frame.size.height and self.view.frame.size.width
You can make your other views proportional to those dimensions or based on their values, etc.
This code should adjust your scroll view to the size of the users screen.
self.view.frame.size.height and self.view.frame.size.width
Also, make sure that your constraints are all good.
Use view.frame.size.height and view.frame.size.width to determine the size of different screen sizes. This will work inside functions only.
I have an app with certain number of UIViews. I now need to swap their positions horizontally. For example, there is a UIView called X at the left end and one called Y at the right end. At a button click, I want Y to reside where X resided and X to come to UIView Y's initial position. I figure, I must be able to do this by swapping the NSLayoutConstraints of them both(just a guess). But I can't get this to work. Is this idea possible? What will be the objective-C code for this?
These are the results I got after trying out the first code(almost there, but not completely). I have only applied it to the views KWI and DXB. What I want is a blind swap between KWI and DXB
If the views are of the same size, then it is not much of a problem. Assume your two views X and Y are called xView and yView. You could do something like this:
CGRect xViewFrame = xView.frame;
UIViewAutoresizing xViewResizingConstraints = xView.autoresizingMask;
xView.frame = yView.frame;
xView.autoresizingMask = yView.autoresizingMask;
yView.frame = xViewFrame;
yView.autoresizingMask = xViewResizingConstraints;
If you want this animated, you can put it inside a [UIView animateWithDuration: animations:^{}] block, and it should work. (I haven't tested it out though)
You could also change the CGRect xViewFrame to use CGPoint xViewCenter and swap the centers for same-sized views.
The property autoresizingMask tells the program what to do in the case of a screen resize - whether by a change in orientation, or a result of device screen size or any other reason.
If the views are NOT of the same size, you would have to deal with the proper margins of your views, and ensure that they do not get clipped outside the screen.
Hope this helps.
EDIT
It seems that you are using UILabels either as your view, or a subview of the two views. If this is the case, make sure you also swap the NSTextAlignment of the UILabels. Something like this:
NSTextAlignment xTextAlignment = xView.titleLabel.textAlignment;
xView.titleLabel.textAlignment = yView.titleLabel.textAlignment;
yView.titleLabel.textAlignment = xTextAlignment;
I have a problem where I want to modify NSLayoutconstraints on a UIView but it appears a lot of the properties are readonly. I initially have four UIViews as squares in a sort of quad view and they are all tied to each other with a gap of about 20 pixels.
I have a button that increases the frame of one of those squares into full screen encompassing all others. It is at this point I would like to change the constraints of that UIView to attach it to the superviews borders at 20 pixels, that way when I rotate it it doesn't go back to the quad view but maintains full screen. It looks like the property I would want to change is 'seconditem' but this won't work. Am I approaching this problem in the wrong way? I find Autolayout a bit difficult so any help would be much appreciated
Hi you can do 2 sets of constraints :
1 to manage your quad view with priority High
1 to manage your fullscreen with priority Low
In the method called when you tap your button, set priority high to your fullscreen constraints and priority low to your quad view constraints.
I understand the difference between frames and bounds I think, bounds are to the view's local coordinate system, while frames are to the superviews.
With scrollviews however, I'm a little confused.
When I have a UIImageView in a UIScrollView and pinch to zoom it larger, it seems the frame grows larger (width and height) increases the width and height of the corresponding UIImage as well.
However, it seems like the bounds of the UIImageView don't change at all.
Why is this? How do scroll views work in regards to all of this? I've read multiple questions and checked the documentation but this explanation is eluding me.
How does zooming in a UIScrollView affect its contents? Does it just change the frame of the zooming view but somehow not the bounds?
See the explanation in my book:
The scroll view zooms by applying a scaling transform to the scalable view; therefore the frame of the scalable view is scaled as well. Moreover, the scroll view is concerned to make scrolling continue to work correctly: the limits as the user scrolls should continue to match the limits of the content, and commands like scrollRectToVisible:animated: should continue to work the same way for the same values. Therefore, the scroll view automatically scales its own contentSize to match the current zoomScale. (You can actually detect this happening by overriding setContentSize in a UIScrollView subclass: you can see the scroll view adjusting its own content size as you zoom.)
Basically (though that is not quite clear from the above quotation) we have no business concerning ourselves with the frame of the scalable view - or any view - that has a non-identity transform applied to it, which is exactly the case here. That fact is made very clear by the Apple documentation on UIView. Thus you should not be looking at the frame - only the transform. The frame value that your are reading changes purely as a side-effect of the transform change.
As for the bounds of the scalable view - obviously the bounds do not change; that is the whole point of how a transform works. It maintains a constant center and bounds, so that subviews and drawing continue to operate correctly within the frame-of-reference coordinates despite the transform. My book talks you through an understanding of this as well.
On the other hand, the scroll view's own bounds can certainly change their origin, not least because that is exactly and identically what it means for a scroll view to scroll. Scrolling is a change of bounds origin, plain and simple. And this would not be surprising during zooming, because, as I just said, the content size has changed, so the content may be repositioned in order to keep displaying it coherently as you zoom.