how to set width and height of a UIVIew in pixels? - ios

I am working on an ObjectiveC app in which I need to set the width and height of a uiview in pixels and than scale that uiview equal to the devices width. The width and height values in pixels are fixed ( let say 900 px x 500 px).
Currently I am doing this,
UIScreen* mainScreen = [UIScreen mainScreen];
CGRect frame = CGRectMake(0, 0, 900.0, 500.0);
[view setFrame:frame];
CGFloat valScale = mainScreen.bounds.size.width/900.0;
[view setContentScaleFactor:valScale];
But this is not giving me the desired values.
What should I do?
(P.S) Does view.frame.size.width return the width in pixels or points?

Hi for scaling a view you can use the transform property. Say you wish to scale your UIView by a factor of 2 then you can use.
self.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 2, 2);
CGRect width and height returns points not pixels. One point has two pixels for 2x devices like iPhone 6,7 and three pixels for 3x devices like iPhone 6 Plus,7 Plus.
For more detail you can refer this Apple's documentation link.

Related

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.

Dynamically centering UIImagepicker viewfinder that has been scaled up to full screen

I'm making a full screen camera for the iPhone 5 and have the following code to scale the 4:3 camera to fill the entire screen, which is a 2:3 ratio. The left and right sides bleed off the screen.
I have to move the cameraView down 71 points in order for it to center with the screen. Otherwise, there's a black bar at the bottom. I'm not quite sure why. Because I don't know why this is happening, I can't figure out how to dynamically code the adjustment to accommodate the iPhone 6 and 6 Plus.
Any help is appreciated.
// get the screen size
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// establish the height to width ratio of the camera
float heightRatio = 4.0f / 3.0f;
// calculate the height of the camera based on the screen width
float cameraHeight = screenSize.width * heightRatio;
// calculate the ratio that the camera height needs to be scaled by
float ratio = screenSize.height / cameraHeight;
//This slots the preview exactly in the middle of the screen by moving it down 71 points (for iphone 5)
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 71.0);
self.camera.cameraViewTransform = translate;
CGAffineTransform scale = CGAffineTransformScale(translate, ratio, ratio);
self.camera.cameraViewTransform = scale;
This finally clicked in my head. Since we know that the camera will always be the same length of the screen width:
//getting the camera height by the 4:3 ratio
int cameraViewHeight = SCREEN_WIDTH * 1.333;
int adjustedYPosition = (SCREEN_HEIGHT - cameraViewHeight) / 2;
CGAffineTransform translate = CGAffineTransformMakeTranslation(0, adjustedYPosition);
self.imagePicker.cameraViewTransform = translate;

Retina issue: how to make UIView to have width exactly 1 of pixel instead of 2 pixels?

