Programmatically align a label from bottom of screen regardless of device - iOS - ios

I've tried
self.lblTimer = [[UILabel alloc] initWithFrame:CGRectMake(x,y,width,height)];
..but since the label i'm looking to position is at the bottom of the screen it goes out of view when i switch devices. I'm trying to make the label 10 pixels in from the left and 10 pixels up from the bottom. It should look consistent regardless if it's viewed on iPhone 4, 5, 6 or 6 plus.

So, your question is about X and Y, right?
The points in iOS start at the top left corner of the screen, so the top left corner of the screen is (0,0).
If you move up/down along the left edge, the X coordinate will continue to be 0. So if you want 10 points to the right of the left edge, X will be 10.
The bottom of the screen can be calculated this way:
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
In here, the variable screenHeight will be the bottom line of the screen. So if you want 10 points above the line, you'll need to get (screenHeight - 10).
However, as mentioned by Lyndsey Scott in the comments below, this places the top left corner of your label in the top screenHeight - 10, which could (very likely with a value of 10) place your label out of sight.
To solve this, you also subtract the height of the label so the label is in sight, in the correct spot.
So your final answer is:
CGRectMake(10,(screenHeight - height - 10),width,height);

Related

Is UIScreen.main.bounds edge to edge?

I have a relatively simple question but I can't seem to find the answer anywhere. When I use:
UIScreen.main.bounds.height
Does this give me the height from the bottom edge of the screen all the way to the top or only till the safe area? For eg. is the height only until the notch for the iPhone X or does it go all that way up past the notch.
is the height only until the notch for the iPhone X or does it go all that way up past the notch
You can easily check this yourself. Set a breakpoint somewhere in any iOS project, and see what rectangles are returned by bounds or nativeBounds for the main screen when the app runs on the device you're interested in, e.g. iPhone X:
(lldb) po [[UIScreen mainScreen] bounds]
(origin = (x = 0, y = 0), size = (width = 375, height = 812))
(lldb) po [[UIScreen mainScreen] nativeBounds]
(origin = (x = 0, y = 0), size = (width = 1125, height = 2436))
You can check that against the dimensions reported for the screen in Apple's documentation:
I'd assume from that that the rectangle returned by bounds for the main screen represents the entire screen, not just the safe area. But if you're still not convinced, you could write a few lines of code that draws a rectangle with those dimensions, and you'll see that the notch and corners occlude parts of the rectangle:

Size dimensions iOS don't make sense

I'm trying to look up the bounds of my screen in Portrait mode (set to only Portrait in Xcode) using Swift but everything I try does not place my sprite on a sensible position.
let screenWidth = self.size.width;
let screenHeight = self.size.height;
var posX: CGFloat = screenWidth;
var posY: CGFloat = screenHeight / 2;
Sprite is positioned out of screen in portrait. Turning the screen reveals the sprite far right of the screen (width), in the middle (height).
So you'd think I should just turn around these values.
let screenWidth = self.size.height;
let screenHeight = self.size.width;
Nope. Still out of screen in portrait. Turning the screen again reveals it, but halfway between middle and border of the right screen border (width), and not in the middle (height).
So I guess I could try to get the values in some other way.
let screenWidth = UIScreen.mainScreen().bounds.width;
let screenHeight = UIScreen.mainScreen().bounds.height;
It's visible in portrait!... But on the far left (not on the border) and not in the middle of the screen's height either. Turning the screen places it a bit left of the middle, and still not center of height.
I think you can guess what I tried next.
let screenWidth = UIScreen.mainScreen().bounds.height;
let screenHeight = UIScreen.mainScreen().bounds.width;
Pretty far on the bottom, slighty right of the middle in portrait. Turning screen makes no sense either.
I'm kinda lost. Googled and tried things for hours but no result.

iOS convert number to iphone 6 equivalent and 6 plus equivalent

