3

I have a subview with (in addition to other standard Cocoa Touch controls) 6 buttons and labels inside of it.

enter image description here

I'm rotating & resizing these buttons and labels on the rotation event with this messy code.

- (void) updateLayoutForNewOrientation: (UIInterfaceOrientation) orientation {
    if (UIInterfaceOrientationIsPortrait(orientation)) {
        button1.frame = CGRectMake(20, 59, 130, 80);
        button2.frame = CGRectMake(170, 59, 130, 80);
        button3.frame = CGRectMake(20, 176, 130, 80);
        button4.frame = CGRectMake(170, 176, 130, 80);
        button5.frame = CGRectMake(20, 293, 130, 80);
        button6.frame = CGRectMake(170, 293, 130, 80);

        label1.frame  = CGRectMake(20, 147, 130, 21);
        label2.frame  = CGRectMake(170, 147, 130, 21);
        label3.frame  = CGRectMake(20, 264, 130, 21);
        label4.frame  = CGRectMake(170, 264, 130, 21);
        label5.frame  = CGRectMake(20, 381, 130, 21);
        label6.frame  = CGRectMake(170, 381, 130, 21);
    } else {
        button1.frame = CGRectMake(20, 59, 130, 60);
        button2.frame = CGRectMake(20, 155, 130, 60);
        button3.frame = CGRectMake(177, 59, 130, 60);
        button4.frame = CGRectMake(177, 155, 130, 60);
        button5.frame = CGRectMake(328, 59, 130, 60);
        button6.frame = CGRectMake(328, 155, 130, 60);

        label1.frame  = CGRectMake(20, 127, 130, 21);
        label2.frame  = CGRectMake(20, 223, 130, 21);
        label3.frame  = CGRectMake(177, 127, 130, 21);
        label4.frame  = CGRectMake(177, 223, 130, 21);
        label5.frame  = CGRectMake(328, 127, 130, 21);
        label6.frame  = CGRectMake(328, 223, 130, 21);
    }
}

That's a bit messy, but works fine and I have a precise control of element position in the view.

enter image description here

By the way I'm wondering if having two different views and flipping them on rotation is more efficient regarding "cpu power" and memory consumption (I think that having a single view instead of two is better for memory, but I could be wrong, I'm pretty new to ios programming).

Thanks for any suggestion!

napolux
  • 15,574
  • 9
  • 51
  • 70

2 Answers2

2

Right now I am working on a similar code what you wrote. The project it is very big, hard to follow what where to modify. It was written for iOS 3 and now the client needed a few modification. It wouldn't so big the problem, if the iOS wouldn't change the pushModal and would be deprecated in iOS6... In my case needed to rewrite the GUI skeleton, and I had Portait / Landscape requirements. Check a few links if you would like it: question1 question2 question3 question4

For a not previsible iOS change it will be to hard to overview that code, especially after 2 year. I wouldn't repeat that programmer mistake who has worked before.

In your case that is my I would choose from different solutions ( but this for sure not) :

Solution 1: Create different xib for landscape and portait. Has the advantage of the modularity: later if you don't need Landscape for various reason it is easy to unlink from your code. Has the disadvantage of creating a new view ( well it can be cached) but still different objects and need synchronizations of data, between model-View2-controller.

Solution2: use only 1 xib file and layout automatically the components by setting up they properties at size inspector ( 5th tab ). Very hard to configure

Solution3: inside that xib file create component-landscape and layout those components to mach the expected design, size, and at Runtime read they size and set it, as you so now, but that can be edited visually.

Storyboard or xib, it is almost the same for me, there can be 2 UIViewController and pop / push the Portait/Landscape to not fill the stack with rotations :)

Speed ofc it is the best if you don't rotate at all, but if you still want, maybe the 2 component in 1 xib, because not need to change the visibility 2-4 times, wich will trigger a lot od function calls: viewwillappear, wiewdidapear, viewwilldisapers and so on.

Community
  • 1
  • 1
2

You ask:

By the way I'm wondering if having two different views and flipping them on rotation is more efficient regarding "cpu power" and memory consumption ...

I believe that the opposite is true. It's far more efficient to have a single view for which you simply invoke your method from viewWillLayoutSubviews (in iOS 5, in iOS 4 I generally use willAnimateRotationToInterfaceOrientation). The efficiency gain is modest, but if efficiency is your goal, I think a single view is the way to go. You might want to use the separate views if they're radically different and thus your code would become hard to manage with a single view, but otherwise I stick with one view. Personally, I also think it's a stronger user interface to have the controls animate into place as you rotate the device.

Personally, when I have content that reorganizes on orientation changes like this, I try to refrain from using hard coded coordinates, but rather use the dimensions of the view to algorithmically determine the the layout of my controls (e.g. how many per row) and from there, determine their coordinates. This way, it takes care of not only landscape versus portrait, but also makes Universal apps (especially if there's ever other devices with different screen sizes in the future) easier, too. I think we can also look forward to iOS 6 also offering some nice enhancements to laying out controls (though it will be a while before we will feel comfortable developing apps that require iOS 6).

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks for your answer! I believe that the single view approach is better, I need to optimize my code in order to be more readable and more like a real code :P – napolux Sep 08 '12 at 20:50