0

I have a few buttons on my View and when the app starts they should flip around their x-axis. When I start the app from Xcode (Build and then run the current scheme) they flip, but when I open the app on my iPhone they don't flip.

My viewDidLoad in my ViewController looks like this:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    model =[[Model alloc] init];
    GameView *gameView = [[GameView alloc] initWithTiles];
    gameView.controller = self;
    self.view = gameView;

    [self flipButtons];
}

Why don't the buttons flip when I start the app from my phone?

If you need additional information just let me know :)

Edit

This is the method that flips the button and gets called for each button:

- (void)flip:(Color*)color {

int flipDirection = arc4random() % 2;
if(flipDirection == 0) flipDirection = -1;

double duration = 200 + arc4random() % (500 - 200);
duration = duration / 1000;


// Animation
[UIView animateWithDuration:duration
                      delay:0.0
                    options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
                 animations:^{
                     self.layer.transform = CATransform3DMakeRotation(M_PI, 0, flipDirection, 0);
                     // wait duration /2 and call changeColor
                     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((duration / 2) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                         [self changeColor:color];
                     });
                 }
                 completion:^(BOOL finished) {
                     self.layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 0);
                 }];

}

Dalibor
  • 153
  • 2
  • 13
  • You telling that your buttons flipping in simulator, but not in device? – Kathiravan G Nov 20 '15 at 13:30
  • @Kathiravan No they're flipping on my device but only if I start the app from Xcode. – Dalibor Nov 20 '15 at 13:31
  • Have NSlog on your flipbuttons method. Start your application in device and check the device console in Xcode, check whether your method called or not. – Kathiravan G Nov 20 '15 at 13:37
  • `dispatch_after` should be in the completion block. – Tamás Zahola Nov 20 '15 at 13:42
  • @TamásZahola May I ask why? – Dalibor Nov 20 '15 at 13:45
  • @Dalibor Yes. `UIView animateWithDuration...` provides no guarantee when or how many times will it call it's `animations:` block. However the `completion:` block is guaranteed to be called exactly once, after the animation has finished. – Tamás Zahola Nov 20 '15 at 13:48
  • @Dalibor please take a look at the accepted answer here: http://stackoverflow.com/questions/5948167/uiview-animatewithduration-doesnt-animate-cornerradius-variation It says you shouldn't use `UIView animateWithDuration` with the `layer`s properties. In that case you should use CoreAnimation directly. – Tamás Zahola Nov 20 '15 at 16:03

1 Answers1

2

viewDidLoad doesn't necessarily mean that the view is on-screen. You should be using viewWillAppear: or viewDidAppear:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    model =[[Model alloc] init];
    GameView *gameView = [[GameView alloc] initWithTiles];
    gameView.controller = self;
    self.view = gameView;
}

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated];
    [self flipButtons];
}

viewDidLoad only signifies that the view controller's view has been instantiated and by that point all IBOutlets have been wired up. You should only do additional initialization here, and must not rely on when viewDidLoad was called or whether it was called multiple times, etc (e.g. you can unload your view controller's view with self.view = nil if it doesn't have a superview, and it'll be automatically reloaded when it's needed).

Why this is necessary: UIViewController loads it's view lazily. When you instantiate a UIViewController with e.g initWithNibName:bundle: it won't load the nib right away; that would be a waste of resources. According to Apple's documentation:

The nib file you specify is not loaded right away. It is loaded the first time the view controller's view is accessed. If you want to perform additional initialization after the nib file is loaded, override the viewDidLoad method and perform your tasks there.

So what happens is, when the view controller's view is queried the first time, loading takes place (see: Order of UIViewController initialization and loading ) and the viewDidLoad call is issued so that you can make adjustments to the view with all the subviews and IBOutlets set up.

Once the view is loaded, the view controller's state transitions are described in this diagram:

enter image description here

The initial state is disappeared.

Community
  • 1
  • 1
Tamás Zahola
  • 9,271
  • 4
  • 34
  • 46
  • 1
    Then please provide us with the implementation of your `flipButtons` method. – Tamás Zahola Nov 20 '15 at 13:36
  • I'm sorry to annoy you but I still don't really know what to do now? – Dalibor Nov 20 '15 at 15:17
  • I found out that it runs the flip method because it changes the button color but somehow doesn't do the animation. – Dalibor Nov 20 '15 at 15:42
  • @Dalibor The button color surely won't be animated, because it's not set in the animation block. You're only _scheduling_ the color changing block in the animation block. You should do that as a separate animation with `duration/2` delay. – Tamás Zahola Nov 20 '15 at 16:01