2012-01-08 65 views
27

爲了在所有視圖之上製作UIView,例如UIAlertView的行爲,我所看到的最佳方式是將其放入應用程序窗口中,即通過添加查看到:查看所有內容:UIWindow子視圖VS UIViewController子視圖

[[[UIApplication sharedApplication] delegate] window] 

但是,我發現的缺點是它不會自動輪換。爲了進行輪換,最好的方法是在當前的AppDelegate上添加視圖,但是,通過這樣做,它將不再是最重要的。比方說,當視圖顯示,並有一個modalViewController彈出,模態視圖肯定會掩蓋視圖。

我的問題是,是否有可能將子視圖添加到最頂端的窗口支持方向?在這種情況下,我需要兩套Nib文件嗎? UIAlertView如何結合最頂級的&方向支持?當我看着UIAlertView.h,我看到實際上有2 UIWindows,一次被稱爲originalWindow,另一個被稱爲dimWindow。有沒有一個地方可以找到UIAlertView.m的源代碼?

回答

4

只有UIWindow的第一個子視圖纔會被告知方位變化。 (< iOS8上)

你提的問題非常相似,這一個:

Multiple views in a UIWindow

由於有說,你可以爲取向的改變通知註冊和處理您的重新佈局「頂部」子視圖的答案那樣。

+1

如何將視圖註冊到設備以接收旋轉事件?它不是視圖控制器,所以沒有代理功能。我是否必須趕上UIDeviceOrientationDidChangeNotification以更改爲相應的方向? – 2012-01-08 02:53:18

2

這是一個可能的解決方案,我在幾個步驟中解釋。

  1. 開始與UIViewController繼承類,而不是UIView,比方說,類命名爲UIViewController
  2. 繼承既然你不能註冊設備/界面旋轉的UIView繼承類TopViewController,這是從UIViewController繼承TopViewController類有方法響應視圖旋轉事件。旋轉事件現在可以被捕獲。
  3. 最後,您可以使用與您在問題中提到的方法相同的方法,將TopViewController視圖置於UIWindow的頂部。

    [[[[UIApplication sharedApplication] delegate] window] addSubview:(TopViewController object).view]; 
    

希望這有助於。

+0

UIViewController的視圖屬性也不會旋轉。不幸。 https://developer.apple.com/library/ios/qa/qa1688/_index.html – khunshan 2014-08-12 13:25:23

15

我找到的最佳解決方案是創建一個透明的容器視圖,將該容器添加到窗口,並將您的警報放入容器中。然後您可以註冊UIApplicationWillChangeStatusBarOrientationNotification以接收輪換事件並轉換容器;這使您可以獨立操作警報的框架:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    ... 
    self.container = [[UIView alloc] initWithFrame:self.window.bounds]; 
    [self.container addSubview:self.alertView]; 
    [self.window addSubview:self.container]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(statusBarWillRotate:) 
                name:UIApplicationWillChangeStatusBarOrientationNotification 
               object:nil]; 
    ... 
} 
... 
- (void)statusBarWillRotate:(NSNotification *)theNotification 
{ 
    CGFloat rotation = 0; 
    switch ([notification[UIApplicationStatusBarOrientationUserInfoKey] intValue]) 
    { 
     case UIInterfaceOrientationLandscapeLeft: 
      rotation = -M_PI_2; 
      break; 
     case UIInterfaceOrientationLandscapeRight: 
      rotation = M_PI_2; 
      break; 
     case UIInterfaceOrientationPortraitUpsideDown: 
      rotation = M_PI; 
      break; 
     case UIInterfaceOrientationPortrait: 
     default: 
      rotation = 0; 
      break; 
    } 
    CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(rotation); 
    CGSize rotatedSize = CGRectApplyAffineTransform(self.window.bounds, rotationTransform).size; 
    [UIView animationWithDuration:[UIApplication sharedApplication].statusBarOrientationAnimationDuration 
         animations:^{ 
     self.container.transform = rotationTransform; 
     // Transform invalidates the frame, so use bounds/center 
     self.container.bounds = CGRectMake(0, 0, rotatedSize.width, rotatedSize.height); 
     self.container.center = CGPointMake(self.window.bounds.size.width/2, self.window.bounds.size.height/2); 
    }]; 
} 

你可以,如果你真的想,與其windowLevel屬性設置爲UIWindowLevelAlert創建一個全新的窗口,這將保證窗口保持在高於所有其他包括鍵盤在內的視圖,但窗口管理變得棘手。上述解決方案應滿足大多數需求。

與簡單地增加一個視圖控制器的視圖到一個窗口的問題是,它不能保證接收所有旋轉和view[Will|Did][Disa|A]ppear:消息,除非它是通過addChildViewController:添加到視圖控制器層次根視圖控制器上。

+0

我有這個解決方案的問題。我無法在最頂端的容器視圖中註冊觸摸。例如,UIButtons不起作用。 – asendra 2014-12-01 18:52:23

+0

@asendra聽起來像你的窗口不是關鍵窗口,但你可能想發佈你自己的問題更多的細節。 – Austin 2014-12-01 18:57:38

相關問題