Orientation Notification Outside ViewController

Discussion in 'iOS Programming' started by kingsapo, Jun 5, 2012.

  1. kingsapo macrumors member

    Joined:
    Jun 10, 2010
    #1
    Hey all! So basically I'm creating a custom UIButton, done so by creating a subclass of UIButton. Everything on the appearance side works great, except orientation changes. Normally, I pass two sets of CGRects to my custom button; one for portrait dimensions, and one for landscape. When the device changes orientation, I would like my button to change its frame to the portrait or landscape dimensions, depending on the orientation. My issue is getting my subclass to recognize orientation changes. Here's what I have tried:

    In my custom button class's init method, among other button-related things, I have:

    Code:
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
    Then in my receivedRotate:

    Code:
    - (void)receivedRotate:(NSNotification *)notification {
        NSLog(@"yep, the orientation changed");
    }
    What's kind of interesting in all this is that on the simulator, it actually sometimes works. Most of the time, though, it gives me either of these in the output:

    or

    Both of these also give me the error "Thread 1: signal SIGABRT" at the line "return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));" in my main.m.

    The fact that it sometimes works is new for me, though I think it may be related to the rendering that I have going on in the background. Maybe the other program taking up the CPU from my MacBook is somehow helping the simulator? I have no idea.

    What's even weirder is that this only works around 1 in 6 times if I also have these methods included in my subclass:

    Code:
    - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation) toInterfaceOrientation:(NSTimeInterval)duration {
        NSLog(@"changed");
    }
    Code:
    - (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame {
        NSLog(@"changed");
    }
    Code:
    - (void)orientationChanged:(NSNotification *)notification {
        
    }
    
    When I take these methods out, it never works. When I put them back, it sometimes works. They really should be irrelevant, because as far as I know, they aren't being used anywhere else by my subclass.

    Please, if anyone has any ideas, it is always appreciated. Even if you don't know the answer directly, but know some other source that may (which is unlikely, since I've scoured the net before this post), please point me in that direction, otherwise I may actually go insane working on this subclass.

    Please, if anyone has any ideas, they are always appreciated. I may actually go insane if I never figure this out and really need to finish this subclass, so any help is greatly appreciated. Thank you.
     
  2. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #2
    Don't try to do this in the button, do it in the view controller.

    Your viewcontroller will keep track of the orientation and it normally doesn't miss a beat so remove all the orientation code from your button class and stick it into one of the methods in your viewcontroller that are called as part of the rotation. Which one will depend on when in the rotation you want to do stuff to your subviews.
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    If you like, have a setOrientation method in your button. Let it update itself when the orientation is set. Call this from your view controller, most likely in layoutSubviews.
     
  4. kingsapo thread starter macrumors member

    Joined:
    Jun 10, 2010
    #4
    Thanks for the responses, guys! I understand that I can do this from the ViewController, but I really wanted to get away from that. My goal is to create a nice self-contained class that can handle orientation changes without relying on the ViewController. The reason being is that I will be creating multiple custom keyboards with multiple buttons, so to have to manually manage each from the ViewController would be daunting. And yes, I know I could have some sort of loop to loop through all of them for me, but I really wanted to get away from this. Like I said in my original post, my code in my UIButton subclass does sometimes work, I just have a feeling that something is not being loaded before I create the notification. If anyone has any ideas for orientation notifications outside the ViewController, or why my posted code sometimes works, I'd love to hear them!
     
  5. kingsapo thread starter macrumors member

    Joined:
    Jun 10, 2010
    #5
    Just an update that I was able to use a workaround by overriding the -layoutSubviews method in my subclass. That method gets called whenever my subviews are re-laid out, which happens during an orientation change. There, I did my orientation check, and changed my button's frame to an appropriate value.

    PhoneyDeveloper I just realized you suggested using layoutSubviews, so thanks for that! I guess I should have listened to you from the beginning. :)

    Thanks again for your help everybody!
     

Share This Page