Auto layout only returning single device width. Expecting device that is being used width - xcode

I'm trying to set my UIImageView corner radius to produce a circular UIImageView. However, when I run my app on an iPhone 7 Plus the image isn't quiet circular.
imageOutlet.layer.cornerRadius = imageOutlet.frame.size.width / 2
While debugging this issue, I noticed that the width returned was the same regardless of the device. Then, when I changed the "view as: iPhone 7 (w C, h R)" near the bottom of the storyboard to iPhone 7 Plus, all worked as expected on iPhone 7 Plus and did not work correctly on iPhone 7.
My constraints for the UIImageView used are as follows:
My intention is to be able to get the width of the UIImageView as it is on the device that is being used.

Add width/height constraints on the UIImageView to force them to be equal. If the width/height of the image is dependent on the screen size, you will get weird results like you described. Since you have a trailing/leading constraint of 42 pixels to the Superview, the width of the image is going to be different depending on the device. The formula you used only works with equal width/height.

After wrestling with this problem for a while I have finally found a solution.
Summary: Calling layoutIfNeeded() on my UIImageView outlet before calling .frame.size.width yields the correct width for the device that is running the application.
Details:
My setAppearance() function is called in the viewDidLoad() function. During viewDidLoad() call, the application returned a width that was based on the default device (in my case: iPhone 7). This happened even when I was running on the iPhone 7 Plus simulator. However, calling width anytime after viewDidLoad() yielded the correct width based on the device that was running the application.
Below, i'm running the application on an iPhone 7s Plus and printing the width during the viewDidLoad function. The width changes from 281.0 (iPhone 7 expected size) to 310.6667 (iPhone 7 Plus expected size) when called again, after the viewDidLoad() fn.
This results in unsatisfactory as my image is not completely circular (my intention with the .frame.size.width/2 call).
However, calling layoutIfNeeded() fn right before accessing the width member of my UIImageView yields the following width during the viewDidLoad() fn.
By forcing the layout of the UIImageView with layoutIfNeeded() before accusing the width, the application receives the correct width based on the device during the viewDidLoad function.
visit https://developer.apple.com/reference/uikit/uiview/1622507-layoutifneeded for more information.

Related

How to prevent Storyboard from resizing (stretching) a UIImage centered on a UIView?