I know we are operating on points not pixels and in most cases it's convenient, but I need to make UIView be 1 pixel instead of 2 pixel height. So, if you drag and drop some UIView (separator line) in Interaface builder, and make it the height of 1px (point) then it will still look like 2 pixel size line on retina screen (both on device and simulator).
I know there contentScaleFactor property on the view which show is it retina (2.0f) or not (1.0f). It looks like the views has the value of 1.0f, so you need to retrieve that from main screen:
[UIScreen mainScreen].scale;
This returns me 2.0f. Now, I'v added height constraint for this separator view added the method which checks isRetina and divides the line to make it exactly 1 pixel:
- (void)awakeFromNib{
[super awakeFromNib];
CGFloat isRetina = ([UIScreen mainScreen].scale == 2.0f) ? YES : NO;
if (isRetina) {
self.separatorViewHeightConstraint.constant /= 2;
}
}
This works, I'm just not sure is it good idea to use 0.5 value ...
To support newer 3x displays (e.g. iPhone 6+) use this code:
UIScreen* mainScreen = [UIScreen mainScreen];
CGFloat onePixel = 1.0 / mainScreen.scale;
if ([mainScreen respondsToSelector:#selector(nativeScale)])
onePixel = 1.0 / mainScreen.nativeScale;
Your code is valid. Using 0.5 to set the frame of a UIView will work as desired, as the frame's arguments are CGFloat's. If you wish to use a CGFloat representing a single pixel in point units for something other than self.separatorViewHeightConstraint.constant, the code below will work.
CGFloat scaleOfMainScreen = [UIScreen mainScreen].scale;
CGFloat alwaysOnePixelInPointUnits = 1.0/scaleOfMainScreen;
You could just do
self.separatorViewHeightConstraint.constant = self.separatorViewHeightConstraint.constant / [UIScreen mainScreen].scale;
yes setting the value to 0.5 is the only way to get "real" 1px lines on retina
Sadly none of the other answers apply for iPhone 6 Plus.
1px lines are not possible on iPhone 6 Plus, as the screen is rendered in 1242x2208 and then down sampled to 1080x1920. Sometimes you will get an almost perfect 1px line, and sometimes the line will disappear completely.
See http://www.paintcodeapp.com/news/iphone-6-screens-demystified for a proper explanation.

CGRect coordinates in non-retina form when using SetFrame

I have a ViewController to which I applied the retina 3.5" form factor in the story board. The iOS iPhone 6.1 simulator also has the Retina configured.
When I try to position a UIImageView using SetFrame, its CGRect coordinates are in the non-retina form (i.e. when I position to 320x480, it goes to the bottom right instead of the middle of the screen):
[myImageView setFrame:CGRectMake(320, 480, myImageView.frame.size.width, myImageView.frame.size.height)];
[self.view addSubview:myImageView];
How to have CGRect coordinates for Retina when using SetFrame ?
Thanks.
The reason for this is because iOS uses points instead of pixels. This way, the same code will work on a retina and a non-retina screen. Therefore, when you set the location to (320,480) you are setting it to point (320,480) not pixel (320,480). This way, if the phone is non-retina, that point will end up being pixel (320, 480) and on retina, it will end up being pixel (640,960).
So what it looks like you want is:
[myImageView setFrame:CGRectMake(160, 240, myImageView.frame.size.width, myImageView.frame.size.height)];
[self.view addSubview:myImageView];
which will place the imageView's top-left corner in the same location on both retina and normal display.
To center a view:
CGFloat x = self.view.frame.size.width;
CGFloat h = self.view.frame.size.height;
[myImageView setCenter:CGPointMake(w/2, h/2)];
...
[self.view addSubview:myImageView];
CGRectMake needs a x,y,width,height.. X,y are the topleft of the view, so use 0,0,w,h for full frame views.

Auto-resize UIView to fit iPhone 5 screen while maintaining proportion

My StoryBoard is configured for iPhone4 resolution, and when running on iPhone 5 I'd like a UIView to get bigger (both height&width).
The problem right now is that the view is only getting higher and not wider. What should be the auto-resize configuration in order to achieve this?
You will probably need to use a subclass of UIView with the setFrame: method overridden to catch frame changes.
- (void)setFrame:(CGRect)frame
{
frame.size.width = frame.size.height; // Make the *width* always equal to the *height*. Logic could go here, etc.
[super setFrame:frame]
}
Reference the height of the screen and use some padding values to set your view frame. Below is code to set the frame of a UIView called yourShapeView:
// Get the frame of the screen
CGRect screenFrame = [[UIScreen mainScreen] bounds];
// Set padding from the top and bottom of the shape
CGFloat verticalPadding = 40.0f;
CGFloat horizontalPadding = 20.0f;
// Get the height/width values
CGFloat height = screenFrame.size.height - (verticalPadding * 2);
CGFloat width = screenFrame.size.width - (horizontalPadding * 2);
// Set the size of your shape based on the height and padding
yourShapeView.frame = CGRectMake(horizontalPadding, verticalPadding, width, height);

Resources