UIAppearance 変更時、リアルタイムに画面反映する

UIAppearance の proxy メソッドから見た目を変更して、即時全画面に適用する方法を調べていて、UISS という iOS で JSON 形式の Stylesheet を扱うライブラリにその答えがあったので、メモです。

UISS#refreshViews

- (void)refreshViews {
    [[NSNotificationCenter defaultCenter] postNotificationName:UISSWillRefreshViewsNotification object:self];

    for (UIWindow *window in [UIApplication sharedApplication].windows) {
        for (UIView *view in window.subviews) {
            [view removeFromSuperview];
            [window addSubview:view];
        }
    }

    [[NSNotificationCenter defaultCenter] postNotificationName:UISSDidRefreshViewsNotification object:self];
}

window の子ビューを全て剥がして貼り直しています。

setNeedsDisplay, setNeedsLayout も試してみましたが、動かなかったので、こちらを採用します。

Swift で書くとこんな感じです。

public func resetViews() {
  let windows = UIApplication.sharedApplication().windows as [UIWindow]
  for window in windows {
    let subviews = window.subviews as [UIView]
    for v in subviews {
      v.removeFromSuperview()
      window.addSubview(v)
    }
  }
}