I have a Universal iOS app and am trying to move from old-style launch images to a simple centered image on a storyboard Launch screen, so I have a single storyboard for all devices. My image (640x1136, iPhone 5s size) needs to not be stretched when the app is run on devices with larger sizes than the image -- in other words, the background color of the UIView should appear surrounding the image on larger devices. For debugging purposes I changed the view background color to a gaudy Lime.
I defined 2 constraints on the UIImageView as directed in the SO post here according to the highest-upvoted answer (Suragch's) and in fact had to also follow the accepted answer's recommendation to add the additional UIView into which my UIImageView would be contained.
The "content mode" of the UIImageView is Center so seems there should be no stretching.
In the pic notice Xcode's Size Inspector settings for the UIImageView. The UIView has iPhone 7-sized dims (750x1334) and so because that iPhone is taller than my image the UIImageView is positioned so that its X is 55, Y is 99. The width and height are same as the image itself (640x1136).
When I run in Simulator an iPhone 7 seems it should look like exactly as what Xcode's Interface Builder shows (Lime color appearing all around the image, but instead, for any device larger than an iPhone 5s or SE it looks like the pic I've attached (an iPad Air, FYI). You can tell the image must be stretched quite a bit vertically because the image is only 1136 tall.
I've attached screenshots for the iPhone 7 (simulator) iPad Air and iPad Pro. Notice the horizontal strips of lime color appear on the right and left edges of the iPad Air. And notice that when it comes to the iPad Pro the lime background color begins to be shown above the image. It's as if on the smaller devices the system is stretching the UIImageView, but as device screen size increases this eventually stops, until for the largest (the Pro) you can actually see the background all around. It seems that for all device sizes listed in the Apple docs that are taller than iPhone 5s or SE, there should be no stretching/distortion. This is what I'm trying to accomplish.
Interface Builder size settings
iPhone 7 (simulator) screenshot
iPad Air (device) screenshot
iPad Pro (device) screenshot
I was able to get this to work finally, by completely eliminating the constraints and only using the autoresizing settings found when you choose the Size Inspector. The UIImageView now retains its specified size and is not stretched.
Try adding a width/height constraint to your ImageView:
This is done by first selecting your ImageView and then selecting this |-☐-| icon (located at the bottom right of the Storyboard window, next to the option where you can change the type of device)
Okay, I think I've figured out the problem. Your image is sized too large. You say you want it to be the size of an iPhone 5, and it's display size is 1136x640 pixels. This is not the same as the width/height in Xcode. To get this, change the device to iPhone 5 (or similar) and get the size. For instance, the size of the View for an iPhone 8 is 667x375. Then your image won't be cut off.

Get iPhone 5s app to scale to iPhone 6 resolution in Xcode Storyboard

I want my iPhone 5s app to simply upscale for the iPhone 6. I have no Launch Images in the project, but I do have the interface builder location declared in the plist to get rid of the black bars. How can I get the app to just upscale, right now it shows white space in Storyboard.
Looking at your question it looks like you are using absolute frame values for positioning, by setting frame.size.{width, height} and frame.origin.{x,y}.
You have two options.
set those values programatically. It's not recommended at all but might be easier to setup. Detect what is the screen's size with [[[UIScreen mainScreen] bounds] size] (check for the height property) or detect the device's version (eg Determine device (iPhone, iPod Touch) with iPhone SDK).
a less slippery road is to transform your project an start using AutoLayout. There's a learning curve but it guarantees that your project will be fitting well any screen. Start here: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Introduction/Introduction.html

xcode drawrect - UIView bounds not reflecting rotation in simulator

I'm using xcode 4.5.2 to learn to develop in iOS6. I have this code in my drawRect...
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGPoint midPoint;
midPoint.x = self.bounds.origin.x + self.bounds.size.width/2;
midPoint.y = self.bounds.origin.y + self.bounds.size.height/2;
... etc
For some reason when I run this in iphone simulator, the result is always
midpoint.x = 160
midpoint.y = 252
regardless of whether the simulator (iPhone retina screen) is in portrait mode or rotated to landscape. The result is thus the graphic that I draw in portrait mode is centred on the screen correctly, but offset to the left in landscape.
Can someone suggest where do I begin to look as to why this is the case?
This drawRect code came directly from an earlier app I wrote which functioned correctly in terms of determining this midpoint of the screen (a UIView spanning the whole screen). This problem arises when I imported this code (the whole class) into my currently program which is segue-ing into instances of these UIViews.
Thanks.
figured it out, I think...
it appears that for unknown reasons (to me anyway), when the phone gets rotated, the view inside the phone did not get resized to fill the new vertical & horizontal dimensions. Thus the midpoint coordinates are always the same - because the view basically did not resize. In the size inspector, the view's got struts on the left & right only and no springs.
By adding both vertical & horizontal springs, the view seems to resize with rotation and the midpoint coordinate seem to change accordingly.
While I've gotten by my hurdle, I'm still unclear why I needed to add springs to the view, since the demo that I was following did not seem to require this step. Any suggestions would be appreciated. Thanks.

grow or shrink UIImageView frame to fit the entire iPhone screen via AutoLayout?

So I'm still getting accustomed to the world of Auto Layout in iOS 6 and it's been a fun (or in plain English -- tough) migration coming over from strings & struts.
I have a UIImageView that's the background for a game I'm working on. Here's what a regular 3.5" Retina Display looks like in Interface Builder:
but if I change the "Size" pop-up in the Simulated Metrics field for the content view to "Retina 4 Full Screen", here's what I see:
And you can see the ugly black bar appearing along the bottom edge of the simulated iPhone 5 screen. This same ugly black bar makes it over to the compiled app running in the iPhone 5 simulator.
Are there any attributes or constraints I can apply via Interface Builder to get the UIImageView's frame to size correctly for the appropriate iPhone device screen size?
Or do I have to enter in constraints via code? (ugh)
I've watched the three WWDC videos and if the engineers covered the topic of sizing a view to fit a parent, they must have glossed over it really fast because I've haven't yet found or heard a decent method to get both UIImageView and NSImageView to size correctly to their parent views under both the iOS and MacOS side.
From what you're showing here, I think that what you want to do is drag the image to meet the bottom of the superview so that it takes up all of the space you want. On the bottom right in the IB view you will see a small, grey pill-shaped set of 3 buttons. Click the center one (once you have your imageView selected). It's the one that looks a little like this: |--|. It will bring up a list of constraints. Once you have done that, select "Bottom Space to Superview". You should then be able to switch between phones and have the image resize automatically.

Why view size is 703x768 for iPad app in Interface Builder?

Im working on my first iPad app.
By default Xcode generated for me a starting point project, which contains the basic template for the Split view controller.
I am focusing on the detail view controller right now (my first app version may only utilize this view).
Anyway, I noticed that in the Xcode integrated Interface Builder the detail view is 703 (width) x 768 (height).
First question: why is the width 703?
Now, the view in the IB shows a portrait layout of the view. So it's even more odd that the width is greater than the height (when it should be the other way around).
I actually expected the width to be 768, and the height 1024.
updated *
2nd Question: In portrait mode, why is the width 1024 and height 768 (see above closing comments).
Thanks.
The split view's master is 320 px wide according to the documentation, leaving the detail pane a comfortable 768 or 704 px wide depending on the orientation of the device.
ref> ipad split view dimension parts
Please take a look here

Resources