2011-07-29 24 views
6

Câu hỏi này đã được hỏi rất nhiều, ví dụ: here nhưng theo như tôi có thể thấy vẫn chưa được trả lời đầy đủ.UIModalTransitionStylePartialCurl với UITabBarController

Tôi có một số UITabBarController với số UINavigationController làm vc gốc cho một trong các tab, chính nó có số MKMapView làm vc gốc của nó. Các hành vi tôi muốn là cho bản đồ để curl một phần trở lên, trong khi rời khỏi thanh tab tại chỗ (tương tự như ứng dụng Bản đồ).

Cho đến giờ tất cả những gì tôi đã xoay xở để làm việc là cho toàn bộ chế độ cuộn tròn, điều này không đẹp.

Giải pháp tôi đã thấy là đặt thuộc tính hidesBottomBarWhenPushed thành NO, điều này sẽ có ý nghĩa nhưng điều này dường như không hoạt động, (trừ khi tôi đang làm điều gì đó sai).

Để rõ ràng, mã của tôi là như sau:

MyVC *aView = [MyVC init]; 
aView.modalTransitionStyle = UIModalTransitionStylePartialCurl; 
aView.hidesBottomBarWhenPushed = NO; 

Đối với phần trình bày, tôi đã cố gắng hai lựa chọn thay thế dưới đây, không ai trong số đó dường như làm việc:

[self presentModalViewController:updateStatus animated:YES]; 
[[self navigationController] presentModalViewController:updateStatus animated:YES]; 

Bất kỳ sự giúp đỡ nhiều đánh giá cao.

+0

FYI phương pháp init trên chỉ là một phương pháp thuận tiện tĩnh mà không được phân bổ, vv – danhopwood

Trả lời

4

Tôi đã xóa StackOverflow (và Internet) để tìm giải pháp cho vấn đề này. Câu hỏi đã được hỏi nhiều lần, nhưng như bạn lưu ý, không bao giờ trả lời đầy đủ. Nhiều người solutions đưa ra một giải pháp có thể chấp nhận được nếu nó không quan trọng cho dù, ví dụ: một thanh công cụ thấp cũng cuộn tròn lên.

Others đã cung cấp giải pháp sử dụng UIView hoạt ảnh/CoreAnimation thay vì UIModalTransitionStylePartialCurl làm kiểu chuyển đổi phương thức; điều này là tồi tệ nhất một giải pháp không được phép trong App Store, và tốt nhất là không hoàn toàn có hiệu lực tương tự như một được từ UIModalTransitionStylePartialCurl (ví dụ như hình dạng của curl là khác nhau).

Không có giải pháp nào trong số này cung cấp câu trả lời bắt chước giải pháp của Apple trong ứng dụng Bản đồ (tức là sử dụng UIModalTransitionStylePartialCurl nhưng để lại UIToolbar chưa được cuộn tròn ở cuối màn hình).

Tôi sẽ tiếp tục trong truyền thống câu trả lời chưa hoàn chỉnh này, vì bạn hỏi về UITabBarController và giải pháp của tôi không giải quyết cụ thể trường hợp đó. Nó, tuy nhiên, giải quyết vấn đề tôi đã có, đó là để có được một trang curl một nửa với một thanh công cụ không cong ở phía dưới.

Phải có cách thanh lịch hơn để thực hiện việc này, nhưng đây là cách tôi quản lý.

rootViewController của AppDelegate là lớp con của UIViewController, mà tôi sẽ gọi TAContainerViewController. TAContainerViewController quản lý a) nội dung thực tế của màn hình ("nội dung được cuộn tròn"), TAContentViewController và b) nội dung "đằng sau" TAContentViewController (ví dụ: cài đặt), mà tôi sẽ gọi TAUnderCurlViewController.

Ví dụ của tôi là TAContainerViewController có các thuộc tính cho TAContentViewControllerTAUnderCurlViewController. UIView nội dung của tôi là một phần phụ của thuộc tính TAContentViewController 's view; tương tự như vậy những gì người dùng nhìn thấy dưới curl là tài sản view của TAUnderCurlViewController.

Trong phương pháp init của TAContainerViewController tôi chắc chắn rằng phải làm như sau:

_underCurlVC.modalTransitionStyle = UIModalTransitionStylePartialCurl; 

Và để cuộn nội dung để lộ dưới trang, tôi thiết lập một hành động mà các cuộc gọi mã này:

[self.contentVC presentModalViewController:self.underCurlVC animated:YES];` 

nơi selfTAContainerViewController, contentVC là bản sao của TAContentViewControllerunderCurlVC là phiên bản TAUnderCurlViewController.

Để loại bỏ chế độ xem, chỉ cần [self.contentVC dismissModalViewControllerAnimated:YES];.

Một số điểm kỳ lạ dường như xảy ra với khung contentVC khi chế độ xem phương thức bị loại bỏ, vì vậy tôi đã đặt lại khung theo cách thủ công khi chế độ xem phương thức bị loại bỏ.

Tôi đã đăng dự án mẫu có thêm chi tiết về số Github. Hy vọng rằng ai đó có thể thực hiện việc này và biến nó thành một giải pháp nhẹ nhàng hơn, hoặc mở rộng nó để làm việc với một số UINavigationController hoặc UITabBarController. Tôi nghĩ rằng mẹo này là kéo View Controller ra khỏi các mối quan hệ được xác định rõ ràng trong các lớp con Cocoa, vì vậy có thể phân lớp những bộ điều khiển View đặc biệt đó sẽ làm điều đó.

1

Phản hồi của Tim Arnold rất phù hợp với tôi, cảm ơn!

Một bẫy cần lưu ý: quá trình chuyển đổi trang-curl sẽ chiếm toàn bộ màn hình nếu bộ điều khiển chế độ xem nội dung của bạn là được thêm làm con của bộ điều khiển chế độ xem bộ chứa. Bạn chỉ có thể không thêm nó như một đứa trẻ, nhưng sau đó không có phương pháp vòng đời nào sẽ được gọi trên bộ điều khiển nội dung của bạn (ví dụ: viewDidLoad, viewWillAppear), có thể là một vấn đề.

May mắn thay, có một cách để giải quyết vấn đề này. Trong điều khiển container của bạn:

  • Thêm điều khiển nội dung của bạn như một đứa trẻ trong viewDidLoad
  • Hủy bỏ nó như một đứa trẻ trong viewDidAppear
  • lại thêm nó như một đứa trẻ trong viewWillDisappear.

Bằng cách đó, trình điều khiển nội dung của bạn nhận các phương thức vòng đời được gọi, trong khi vẫn có thể thực hiện chuyển đổi trang-curl mà không chiếm toàn bộ màn hình.

Dưới đây là toàn bộ mã của một giải pháp trần xương:

@interface XXContainerController : UIViewController 
@property (strong, nonatomic) UIViewController *contentController; 
@property (nonatomic) BOOL curled; 
@end 

@implementation XXContainerController 

@synthesize contentController = _contentController; 
@synthesize curled = _curled; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.contentController = [self.storyboard 
     instantiateViewControllerWithIdentifier:@"SomeControllerInStoryboard"]; 

    // Add content controller as child view controller. 
    // This way, it will receive all the view lifecycle events 
    [self addChildViewController:self.contentController]; 
    self.contentController.view.frame = self.view.bounds; 
    [self.view addSubview:self.contentController.view]; 
    [self.contentController didMoveToParentViewController:self];  
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 

    // Remove the content controller as child view controller. 
    // This way, the modal page curl transition will 
    // not take over the whole screen. 
    // NOTE: need to wait until content controller has appeared 
    // (which will happen later). 
    // Achieve this by running the code at the end of the animation loop 
    [UIView animateWithDuration:0 animations:nil completion:^(BOOL finished) { 
     [self.contentController removeFromParentViewController]; 
    }]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 

    // Add the content controller as child view controller again 
    // so it receives the view lifecycle events 
    [self addChildViewController:self.contentController]; 
} 

- (void)setCurled:(BOOL)curled 
{ 
    if (curled == _curled) return; 

    _curled = curled; 

    // Curl up the content view and show underneath controller's view 
    if (curled) { 
     // Note you can specify any modal transition in storyboard 
     // E.g. page curl, flip horizontal 
     [self.contentController 
      performSegueWithIdentifier:@"SomeModalSegueDefinedInStoryboard" 
      sender:self]; 

    // Uncurl and show the content controller's view again 
    } else { 
     [self.contentController dismissModalViewControllerAnimated:YES]; 

     // Have to do this, otherwise the content controller's view 
     // gets messed up for some reason 
     self.contentController.view.frame = self.view.bounds; 
    } 
} 

@end 
+0

Cám ơn xây dựng! Một khía cạnh không đầy đủ của giải pháp của tôi là nó không sử dụng API ngăn chứa chế độ xem bộ điều khiển thích hợp. –

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