2011-08-02 31 views
22

Tôi đã thấy một số câu hỏi tương tự về vấn đề này, nhưng không có câu hỏi nào đáp ứng nhu cầu cụ thể của tôi. Tôi muốn có thể viết một phương thức trợ giúp chung để trả về kích thước khung tối đa có thể sử dụng cho UIView, xem xét liệu ứng dụng có kết hợp thanh trạng thái, thanh điều hướng và/hoặc thanh tab hay không. thời gian.Lập trình xác định kích thước khung tối đa có thể sử dụng cho một UIView

định nghĩa phương pháp sẽ là một phần mở rộng của UIScreen:

+ (CGRect) maximumUsableFrame; 

Bắt kích thước có hoặc không có thanh trạng thái có thể được nhận được từ

[UIScreen mainScreen].applicationFrame

bất động sản, nhưng tôi không thể hình ra một cách để xác định nếu có một thanh điều hướng hoặc thanh tab hiện tại. Tôi đã nghĩ về việc duy trì một số cờ toàn cầu trong ủy nhiệm ứng dụng của tôi nhưng điều này có vẻ thực sự khó khăn và dừng mã là chung chung và có thể sử dụng lại được. Tôi cũng đã xem xét đi qua một UIView như một tham số, nhận được cửa sổ của khung nhìn, sau đó là rootViewController và sau đó nhìn thấy nếu tài sản điều khiển chuyển hướng được thiết lập. Nếu vậy thì kiểm tra xem bộ điều khiển điều hướng có bị ẩn hay không. Tất cả rất clunky nếu bạn hỏi tôi.

Bất kỳ suy nghĩ nào cũng sẽ được đánh giá cao.

Dave

EDIT: Kết hợp ý tưởng từ câu trả lời Caleb trong trường hợp này là sử dụng cho bất cứ ai khác:

// Extension to UIViewController to return the maxiumum usable frame size for a view 
@implementation UIViewController (SCLibrary) 

- (CGRect) maximumUsableFrame { 

    static CGFloat const kNavigationBarPortraitHeight = 44; 
    static CGFloat const kNavigationBarLandscapeHeight = 34; 
    static CGFloat const kToolBarHeight = 49; 

    // Start with the screen size minus the status bar if present 
    CGRect maxFrame = [UIScreen mainScreen].applicationFrame; 

    // If the orientation is landscape left or landscape right then swap the width and height 
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { 
     CGFloat temp = maxFrame.size.height; 
     maxFrame.size.height = maxFrame.size.width; 
     maxFrame.size.width = temp; 
    } 

    // Take into account if there is a navigation bar present and visible (note that if the NavigationBar may 
    // not be visible at this stage in the view controller's lifecycle. If the NavigationBar is shown/hidden 
    // in the loadView then this provides an accurate result. If the NavigationBar is shown/hidden using the 
    // navigationController:willShowViewController: delegate method then this will not be accurate until the 
    // viewDidAppear method is called. 
    if (self.navigationController) { 
     if (self.navigationController.navigationBarHidden == NO) { 

      // Depending upon the orientation reduce the height accordingly 
      if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { 
       maxFrame.size.height -= kNavigationBarLandscapeHeight; 
      } 
      else { 
       maxFrame.size.height -= kNavigationBarPortraitHeight; 
      } 
     } 
    } 

    // Take into account if there is a toolbar present and visible 
    if (self.tabBarController) { 
     if (!self.tabBarController.view.hidden) maxFrame.size.height -= kToolBarHeight; 
    } 
    return maxFrame; 
} 
+1

Nếu Navigationbar và TabBar có thể nhìn thấy, bạn có thể tìm thấy chiều cao theo cách này: 'self.navigationController.navigationBar.frame.size.height;' và 'self.tabBarController.tabBar.frame.size.height'. Tại sao biến cho chiều cao tabbar gọi là kToolBarHeight?=) – Alexander

+0

Tùy thuộc vào cách bạn muốn sử dụng điều này, ít nhất trong trường hợp của tôi, tôi cũng cập nhật nguồn gốc khung cho navController vì vậy tôi biết chính xác nơi tôi có thể định vị khung nhìn của tôi trong ViewController. Nếu không, bạn vẫn có thể kết thúc dưới thanh điều hướng. –

Trả lời

7

Tôi nghĩ rằng bạn đang đưa phương pháp của bạn tại địa điểm sai. UIScreen biết về màn hình, nhưng nó không (và không nên) biết bất cứ điều gì về những gì hiển thị trên màn hình. Đó là bộ điều khiển xem có trách nhiệm quản lý chế độ xem, vì vậy đó là nơi mà phương thức thuộc về. Hơn nữa, vì khung tối đa phụ thuộc vào cấu hình của một bộ điều khiển khung nhìn cụ thể, nên đây là một phương thức cá thể chứ không phải là một phương thức lớp. Tôi nghĩ bạn nên thêm một thể loại để UIViewController với phương pháp:

- (CGRect) maximumUsableFrame; 

