Изменить цвет фона UIWindow при вращении устройства

Мой UIWindow изначально имеет белый фон. Я хочу изменить фон на синий (постоянно), когда устройство вращается. Но на самом деле происходит то, что цвет ненадолго мигает синим, а затем снова становится белым.

В делегате приложения:

- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
{
    self.window.backgroundColor = [UIColor blueColor];
}

Этот код вызывается, как и ожидалось, но когда ротация завершается, -[UIWindow setBackgroundColor:] вызывается во второй раз (как я обнаружил, создав подкласс UIWindow). Стек вызовов для второго вызова:

-[UIWindow setBackgroundColor]
-[UIWindow _finishedFullRotation:finished:context:]
-[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
-[UIViewAnimationState animationDidStop:finished:]
-run_animation_callbacks
...

Изменить (для ответа @VinceBurn)

Приложение имеет ровно одно представление (из шаблона проекта приложения на основе представления Xcode). Теперь я установил цвет фона представления (в IB) на 0% непрозрачности. Все еще получаю те же результаты.

Чтобы убедиться, что белый цвет не исходит от какой-либо другой настройки цвета по умолчанию, я сначала устанавливаю цвет фона окна на зеленый:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    self.window.backgroundColor = [UIColor greenColor];
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    return YES;
}

Когда он вращается, он ненадолго мигает синим цветом, но снова становится зеленым.


person jlstrecker    schedule 06.12.2011    source источник
comment
Где и как изначально установить белый фон?   -  person Vincent Bernier    schedule 06.12.2011
comment
@VinceBurn - я пытался нигде не устанавливать его (белый цвет по умолчанию) и пытался установить его в -application:didFinishLaunchingWithOptions:. Одинаковые результаты в любом случае.   -  person jlstrecker    schedule 06.12.2011
comment
@jlstrecker: Извините, это было немного быстро и глупо - пожалуйста, забудьте об этом. Немного похоже на баг. Я только что наткнулся на UIView animateWithDuration:animations. Я не работал с этим, но, возможно, его можно реализовать таким образом, чтобы обойти второй вызов.   -  person Kay    schedule 06.12.2011


Ответы (2)


В итоге я изменил цвет фона активного представления UIViewController вместо UIWindow:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    self.view.backgroundColor = [UIColor blueColor];
}

Причина, по которой я пытался установить цвет фона UIWindow, заключалась в том, чтобы получить одинаковый цвет фона во всем приложении. По-видимому, самый простой способ добиться этого — наследовать все UIViewController в приложении от подкласса UIViewController, который реализует -didRotateFromInterfaceOrientation:.

person jlstrecker    schedule 09.12.2011

Этот код немного лучше, но я все еще надеюсь на что-то другое.

- (void)changeColor 
{
  self.window.backgroundColor = [UIColor orangeColor];
}
- (void)application:(UIApplication *)application 
willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation 
                      duration:(NSTimeInterval)duration
{
  //  At first set it to the color
  self.window.backgroundColor = [UIColor orangeColor];
  // And make it change again when the animation is finished
  [self performSelector:@selector(changeColor) 
             withObject:self 
             afterDelay:duration + 0.005];
      //  You may have to play with the add part of the duration this was working 
          in the simulator, but on device?
}

Я предполагаю, что под капотом ориентация изменяется через CAAnimation, а новое свойство, установленное в CAAnimation, не сохраняется в конце, поэтому вам нужно установить их также вне анимации.

person Vincent Bernier    schedule 06.12.2011
comment
@jlstrecker Это было так интригующе, что я попробовал. И я не могу это исправить. Я пытаюсь зарегистрироваться в NSNotification для изменения ориентации, в документации говорится, что он вызывается позже, чем делегат приложения. Но все тот же результат... - person Vincent Bernier; 07.12.2011
comment
Попробовал ваше решение на нескольких устройствах (с немного измененным приложением, которое становится зеленым для портретной ориентации и синим для альбомной ориентации). Время добавления к duration для устройств больше похоже на 0,2 или 0,25. Как оказалось, идеальное время зависит не только от устройства, но и от направления, в котором вы вращаетесь (в альбомную или портретную), и от того, сколько раз вы вращались раньше! Если время слишком короткое, цвет не меняется, а если слишком длинное, цвет мерцает после вращения. Я собираюсь попробовать другие обходные пути, и если я в конечном итоге использую ваш, я отмечу его как ответ. - person jlstrecker; 09.12.2011
comment
@jlstrecker, если вы найдете лучшее решение, напишите небольшой комментарий, мне любопытно. Спасибо. Я не уверен, когда именно вам нужно изменить цвет, но я видел в документе, что его можно анимировать, поэтому, если вы увеличите время, вы можете запустить анимацию этого свойства после завершения поворота. .. но, вероятно, не тот эффект, который вы ищете. - person Vincent Bernier; 09.12.2011