How do I specify fullscreen background images in X

2019-09-03 15:04发布

问题:

I am developing an ObjC iPhone app in Xcode 6, targeting iOS 7 as the minimum version.

I have fullscreen background images for the main UIViewController instance in my app. The app uses four visual themes, and each background now comes in three sizes. To support 4", 4.7", and 5.5" screens, the image widths are 640, 750, and 1242 pixels respectively. In my project, I choose a specific image based on the result of [[UIScreen mainScreen] nativeBounds] to get the background image corresponding to the screen resolution. For example, background_gray (for 640 pixels), background_gray_750, and background_gray_1242.

Is there a way I can arrange all of my background images in an Xcode xcassets bundle so each device will only get the background images it will use? In other words, the backgrounds with pixel widths of 750 and 1242 pixels will never get used on a 3.5" or 4" screen.

Both the 640-pixel 750-pixel width images are 2x, so this isn't a matter of simply specifying 1x, 2x, and 3x versions of one image using the same name.

回答1:

No, there is only a single application bundle distributed to the store for all devices iPhone 4 through iPad. This bundle will need to hold your images for all devices.



回答2:

I recently faced this situation too and pondered why Apple didn't include a Retina 4.7 2x option in the device-specific image set.

Rather than creating an image set for each size variation, as you described, I used two image sets per image: one which contains images for 1x, 2x, Retina 4" 2x, and 3x like this:

And one for the iPhone 6 (Retina 4.7" 2x) image, like this:

This way I only need to check for the screen width that matches the iPhone 6, like so:

CGFloat screenWidth = CGRectGetWidth([UIScreen mainScreen].nativeBounds);
NSString *imageName = (screenWidth == 750.0) ? @"Image~750" : @"Image";
UIImage *image = [UIImage imageNamed:imageName];

The false condition in the above ternary operator defers to the OS to pick the correct image to display from the first image set above.



回答3:

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 1800x1800 image for each app. They are mostly around 300-400KB. It works for me because there is lots of white space around the image. I basically put a square image in the center of the screen. If you want to fill up the whole screen, then this method won’t work. 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.

This is what the background looks like.



回答4:

In your prefix.pch define the resolution :

    #endif
    #define   IsIphone6     ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )667 ) < DBL_EPSILON )
    #define   IsIphone5     ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
    #define   IsIphone4     ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )480 ) < DBL_EPSILON )
    #define   IsIphone6Plus     ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )736 ) < DBL_EPSILON )

in all your file .m now you can use if & else for any function:

  if (IsIphone6Plus) {

      bg.image = [UIImage imageNamed:@"bg6plus.png"];

  } else if (IsIphone6){

      bg.image = [UIImage imageNamed:@"bg6.png"];

  } else if (IsIphone5) {

      bg.image = [UIImage imageNamed:@"bg5.png"];

  } else if (IsIphone4) {

       bg.image = [UIImage imageNamed:@"bg4.png"];


  } else {

       bg.image = [UIImage imageNamed:@"ipad.png"];
  }

If for example the image is the same for 5/6 and 6plus you can use:

 if (IsIphone5||IsIphone6||IsIphone6Plus) {

          bg.image = [UIImage imageNamed:@"bg.png"];

      } else if (IsIphone4) {
           bg.image = [UIImage imageNamed:@"bg4.png"];
      } else {

           bg.image = [UIImage imageNamed:@"ipad.png"];
      }

This is valid for all example for a button position, dimensions of scroll views exc

hope this help you or other people