Reputation: 41
I placed a background image that needs to fill the iPhone screen. It is fine in portait view but when I rotate the device the top is cropped which I don't want. The best seems to be an image for the portrait view and one for the landscape view. I tried to use the size classes, assigning 1 image for compact W and any H and 1 for any W and compact H. I can't make it work. I am using Xcode 6.3 and swift 1.2. I made another app using the instructions in the book iOS 8 essentials (Neil Smyth) chapter 24 but it does not work. I downloaded the file "universal_images", thinking I was doing something wrong but it does not work neither.
Upvotes: 2
Views: 4816
Reputation: 1
I wanted to do this and it took me forever to find an ios 11/swift 4 version of the solution so I thought I would offer it here. You follow all the steps given in the answer above but the code is:
func changeBackground() {
//iPads etc
if traitCollection.horizontalSizeClass == .regular{
background.image = UIImage(named: "beethovenV.png")
}
else {
//compact width - most iPhones in portrait
background.image = UIImage(named: "beethovenV.png")
//iphone in landscape
if traitCollection.verticalSizeClass == .compact{
background.image = UIImage(named: "beethovenH.png")
}
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
changeBackground()
}
Upvotes: 0
Reputation: 41
This is the answer to my question.
1 - I added my two background pictures (one landscape version and one portrait version) in Supporting files , in a group that I named "images" (not necessary but tidier).
2 - In Main.storyboard, I added a View (via object library on the right inside bottom) that appears inside the already present view in the view controller scene.
3 - Inside that view I put an image view and in the editor -> image view ->image selected the portrait image file. View-> mode-> Aspect to fill
4 - I add constraints to the container view and image view through the pin menu 0 bottom, top, left , right.
5 - In ViewController.swift inside the class ViewController: UIViewController {…… I added the following code:
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
if (toInterfaceOrientation.isLandscape) {
println("Landscape");
background.image = UIImage (named: "BeethovenH.png")
}
else {
println("Portrait");
background.image = UIImage (named: "BeethovenV.png")
}
}
It worked perfectly. Thanks for your help.
Upvotes: 2
Reputation: 8014
I always use two images: one for portrait and one for landscape and have different resolutions for different targets. This is the best way to guarantee your background looks right on different devices with different aspect ratios.
I always make the background a UIImageView contained in a separate UIView. Add constraints to all sides to pin the container view and image view to the edges. This ensures the image fills the screen for portrait and landscape automatically.
I have the following method to set the background for a given orientation. It relies on a factory class to load the appropriate image. Loading backgrounds requires more effort than normal images as size class does not tell you anything about the aspect ratio. Replace the MyImageFactory
with whatever code you use to load the appropriate image.
- (void) setBackgroundImage:(UIInterfaceOrientation) orientation{
if (orientation == UIInterfaceOrientationLandscapeLeft ||
orientation == UIInterfaceOrientationLandscapeRight)
{
NSLog(@"Setting background to landscape");
[self.backgroundImageView setImage:[MyImageFactory backgroundImageLandscape]];
}
else{
NSLog(@"Setting background to Portrait");
[self.backgroundImageView setImage:[MyImageFactory backgroundImage]];
}
}
Call the background setting method in viewWillAppear
to initialise the background to the startup orientation as follows:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Set the background image
[self setBackgroundImage:self.interfaceOrientation];
}
Finally to deal with rotation, override the rotation method as follows:
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[self setBackgroundImage:toInterfaceOrientation];
// Do anything else which is rotation specific.
}
Works well on iOS7 to iOS9.
Upvotes: 0
Reputation: 1003
You need to do simple 2 steps 1.) Choose size class any,any it will run on both portrait and landscape mode for all devices both for ipad and iphone.
2.) Use autolayout and set constraint as shown in screenshot
It will work fine.Thanks
Upvotes: -1