2011-01-19 12 views
6

Tôi đang cố gắng hiển thị UISplitViewController trình bày nó dưới dạng Bộ điều khiển Chế độ xem trong ứng dụng iPad của tôi. Tôi quản lý để có nó hiển thị, nhưng đối với một số lý do có một khoảng cách bên trái của chế độ xem kích thước của một thanh trạng thái cũng được bảo quản khi định hướng được thay đổi.Làm thế nào để sử dụng UISplitViewController làm Bộ điều khiển Chế độ xem?

alt text

Có ai biết tại sao điều này xảy ra không? Hoặc nếu điều này thậm chí có thể? Có lẽ tôi đang tự đào một cái lỗ lớn.

Trả lời

6

Cổ phiếu UISplitViewController được thiết kế để sử dụng làm bộ điều khiển chế độ xem gốc. Trình bày một cách khiêm tốn đi ngược lại Nguyên tắc giao diện người của Apple và có khả năng cao bị từ chối bởi Nhóm đánh giá ứng dụng. Ngoài ra, bạn có thể nhận được lỗi:

Application tried to present Split View Controllers modally

+2

một sự thay thế là để thử một bộ điều khiển aftermarket splitview trên cho kích thước, như https://github.com/SlavaBushtruk/APSplitViewController –

+1

upvoted cho "view controller Aftermarket" –

3

Về mặt kỹ thuật, đây là những gì tôi đã làm:

1/Subclass một UIViewController tức. @interface aVC: UIViewController

2/Trong chế độ xemDidLoad, hãy thiết lập một splitViewController, nghĩa là. aSplitVC

3/Sau đó self.view = aSplitVC.view

Sau khi tất cả, hiện tại AVC như modalViewController

+0

Không làm việc trên Xcode 8, iOS 8+ Nhật ký lỗi: "Chế độ xem chỉ có thể được kết hợp với nhiều nhất một bộ điều khiển chế độ xem tại một thời điểm!" – Jerome

3

Tôi đồng ý với Evan rằng đây là hơi off-màu cho Apple, nhưng tôi đã có thể hoàn thành một phiên bản hoạt động của giải pháp này với giải pháp sau:

UISplitViewController *splitVC = [[UISplitViewController alloc] init]; 
    splitVC.delegate = VC2; 
    splitVC.viewControllers = [NSArray arrayWithObjects:navcon1, navcon2, nil]; 

    UINavigationController *splitNavCon = [[UINavigationController alloc] init]; 
    splitNavCon.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    [splitNavCon.view addSubview:splitVC.view]; 
    VC2.splitParentViewController = splitNavCon; 

    [self presentViewController:splitNavCon animated:YES completion:nil]; 

Điều này cho phép tôi có nút quay lại hoạt động trong UISplitViewController mới được trình bày một cách vừa phải trên màn hình.

Bạn sẽ nhận thấy rằng tôi thực sự vượt qua VC2 (đại biểu của UISplitViewController) UINavigationController mẹ của nó. Đây là cách tốt nhất mà tôi thấy tôi có thể bỏ qua những UISplitViewController từ bên trong VC2:

[splitParentViewController dismissViewControllerAnimated:YES completion:nil]; 
+1

Ý tưởng cơ bản ở đây hoạt động đủ tốt, nhưng ARC có thể ăn 'UISplitViewController' nếu cái gì khác không giữ lại nó. Vì vậy, nếu trẻ em của bạn xem biến mất sau khi được trình bày theo cách này, di chuyển nó lên thành một tài sản hoặc một cái gì đó. – Nuthatch

8

Giống như đối với nhiều người bạn, tôi cần một người 'cách phương thức' để sử dụng UISplitViewController. Điều này có vẻ là một vấn đề cũ, nhưng tất cả những gì tôi thấy trong StackOverflow là giải thích lý do tại sao vấn đề xảy ra khi bạn cố gắng làm như vậy (như câu trả lời được chấp nhận ở trên), hoặc 'hack-arounds'.