Nó vẫn còn khá chung chung, dành cho tất cả các bộ điều khiển xem, nhưng đồng thời có quyền truy cập để xem thuộc tính điều khiển như navigationControllertabBarController.

+1

Cảm ơn các con trỏ tất cả các công cụ tốt và làm cho rất nhiều ý nghĩa. Sẽ viết phần mở rộng và cho bạn biết làm thế nào tôi nhận được trên. –

+2

Đã thêm một danh mục vào UIViewController và chỉnh sửa câu hỏi ban đầu của tôi để bao gồm mã và sẽ đánh giá cao suy nghĩ của bạn. Chúc mừng Dave. –

9

Sử dụng ứng dụngKhung. [[UIScreen mainScreen] applicationFrame]

Đây là cách tôi sử dụng nó để cắt các chất liệu trong ảnh chụp màn hình của tôi.

Dưới đây là một số mã mẫu.

-(UIImage*) crop20PointsifStatusBarShowsUp 
{ 
    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame]; //Look at this 
    float sizeOfStatusBarVar= applicationFrame.origin.y; 
    if ([BGMDApplicationsPointers statusBarShowUp]) 
    { 
     CGRect newSize = CGRectMake(0, sizeOfStatusBarVar, self.size.width, self.size.height-sizeOfStatusBarVar); 
     UIImage * newImage = [self cropUIImageWithCGRect:newSize]; 
     return newImage; 
    } 
    else{ 
     return [self copy]; 
    } 
} 
+0

Không biết tại sao đây không phải là câu trả lời hàng đầu. – Isak

0

Để làm việc này phải sử dụng giới hạn ứng dụng và chuyển hướng để tìm ra từ thanh trạng thái nào cần được loại bỏ. Đây là bản sao và tinh chỉnh của mã được đăng ban đầu. Tôi đã tạo một ứng dụng nhanh chạy thuật toán này thông qua các kết hợp có navbar/tabbar/none với thanh trạng thái và nó hoạt động trong tất cả các kịch bản.

- (CGRect) maxFrame 
{ 
    // Start with the screen size minus the status bar if present 
    CGRect maxFrame = [UIScreen mainScreen].applicationFrame; 

    // the glass screen size 
    CGRect maxBounds = [UIScreen mainScreen].bounds; 


NSLog(@"MaxFrame for %d: (%f, %f, %f, %f)", self.interfaceOrientation, maxFrame.origin.x, maxFrame.origin.y, maxFrame.size.width, maxFrame.size.height); 
NSLog(@"MaxBounds for %d: (%f, %f, %f, %f)", self.interfaceOrientation, maxBounds.origin.x, maxBounds.origin.y, maxBounds.size.width, maxBounds.size.height); 


    // figure out the offset of the status bar 
    CGFloat statusBarOffset; 
    switch (self.interfaceOrientation) { 
     case UIInterfaceOrientationPortrait: 
      statusBarOffset = maxFrame.origin.y; 
     break; 
     case UIInterfaceOrientationPortraitUpsideDown: 
      statusBarOffset = maxBounds.size.height - maxFrame.size.height; 
     break; 
     case UIInterfaceOrientationLandscapeRight: 
     case UIInterfaceOrientationLandscapeLeft: 
      statusBarOffset = maxBounds.size.width - maxFrame.size.width; 
     break; 
    } 

    // If the orientation is landscape left or landscape right then swap the width and height 
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { 
     CGFloat temp = maxBounds.size.height; 
     maxBounds.size.height = maxBounds.size.width; 
     maxBounds.size.width = temp; 
    } 

    // apply status bar to the top of the view 
    maxBounds.origin.y = statusBarOffset; 
    maxBounds.size.height -= statusBarOffset; 

    // Take into account if there is a navigation bar present and visible (note that if the NavigationBar may 
    // not be visible at this stage in the view controller's lifecycle. If the NavigationBar is shown/hidden 
    // in the loadView then this provides an accurate result. If the NavigationBar is shown/hidden using the 
    // navigationController:willShowViewController: delegate method then this will not be accurate until the 
    // viewDidAppear method is called) 
    if (self.navigationController && !self.navigationController.navigationBarHidden) { 
     NSLog(@"has nav bar"); 
     maxBounds.size.height -= self.navigationController.navigationBar.frame.size.height; 
     maxBounds.origin.y += self.navigationController.navigationBar.frame.size.height; 
    } 

    // Take into account if there is a toolbar present and visible 
    if (self.tabBarController && !self.tabBarController.view.hidden) { 
     maxBounds.size.height -= self.tabBarController.tabBar.frame.size.height; 
     NSLog(@"has tab bar"); 
    } 

NSLog(@"result for %d: (%f, %f, %f, %f)", self.interfaceOrientation, maxBounds.origin.x, maxBounds.origin.y, maxBounds.size.width, maxBounds.size.height); 
    return maxBounds; 
} 
+0

đã phải nhận xét maxBounds.origin.y = statusBarOffset; và maxBounds.origin.y + = self.navigationController.navigationBar.frame.size.height; trong một ứng dụng khác được sử dụng trong này. –

Các vấn đề liên quan