2015-02-20 16 views
5

Tôi biết rằng điều này trông giống như một câu hỏi rất lớn nhưng nó không phải như vậy don 'sợ để đọc nó. Chủ yếu là tôi giải thích cách thức hoạt động của các công cụ.UIWindow vấn đề định hướng (hai UIWindows và chế độ phong cảnh)

Tôi có hai UIWindow giây trong ứng dụng của mình. Người đầu tiên là cửa sổ chính được tạo bởi ứng dụng theo mặc định. Cái thứ hai được gọi là modalWindow và cũng được tạo trong ứng dụng đại biểu.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Override point for customization after application launch. 


    self.modalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.modalWindow.windowLevel = UIWindowLevelStatusBar; 

    //Other stuff I need 
    //.... 

    return YES; 
} 

Hầu hết ứng dụng của tôi chỉ có ở chân dung nhưng có một bộ điều khiển chế độ xem nơi người dùng có thể chuyển sang hướng ngang. Tôi đang nghe thay đổi cảnh quan qua:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

Phương pháp này hoạt động tốt và trong phương pháp orientationChanged Tôi trình bày bộ điều khiển chế độ xem ngang. Tất cả là tốt vào thời điểm này. Nếu tôi quay trở lại chân dung tôi nhận được orientationChanged bắn một lần nữa tại thời điểm đó tôi loại bỏ bộ điều khiển chế độ xem ngang.

Bây giờ, hãy giải thích cách cửa sổ thứ hai được phát. Khi ở chế độ ngang, có một thao tác (chỉ cần nhấn nút) hiển thị bộ điều khiển chế độ xem mới trên cửa sổ thứ hai (modalWindow). Ok hãy giải thích điều này.

Các đại biểu ứng dụng có hai phương pháp mà trông giống như vậy:

- (void)presentActivityOnModalWindow:(UIViewController *)viewController 
{ 
    self.modalWindow.rootViewController = viewController; 
    self.modalWindow.hidden = NO; 
} 

- (void)modalTransitionFinished:(NSNotification *)notif 
{ 
    self.modalWindow.hidden = YES; 
    self.modalWindow.rootViewController = nil; 
} 

tôi gọi là presentActivityOnModalWindow qua [[[UIApplication sharedApplication] delegate] performSelector....]. Tôi biết nó không phải là thực hành tốt nhất nhưng nó hoạt động tốt. Đối với việc sa thải tôi sử dụng NSNotificationCenter để đăng thông báo về việc sa thải. Bộ điều khiển xem được hiển thị trên modalWindow chỉ hỗ trợ chế độ dọc. Nó quay trở lại YES trong shouldAutorotateUIInterfaceOrientationMaskPortrait trong supportedInterfaceOrientations.

Ok rất nhiều giải thích nhưng bây giờ chúng tôi gặp phải sự cố. Khi tôi xoay để cảnh quan, bật lên các modalWindow, bỏ qua cửa sổ phương thức và xoay trở lại chân dung cửa sổ chính của tôi vẫn còn trong chế độ phong cảnh và tất cả mọi thứ trông thảm khốc.

Tôi đã thử thêm một người quan sát cho cả windowmodalWindow và khai thác gỗ thay đổi trong framebounds và đây là kết quả:

Did finish launching: 
window frame {{0, 0}, {320, 568}} 
window bounds {{0, 0}, {320, 568}} 
modalWindow frame {{0, 0}, {320, 568}} 
modalWindow bounds {{0, 0}, {320, 568}} 

Rotate to landscape: 
window frame {{0, 0}, {568, 320}} 

Open activity in landscape: 
modalWindow frame {{0, 0}, {320, 568}} 
modalWindow frame {{0, 0}, {320, 568}} 

Dismiss activity: 
none 


Rotate back to portrait: 
none 

Vì vậy, có vẻ như tôi window không lấy lại cho khung bình thường khi chúng tôi nhận quay lại chế độ dọc. Cách sửa lỗi này? Nếu tôi cần cung cấp thêm bất kỳ chi tiết nào, hãy hỏi.

Trả lời

1

Hệ thống sẽ chỉ xử lý xoay vòng keyWindow của bạn. Nếu bạn có các cửa sổ khác, bạn sẽ phải tự xoay vòng.

Tôi cũng nghĩ rằng bộ điều khiển phương thức là cách để thực hiện. Nhưng nếu bạn thực sự muốn xử lý các phép quay, hãy xem các thư viện "cửa sổ tùy chỉnh" khác xoay vòng như thế nào. quan điểm Alert là một ví dụ tuyệt vời:

https://github.com/search?o=desc&q=uialertview&s=stars&type=Repositories&utf8=

-1

Bạn đang tạo 2 cửa sổ và Apple khuyên bạn nên chống lại điều này. Một ứng dụng sẽ thực sự có nhiều cửa sổ như có các thiết bị hiển thị. (SEE UIWindow reference)

Tôi khuyên bạn nên sử dụng 2 chế độ xem và "vẽ" mọi thứ lên các chế độ xem đó theo hướng. Sau đó, ẩn một chế độ xem, khi chế độ xem khác được hiển thị.

Hoặc bạn chỉ có thể sử dụng 1 chế độ xem và thực hiện điều chỉnh tại thời điểm thay đổi định hướng. Sự dễ dàng làm điều này phụ thuộc vào loại thông tin được hiển thị. Thay đổi định hướng được phát hiện tốt nhất bằng mã AppDelegate.

Đây là mẫu mã tôi sử dụng để phát hiện thay đổi định hướng và sau đó kiểm tra kích thước mới của cửa sổ.

- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation 
{ 

    //other stuff from rotate: 
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 

    CGRect appFrame = [[UIScreen mainScreen ]applicationFrame];//using frame so status bar is not part of calculations. 

    if (orientation == UIInterfaceOrientationLandscapeRight 
     || 
     orientation == UIInterfaceOrientationLandscapeLeft 
     ) 
    { 
     self.currentAppScreenWidth = appFrame.size.height; 
     self.currentAppScreenHeight = appFrame.size.width; 
     [YOURapp reArrangeSubViews_and_Layouts: appFrame];//Something like this - maybe. 
    } 
    else 
    { 
     self.currentAppScreenWidth = appFrame.size.width; 
     self.currentAppScreenHeight = appFrame.size.height; 
     [YOURapp reArrangeSubViews_and_Layouts: appFrame];//Something like this - maybe. 

    } 
} 

Hy vọng điều đó sẽ hữu ích. Một điều khác. Nếu bạn đang hiển thị cùng một thông tin với bố cục khác, thì bạn có thể đặt nó ra bằng cách sử dụng các công cụ Xcode, để thích ứng với định hướng theo cách phù hợp. Nếu một số thứ vẫn chưa hoàn hảo, hãy thử tinh chỉnh bằng mã. Nếu bạn đang hiển thị thông tin hoàn toàn khác, cách tiếp cận 2 lượt xem có thể là cách dễ nhất.

[Có thể một số thông tin khác về sự khác biệt trong dữ liệu được hiển thị trên 2 màn hình, nếu giải pháp trên không có hiệu quả với bạn. Chúc mừng.]

0

Apple không khuyến khích sử dụng các cửa sổ theo cách này. Nó có lẽ là tốt nhất để sử dụng một UIViewController hiển thị modally thay cho bạn

self.modalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 

Trình bày một modally UIViewController được thực hiện từ một thể hiện UIViewController sử dụng

[self presentViewController:<#(UIViewController *)#> animated:<#(BOOL)#> completion:<#^(void)completion#>] 
Các vấn đề liên quan