0

I am building an app that displays an image in landscape and portrait modes. Rotating works perfectly. The image is also perfectly positioned in landscape mode. However it keeps its landscape coordinates in portrait, which misplace it as a result. Please find my code below. Could you let me know what I'm missing? Is there also a way to achieve this strictly from a Xib file?

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[self navigationController] setNavigationBarHidden:YES animated:NO];

UIImage *startImage = [UIImage imageNamed:@"title.png"];
UIImageView *startImageView = [[UIImageView alloc] initWithImage:startImage];

if (curOrientation == UIInterfaceOrientationPortrait || curOrientation == UIInterfaceOrientationPortraitUpsideDown) {

    [startImageView setFrame:CGRectMake(-128, 0, 1024, 1024)];

}else{

    [startImageView setFrame:CGRectMake(0, -128, 1024, 1024)];

}

[self.view addSubview:startImageView];


}
Armand
  • 435
  • 1
  • 11
  • 23

1 Answers1

3

Currently you are only calling this code when the view is first loaded. You actually need to call it

  • whenever the view appears onscreen (in case the device was rotated while it was offscreen)
  • whenever the device is rotated

but you should keep the view creation code in viewDidLoad, as you only want to create it once.

Make a property to keep a pointer to the view so that you can refer to it from all of these places in your code…

@property (nonatomic, weak) UIImageView* startImageView;

Create it in viewDidLoad (but don't worry then about the geometry, as you can do this in viewWillAppear):

- (void)viewDidLoad
{
    [super viewDidLoad];
        // Do any additional setup after loading the view.
    [[self navigationController] setNavigationBarHidden:YES animated:NO];
    UIImage *startImage = [UIImage imageNamed:@"title.png"];
    UIImageView *startImageView = [[UIImageView alloc] initWithImage:startImage];
    self.startImageView = startImageView;
    [self.view addSubview:startImageView];
}

Make a generic orientation method:

- (void) orientStartImageView
    {
        UIInterfaceOrientation curOrientation = [UIApplication sharedApplication].statusBarOrientation;
        if (curOrientation == UIInterfaceOrientationPortrait || curOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            [self.startImageView setFrame:CGRectMake(-128, 0, 1200, 1200)];
        }else{
            [self.startImageView setFrame:CGRectMake(0, -128, 1200, 1200)];
        }
    }

Call it from viewWillAppear (triggered every time the view comes onscreen):

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self orientStartImageView];
}

Call it from viewWillLayoutSubviews (triggered every time the view IS onscreen and the device rotates):

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self orientStartImageView];
}

By the way, I am not sure your frames are correct - in portrait you are shifting the left edge offscreen, in landscape you are shifting the top edge offscreen. Is that what you want? It may well be that you can achieve what you want in Interface Builder, but it is not clear from your code what that is - maybe you could post a picture. Also check that you have Autolayout disabled (checkbox in Interface Builder's file inspector) to simplify issues.

update

You may be able to do this from the Xib with no code: centre the imageView in it's superView, set it's size to your final size (eg 1200x1200), disable Autolayout, deselect all springs and struts, set your View Mode appropriately (eg center or scaleToFill)

enter image description here

enter image description here

enter image description here

foundry
  • 31,615
  • 9
  • 90
  • 125
  • thanks a lot. It works perfectly! Now about the edges offscreen this is exactly what I want. Let me explain: I'm displaying images that I want to look the same portrait or landscape. No resizing needed even though some part will be cut. The idea is to have all the important elements of an image at the center of the screen and less important ones at edges. The centered elements will be displayed no matter the mode. And we couldn't care less about the different left out elements... e.g Joe Blow on Kobe Bryant's dunk pic. Unless you're Joe Blow :-) Now how doing it from the Xib? – Armand Feb 18 '13 at 00:57
  • Thanks @He Was. I'll give it a try. I'll also need to add buttons. I'm wondering if it's possible to combine approaches? Like position some elements through the Xib and others programmatically. For instance let's say I want to place some buttons on your view above. Could I program the view and then position the buttons in the Xib. Wouldn't the image cover them? Excuse my lack of knowledge at this level :-) – Armand Feb 18 '13 at 14:25
  • @Armand, yes you can mix and match. Try it out and start a new question if you get stuck (try to make your question quite specific to your problem). Some of the pros will tell you that everything should be done in code, but as you are starting out I would recommend the opposite, do as much as you can in the Xib (or Storyboard). Use code when the Xib (with autosizing masks) won't organise things for you. But don't use the new autolayout feature, it can easily confuse. – foundry Feb 18 '13 at 14:35