I have an app that is using a UITabBar and UINavigationBar. I am creating a UIImageView that contains my background image and then add that UIImageView to my self.view as a subview. This causes the background to appear "squished" vertically. The background image is not starting until the bottom of the NavBar and then runs down behind the TabBar.
Here's the code I'm using to add the background:
UIImageView* backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"]];
[backgroundView setFrame:CGRectMake(0, 0, 320, 480)];
[self.view addSubview:backgroundView];
Any ideas about how to keep the actual size of the background would be greatly appreciated.
First off, you won't have 480 points of height to use with a UINavigationBar present on anything less than an iPhone/iPod 5. You should use self.view.frame.size.height to get the actual size. Really, you should just set the frame to the view's bounds.
[backgroundView setFrame:self.view.bounds];
Secondly, you should set the contentMode property of the UIImageView.
[backgroundView setContentMode:UIViewContentModeScaleAspectFill]; //Set UIViewContentModeScaleAspectFit if you want to show the full image with the potential of a letterbox
That should solve your problems.
I'm not quite sure what you're asking. Yes, any view that belongs to a tab bar controller or navigation controller will be resized to fit the remaining screen space, but you know exactly how much space your image view will have left after considering the space consumed by the other UI elements:
Status bar: 320 x 20 (portrait), 480 x 20 (landscape) Navigation bar: 320 x 44 (portrait), 480 x 34 (landscape) Tab bar: 320 x 49 (portrait), 480 x 49 (landscape)
So basically, you have the following available space for your image view:
Portrait: 320 x 367 Landspace: 480 x 217
Design your Default.png with those dimensions in mind. Honestly, the easiest way to match your first screen with your Default.png is to simply take a screenshot of the iOS Simulator.
Related
I am trying to resize the view but not working,
I have UIView in CustomCell, its working in iphone 5S but when i check in iPhone6 or iphone6+ simulator than its not changing the size of UIViews.
cell.ViewImgWithOption.frame= CGRectMake(0, 0, WIDTH,60);
Above code working in 320 size screen Width but not working in 375 or 414 size screen Width.
Any suggestion?
try this one hope it will work.
cell.ViewImgWithOption.frame= CGRectMake(0, 0,self.view.frame.size.width,60);
Currently I'm using a custom image for my UITableView Accessory View. I set the accessory view to an imageview with this custom image. If I use cell-arrow.png (15x15 px) it looks quite pixelated. However, if I use cell-arrow.png (100x100 px) and then re-size it in code [see below] then it looks much better. Why is this?
Follow up question:
It seems that it has been determined that using a 100x100px image and then sizing it down to a 15x15 looks better on a the device (specifically with retina, haven't fully tested it < 4.0). The follow up question is what maximum size I can set the image to so that it increases the resolution? For example, I tested a 1024x1024 version of the same exact cell-arrow.png image, and it look identical to when I re-sized the 100x100 px image.
*Code used to re-size image: *
CGRect myImageRect = CGRectMake(0.0f, 0.0f, 15.0f, 15.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"cell-arrow.png"]];
// cellArrowNotScaled ends up making the image look very pixelated
// UIImageView *cellArrowNotScaled = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell-arrow15.png"]];
cell.accessoryView = myImage; //cellArrowNotScaled;
In general, you should use an image that is exactly the size that it will be used on screen. Otherwise, you are leaving your image scaling up to the software, and you may end up with misaligned pixels and sharp lines turning fuzzy. Remember that as of iOS 4, all measurements in UIKit are in UIKit points, where on a Retina display 1pt = 2px, and on non-Retina, 1pt = 1px.
So, for your 15pt × 15pt image view, you will need two image files if you intend to target both Retina and non-Retina devices:
cell-arrow.png, a 15px × 15px image
cell-arrow#2x.png, a 30px × 30px image
Then you call [UIImage imageNamed:#"cell-arrow"] (note the lack of an extension - UIKit figures it out for you), and the OS will load the 1x or 2x version as appropriate.
I tried to add a UITableView programmatically to my view, but setting its parameters as follows doesn't work (the last cell is cropped).
table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480) style:UITableViewStylePlain];
I tried to replace the height by 460, which works pretty well. But I want to know the exact size of this bar :
Thanks for your help.
You should never hardcode the exact value of the height at any point in your code.
As long as you use default UI components (UINavigationController / UITableView / UICollectionView / etc.) you usually don't need to worry about the status bar height at all. These ViewControllers should layout correctly on any device and any orientation.
If you do have custom layout needs, you should refer to the safeAreaLayoutGuide on UIView, instead of hardcoding a height:
https://developer.apple.com/documentation/uikit/uiview/2891102-safearealayoutguide?language=objc
But to make this answer complete - the size of the status bar is different on different devices and different orientations:
Most devices up to the iPhone X have a 20pt height in portrait & landscape.
(20px, 40px, 60px in #1x, #2x, #3x)
On iPhone X in portrait it's 44pt (so 44px, 88px, 132px accordingly).
In landscape the height is different though.
Your parent view controller will resize it's view to the right size. You can
make your view controller load a subclass of UIView and override -layoutSubviews
insert your subview with the proper starting size ([[ MyViewClass alloc ] initWithFrame:superview.bounds]) and the proper autoresizing mask. It's important when using autoresizing struts & springs that you give your view the proper size to start with.
BTW--another problem with hard coding the status bar height: it's sometimes double-height. (when the user is recording audio, making a phone call, using internet tethering, using navigation, etc.)
This answer is to Rob's question in the comments to the original question:
So if I don't hard-code my screen size, how can I set it automatically to fit my UIViewController?
Try this:
- (void)viewDidLoad {
[super viewDidLoad];
table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
// all other table setup
table.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:table];
}
This assumes you want the table view to fill the view controller's view. Adjust as needed.
This will ensure the table view's size changes as the view controller's view size changes. This covers rotations, in-call status bars, etc.
You should't use set pixel dimensions to size something to the screen. use you view's frame. i.e.
table = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
Anyway. It's 20 points. 20px non retina. 40px retina.
Update for iPhone X
Previously all iPhone devices have a status bar height of 20pt. But on iPhone X, it's 44pt. So be careful when implementing your UI.
I have a 850x1100 UIView defined in a storyboard it is 4 times the size of a normal window, and I'm using it as a PDF generation template.
The view is wrapped within a scrollview. Yet when I display the view, its frame gets resized and becomes 320x460, effectively cutting off everything outside the frame.
Does anyone have insight on why my UIView defined in a storyboard as 850x1100 gets its frame reset to 320x460 when displayed on an iPhone?
This frame recalculation is not a bug. The frame of a view represents its position and size relative to the screen coordinates.
The iPhone viewing area is 320x480 and any view that has its frame set to a CGRect larger than the viewing area of the device will become "clipped" and have its frame set back to the viewing area (320x460 viewing area due to the status bar).
Try:
scrollView.contentSize = CGSizeMake(850,1100);
scrollView.clipsToBounds = NO;
pdfView.clipsToBounds = NO;
Are you sure it's not the scrollview whose contentsize is too small? It won't automatically resize based on the content - you have to explicitly set the contentSize of the UIScrollView
I have a UIView of size width=320px height=40px which I want to display at the bottom looking like a tab-bar.
I use the following code to accomplish this and it works fine on iPhone. But when I try the iPad simulator, the view does not appear anywhere on the screen.
buttonsView.frame=CGRectMake(
0,
self.view.frame.size.height - buttonsView.frame.size.height,
self.view.frame.size.width,
buttonsView.frame.size.height );
This stretches the view to the width of the screen but keeps it's original height.
How can I make this show right on my iPad also?
[UPDATE]
This happens in my viewDidLoad.
I have this NSLog now:
NSLog(#"buttonsView Width: \t%g\t%g\tHeight:\t%g\t%g",self.view.frame.size.width, buttonsView.frame.size.width, self.view.frame.size.height, buttonsView.frame.size.height);
With output:
iPhone:
buttonsView Width: 320 320 Height: 460 40
iPad:
buttonsView Width: 768 768 Height: 1004 40
I also create another view like this for the top of the page which works fine:
dataView.frame=CGRectMake(
0,
0,
self.view.frame.size.width,
dataView.frame.size.height);
Have you looked (using breakpoints or NSLog) at the values you are putting into the CGRectMake call, just as a sort of "sanity check"?
Thanks for the info. My next thought is that between viewDidLoad and viewWillAppear something is being changed by the OS. Perhaps try moving the code to viewWillAppear so that you are guaranteed the frames you are working with will be the frames that will be displayed. This Stack Overflow answer explains it in a little bit more depth.
This happened because the Auto Resizing was set for the UIView's.
To fix, set the Auto Resizing to bind it to the top left corner. This way whenever you change the frame, it is relative to the top left pixel.