Tuy nhiên, đôi khi nó cũng không phải là rất thuận tiện để thay đổi nhiều mã cơ sở của bạn và làm cho một UISplitViewController đối tượng ban đầu chỉ để có được chức năng của nó lên và chạy.

Hóa ra, có một cách để làm cho mọi người hạnh phúc (bao gồm cả các nguyên tắc của Apple). Các giải pháp mà tôi thấy tốt nhất, là sử dụng các UISplitViewController bình thường, nhưng khi cần thiết sẽ được hiển thị/miễn nhiệm, sử dụng phương pháp sau đây:

-(void)presentWithMasterViewController: (UIViewController *) thisMasterViewController 
    andDetailViewController: (UIViewController *) thisDetailViewController 
         completion:(void(^)(void))completion 
{ 
    masterViewController = thisMasterViewController; 
    detailViewController = thisDetailViewController; 

    [self setViewControllers:[NSArray arrayWithObjects:masterViewController, detailViewController, nil]]; 

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 

    self.window.rootViewController = self; 

    [self.window makeKeyAndVisible]; 

    if(completion) 
     completion(); 
    } 

-(void)dismissViewControllerWithCompletion:(void (^)(void))completion 
{ 
    self.window = nil; 
    masterViewController = nil; 
    detailViewController = nil; 
    if(completion) 
     completion(); 
} 

đâu "cửa sổ", là một tài sản của lớp con UISplitViewController của bạn. Và hệ thống sẽ chăm sóc phần còn lại!

Để thuận tiện/tài liệu tham khảo, Tôi đã tải lên này như một lớp con UISplitViewController để GitHub:

ModalSplitViewController

--EXAMPLE về cách sử dụng -

mySplitViewController = [[ModalSplitViewController alloc] init]; 
    mySplitViewController.delegate = self; 

    [mySplitViewController presentWithMasterViewController:masterViewController andDetailViewController:detailViewController completion:nil]; 

    // when done: 

    [mySplitViewController dismissViewControllerWithCompletion:nil]; 
    mySplitViewController = nil; 

Side-lưu ý: Tôi đoán hầu hết các sự nhầm lẫn bắt nguồn từ thực tế là ví dụ sử dụng UISplitView từ tài liệu của Apple sử dụng cửa sổ được tạo trong appDelegate và thực tế là hầu hết mọi người không phải là rất quen thuộc với khái niệm cửa sổ - bởi vì chúng ta thường không cần (chúng được tạo một lần trong StoryBoards hoặc mã soạn sẵn).

Ngoài ra, nếu bạn đang thực hiện khôi phục trạng thái, không được quên rằng UIViewControllers được lập trình sẽ không tự động khôi phục bởi hệ thống.

0

Tôi tin người ta có thể làm theo cách khác: thay vì bộ điều khiển tùy chỉnh trình bày bộ điều khiển chia, người ta có thể thiết lập bộ điều khiển chia làm bộ điều khiển cửa sổ gốc trong bảng phân cảnh và trên đầu trang của nó, bạn có thể thêm bộ điều khiển tùy chỉnh của mình (tức là màn hình đăng nhập) và xóa nó khỏi màn hình (removeFromSuperview chẳng hạn) khi cần.

0

Câu trả lời đó không thực sự chính xác, vì nó không còn giá trị nữa kể từ iOS8 và nếu bạn cần hỗ trợ iOS7, bạn có thể thực hiện điều đó giống như bạn đặt UIViewController thực sự có vùng chứa dưới dạng SplitView.

let mdSplitView = self.storyboard?.instantiateViewControllerWithIdentifier("myDataSplitView") as! MyData_SplitVC 
    self.addChildViewController(mdSplitView) 

    mdSplitView.view.bounds = self.view.bounds 
    self.view.addSubview(mdSplitView.view) 
    mdSplitView.didMoveToParentViewController(self)