Lets say I have a 44px x 44px UIView on the iphone 5. What's the formula for converting that to the equivalent pixel size for the iphone 6 and 6 plus??
Like would it be 88 x 88 & 132 x 132 or what?
If I have a 44 x 44 UIView on the iPhone 5, how can I have that same view on 6 and 6 plus proportionately take up the same space on the screen
+(float)convertWidthToEquivalentDeviceWidth:(float)width{
float sizedToWidthDesignedTo = 320.0f;
float actualWidth = [[UIScreen mainScreen] bounds].size.width;
float percentWidth = actualWidth/sizedToWidthDesignedTo;
return width * percentWidth;
}
+(float)convertHeightToEquivalentDeviceHeight:(float)height{
float sizedToHeightDesignedTo = 568.0f;
float actualHeight = [[UIScreen mainScreen] bounds].size.height;
float percentHeight = actualHeight/sizedToHeightDesignedTo;
return height * percentHeight;
}
You can get the width of the screen and divide it to the number you want so you don't need to do code for every single device:
viewWidth = [[UIScreen mainScreen] bounds].size.width / scaleOfYourChoice
Setup constraints for top, leading, trailing space and aspect ratio.
The leading and trailing constraints will make your view change width on bigger phones and the aspect ratio constraint will adjust its height accordingly.
Here's what you do: you set the frame to be 44x44. Then you do nothing else whatsoever. UIKit coordinates are not in pixels; the problem is dealt with for you.
Use -[UIScreen nativeScale] if you're curious how many physical pixels are inside a point. That's effectively the number your UIKit coordinates are being multiplied by to make pixels.
If you instead want your view always to be, say, 36% of the available space, use an equal widths NSLayoutConstraint with a multiplier of 0.36.

Why does it think screenWidth / 2 is the far right side of the screen?

I'm pretty new to iOS development-- still in those early days of not knowing where to look to figure out what could be wrong.
So I have this:
#define kScreenWidth [UIScreen mainScreen].bounds.size.height
And then I have this:
TileView* tile = [[TileView alloc] initWithLetter:letter andSideLength:tileSide];
tile.center = CGPointMake(kScreenWidth/2, 50);
[self.gameView addSubview:tile];
And then I run the simulator and the tile gets drawn wayyy off to the side. It's that little black 1 over there in the corner. But when I set the X value for the center to 0, it appears against the far left side. So why would it think the middle was over there?
Got your width and height mixed up in the initial declaration of kScreenWidth

UIView UIScrollview - frames, bounds, center confusions

I am putting a UIImageView inside a UIScrollView, and trying to control the image so that it is centred on the scrollview after a zoom. and I am not sure the best way to do this.
The apple docs tell us NOT to use the frame property: "Warning If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored." So I am attempting using the following in a UIViewController subclass whose xib contains a scrollView and contained imageView:
scrollView.bounds =
CGRectMake
(scrollView.contentSize.width/2 - scrollView.center.x,
scrollView.contentSize.height/2 - scrollView.center.y,
scrollView.bounds.size.width,
scrollView.bounds.size.height);
containedView.center =
CGPointMake
(containedView.bounds.size.width*scrollView.zoomScale/2,
containedView.bounds.size.height*scrollView.zoomScale/2);
This works accurately where the width and height of the containedView is larger than that of the scrollView and sets the views so that subsequent scrolling will take you exactly to the edges of the containedView. However when either dimension of the image is smaller than the scrollView width and height the image is magnetically attracted to the top left corner of the screen. In the iPad Simulator (only) when the images is shrunk to the size of minimumZoom it does lock on to the centre of the screen. The magnetic attraction is very smooth as if something in the UI is overriding my code after the image has been centred. It looks a bit like a CALayer contentsGravity ( kCAGravityTopLeft ) thing, maybe?
Apple contradict their own advice in their code sample, photoScroller (in a subclass of UIScrollView):
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = imageView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
imageView.frame = frameToCenter;
This method does a better job of centring when the image is smaller, but when I try this on my project it introduces some kind of inconsistencies. For example, with scrollView.bounces = NO, a horizontal image whose height is smaller than the height of the scrollView but whose width is larger (so it can be scrolled from left to right) will scroll further to the left than it should (when scrolling to the right it stops correctly at the edge of the image, although if scrollView.bounces = YES it then bounces in from the edge so the image is always cropped on the left) When the image is larger in both dimensions than its containing scrollview this issue accentuates and the whole result feels broken, which is unsurprising given Apple's documented advice.
I have scoured the forums and can't find much comment on this. Am I missing something really obvious?
You don't appear to be using the transform property, so you can ignore that warning about not using the frame property when using the transform property. Go ahead and use the frame property, just like Apple (and the rest of us) do.

Resources