I have 27 apps in the store and did not want to create and manage new backgrounds for each of them. And I suspect that there will be more sizes in the future. So what I did was create an 1800×1800 image for each app. They are mostly around 300-400KB. Then in viewWillAppear I call this method.
- (void)pickBackgroundImage {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGFloat scale = [UIScreen mainScreen].scale;
CGPoint midPoint = [Utilities findMidpoint:self.view];
NSString *pictFile = [[NSBundle mainBundle] pathForResource:@"Background" ofType:@"png"];
UIImage *imageToDisplay = [UIImage imageWithContentsOfFile:pictFile];
imageToDisplay = [UIImage imageWithCGImage:imageToDisplay.CGImage scale:scale orientation:imageToDisplay.imageOrientation];
CGRect pictFrame;
if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
CGFloat imageWidth = (unsigned int)(.9f * self.view.frame.size.width);
pictFrame = CGRectMake(midPoint.x - imageWidth/2, midPoint.y - imageWidth/2, imageWidth, imageWidth);
pictFrame.origin.y = self.view.frame.origin.y + .3f * pictFrame.origin.y;
} else {
CGFloat imageWidth = (unsigned int)(self.view.frame.size.height - 20 - 44);
pictFrame = CGRectMake(midPoint.x - imageWidth/2, midPoint.y - imageWidth/2, imageWidth, imageWidth);
pictFrame.origin.y = 10;
}
self.BGView = [[UIImageView alloc] initWithImage:imageToDisplay];
self.BGView.frame = pictFrame;
self.BGView.contentMode = UIViewContentModeScaleAspectFit;
[self.view insertSubview:self.BGView atIndex:0];
}
The arithmetic is a little tricky, but basically I figure out how big the screen is, then subtract the menubar and bottom bar. Then fill 90% of whats left with the image. I use the scale factor, CGFloat scale = [UIScreen mainScreen].scale;, to make the device think that the image was created just for it, e.g. @2x or @3x.
Works in the simulator for all devices. I don’t have a new phone so I haven’t been able to test it on one yet.