2012-05-03 24 views
25

Trong ứng dụng iPad, tôi đang sử dụng UISplitViewController. Tôi cần buộc phải hiển thị cửa sổ chính khi ứng dụng khởi chạy ở chế độ dọc.UISplitViewController: Làm cách nào để hiển thị cửa sổ chính khi khởi chạy ứng dụng? (ảnh chân dung)

Bây giờ tôi đang sử dụng mã này và mã hoạt động tốt trên iOS 5.0.

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 
    if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) { 
     [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]; 
    }    
} 

Nhưng trong iOS 5.1 (với loại cửa sổ chính mới), hành vi có vẻ là ngẫu nhiên. Đôi khi cửa sổ bật lên hiển thị ở chế độ toàn màn hình và đôi khi hoạt động tốt.

Một số đề xuất cho 5.1?

+1

Đây là câu trả lời hay: http://stackoverflow.com/a/15817100/733862 – akofink

Trả lời

13

Tôi đã vật lộn với điều này một thời gian, và thậm chí bây giờ tôi không hài lòng với giải pháp 100%, nhưng đó là điều duy nhất tôi có thể đưa ra, với những hạn chế hiện tại.

Đầu tiên, ghi đè lên các phương pháp đại biểu sau đây:

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController 

và sử dụng nó để lấy một tham chiếu đến mục nút thanh, và lưu nó trong một Ivar:

barButtonForMaster = barButtonItem; 

Sau đó, khi bạn muốn hiển thị trình điều khiển chế độ xem chính, thực hiện cuộc gọi như sau:

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster]; 

Trong trường hợp bạn muốn hình này ngay lúc bắt đầu, sau đó sử dụng một số chậm trễ trong việc để ngăn chặn ứng dụng đâm (nhờ những nhận xét hữu ích):

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1]; 

Trong trường hợp đó, bạn có thể thực hiện việc chọn đúng trong sự chia rẽ quan điểm phương pháp đại biểu.

+1

Cảm ơn. Tôi làm điều này với mã của bạn cộng với mã trước đó của tôi. Nhưng đôi khi ứng dụng gặp sự cố. Tôi nghĩ rằng đó là bởi vì tôi làm điều đó trong delegate splitViewController và có thể, trong một số trường hợp, bộ điều khiển nó không được tạo ra đầy đủ. Bây giờ tôi làm mã đó với perfromSelectorAfterDelay và làm việc rất tốt. Cảm ơn. – alejandromp

+0

Điều này sẽ dẫn đến một trình biên dịch có thể bị rò rỉ bộ nhớ cảnh báo – anders

13

Mở rộng về câu trả lời của Rob, này hoạt động tốt đối với tôi (trong viewDidLoad của màn hình chi tiết):

//If in portrait mode, display the master view 
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { 
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem]; 
} 

Không cần phải lấy một tham chiếu riêng biệt, sử dụng self.navigationItem.leftBarButtonItem thay

+0

điều này là tuyệt vời và hoạt động hoàn hảo! nó cho tôi một cảnh báo mặc dù, "PerformSelector có thể gây ra một rò rỉ vì chọn của nó là không rõ" bạn sẽ biết tại sao và phải làm gì với nó? – bllubbor

+2

AFAIK trình biên dịch phân tích các cuộc gọi phương thức và thêm mã để quản lý các quầy tham chiếu ARC (để quản lý Garbage Collection). Gọi một phương thức như thế này giống như sử dụng các phản xạ trong Java (được thực hiện trong suốt thời gian chạy), do đó trình biên dịch không thể thực hiện phép thuật refCount của nó trong trường hợp này. Tuy nhiên, miễn là phương thức được gọi không trả về bất kỳ đối tượng được cấp phát nào (sau đó sẽ là một sự rò rỉ), nó sẽ không có vấn đề gì. Trong trường hợp này, chúng tôi không trả lại bất cứ thứ gì từ phương thức được gọi. Để tránh cảnh báo này, hãy xem: http://www.learningipadprogramming.com/2012/04/03/how-to-ignore-performselector-leak-warning/ – Setomidor

+1

cảm ơn bạn tuyệt vời. – bllubbor

5

Nếu bạn cần nó lúc khởi động ứng dụng, ghi đè phương pháp này trong điều khiển điểm chi tiết của bạn:

-(BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation 
{ 
    return NO; 
} 

tuy nhiên nếu sau đó bạn cần nó để sau đó giấu nó trông như thể phương thức không được gọi, vì vậy bạn sẽ phải ẩn nó theo cách thủ công.

+0

Cảm ơn! Đây sẽ là câu trả lời được chấp nhận. – Bill

+1

Điều này không được chấp nhận trong iOS 8. – phatmann

0

Không cần giữ tài liệu tham khảo ngớ ngẩn xung quanh thanhButtonItem. Chỉ cần gọi cùng một mục tiêu/hành động. Xem câu trả lời của tôi https://stackoverflow.com/a/25695923/1021430

Mục tiêu là bộ điều khiển phân chia xem, và hành động là toggleMasterVisible:

+0

Chuyển đổi đóMasterVisible là một phương thức riêng tư. –

26

Không đề nghị vào đây để 5.1, nhưng một cho 8,0:

Bây giờ với iOS8, có một loạt các phương pháp mới cho cấu hình UISplitViewController.

Trong trường hợp của bạn, juste đặt đúng giá trị trong preferredDisplayMode, ví dụ: trong masterViewController viewDidLoad.

Objective-C:

- (void)viewDidLoad { 
    // configuring splitviewcontroller 
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; 

    //.... 
} 

Swift:

override func viewDidLoad() { 
     self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible 
    } 

Nhưng đó là tất nhiên chỉ iOS8.

+5

Lực lượng này hiển thị cạnh nhau. Nó không hiển thị khung nhìn chính trong chế độ popover như OP được yêu cầu. – phatmann

+0

@phatmann, tôi không nghĩ rằng alejandromp đang nói về popover. Anh ấy nói * Tôi cần phải ép buộc để hiển thị cửa sổ chính của chủ nhân * nhưng điều đó không có nghĩa là bất cứ điều gì, trên thực tế. Xem xét bối cảnh, anh ta nói về việc hiển thị chế độ xem chính bên cạnh trong chế độ dọc, như trong cảnh quan. – Martin

+0

cũng có thể được gọi trong detailViewController – fujianjin6471

7

Đối iOS8 cách dễ nhất là với những điều sau:

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay; 

tôi sử dụng này khi ứng dụng được khởi động lần đầu tiên cho thấy log-in trong masterViewController. Trong mọi trường hợp khác mà tôi sử dụng

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic 
1

Một biến thể chút ít hacky (nhanh chóng):

let btn = self.splitViewController!.displayModeButtonItem() 
btn.target?.performSelector(btn.action, withObject: btn) 
1

tôi sử dụng giải pháp này:
Trong splitViewController trong viewDidLoad thiết displayMode để .primaryOverlay

override func viewDidLoad() { 
    if self.isCollapsed == false, self.displayMode == .primaryHidden { 
     self.preferredDisplayMode = .primaryOverlay 
    } 
} 

Và trong chế độ xemWillAppear đặt lại cho .automatic

override func viewWillAppear(_ animated: Bool) { 
    self.preferredDisplayMode = .automatic 
} 

Cách xem chính này sẽ được hiển thị khi khởi chạy UISplitViewController và có hành vi mặc định sau khi định hướng sẽ thay đổi.

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