presentViewController và hiển thị thanh điều hướng


99

Tôi có hệ thống phân cấp bộ điều khiển chế độ xem và bộ điều khiển trên cùng được hiển thị dưới dạng một phương thức và muốn biết cách hiển thị thanh điều hướng khi sử dụng

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

Các tài liệu cho 'presentViewController: animation: complete:' lưu ý:

'Trên iPhone và iPod touch, giao diện được trình bày luôn ở chế độ toàn màn hình. Trên iPad, bản trình bày phụ thuộc vào giá trị trong thuộc tính modalPresentationStyle. '

Đối với 'modalPresentationStyle', tài liệu cho biết:

Kiểu trình bày xác định cách hiển thị trên màn hình bộ điều khiển dạng xem được trình bày theo phương thức. Trên iPhone và iPod touch, bộ điều khiển chế độ xem phương thức luôn được hiển thị toàn màn hình, nhưng trên iPad có một số tùy chọn trình bày khác nhau.

Có cách nào để đảm bảo rằng thanh điều hướng hiển thị bên dưới thanh trạng thái sau khi điều khiển chế độ xem tự hiển thị không? Tôi có nên giải thích tài liệu là, bạn không nhận được bất kỳ tùy chọn nào của iPhone / iPod và chỉ trên iPad?

Trước đây, tôi đã sử dụng 'UIViewController:presentModalViewController:animated'nó hoạt động tốt, nhưng kể từ iOS 5.0, API không được dùng nữa nên tôi đang chuyển sang cái mới.

Về mặt trực quan, những gì tôi muốn làm là để bộ điều khiển mới trượt vào từ cuối màn hình, giống như API cũ đã từng làm.

[đang cập nhật bằng mã]:

// My root level view:
UIViewController *vc = [[RootViewController alloc] 
                            initWithNibName:nil 
                            bundle:[NSBundle mainBundle]];
navController = [[UINavigationController alloc] initWithRootViewController:vc];        
....

// Within the RootViewController, Second view controller is created and added 
// to the hierarchy. It is this view controller that is responsible for 
// displaying the DetailView:
SecondTierViewController *t2controller = [[SecondTierViewController alloc] 
                                           initWithNibName:nil
                                           bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:t2controller animated:YES];

// Created by SecondTierViewController 
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                        bundle:[NSBundle mainBundle]];  

controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.modalPresentationStyle = UIModalPresentationCurrentContext;

[self.navigationController presentViewController:controller 
                                        animated:YES 
                                        completion:nil];

Câu trả lời:


193

Đúng là nếu bạn trình bày một bộ điều khiển chế độ xem trên iPhone, nó sẽ luôn hiển thị toàn màn hình cho dù bạn trình bày nó như thế nào trên bộ điều khiển chế độ xem trên cùng của bộ điều khiển điều hướng hoặc bất kỳ cách nào khác. Nhưng bạn luôn có thể hiển thị thanh điều hướng với cách giải quyết sau:

Thay vì trình bày bộ điều khiển chế độ xem đó theo cách trình bày bộ điều khiển điều hướng theo phương thức với bộ điều khiển chế độ xem gốc của nó được đặt làm bộ điều khiển chế độ xem bạn muốn:

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navigationController = 
    [[UINavigationController alloc] initWithRootViewController:myViewController];

//now present this navigation controller modally 
[self presentViewController:navigationController
                   animated:YES
                   completion:^{

                        }];

Bạn sẽ thấy một thanh điều hướng khi chế độ xem của bạn được trình bày theo phương thức.


Đó là khá nhiều những gì tôi đã bắt đầu. Nhưng lý do tôi không sử dụng 'presentModalViewController' là vì nó được ghi nhận là một API không dùng nữa.
Jonas Gardner

đây là những gì đã được viết trong lớp UIViewController: // Hiển thị bộ điều khiển chế độ xem khác dưới dạng con phương thức. Sử dụng chuyển đổi trang tính theo chiều dọc nếu hoạt ảnh. Phương thức này đã được thay thế bằng presentViewController: animation: complete: // Nó sẽ KHÔNG ĐƯỢC DÙNG, hãy lập kế hoạch cho phù hợp. - (void) presentModalViewController: (UIViewController *) modalViewController animation: (BOOL) animation; vì vậy chỉ cần gọi phương thức mới và chuyển nil để hoàn thành và bạn sẽ tốt.
Manish Ahuja

Câu trả lời chính xác. Cập nhật để sử dụng(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne

2
Khi tôi cố gắng trình bày một bộ điều khiển điều hướng, nó bị treo ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'). Làm thế nào điều này có thể hoạt động?
oarfish

Trong trường hợp của tôi, nó hiển thị thanh nhưng nội dung khác được đặt không chính xác khi trình bày hoạt ảnh. Và chỉ sau hình ảnh động này, nó mới nhảy vào đúng vị trí.
Vyachaslav Gerchicov

46

Swift 5.*

Dẫn đường:

guard let myVC = self.storyboard?.instantiateViewController(withIdentifier: "MyViewController") else { return }
let navController = UINavigationController(rootViewController: myVC)

self.navigationController?.present(navController, animated: true, completion: nil)

Quay lại:

self.dismiss(animated: true, completion: nil)

Swift 2.0

Dẫn đường:

let myVC = self.storyboard?.instantiateViewControllerWithIdentifier("MyViewController");
let navController = UINavigationController(rootViewController: myVC!)

self.navigationController?.presentViewController(navController, animated: true, completion: nil)

Quay lại:

self.dismissViewControllerAnimated(true, completion: nil)

1
Nhưng thế nào để thiết lập khi tôi cố gắng mã của bạn sau đó chỉ thiết lập thanh điều hướng nhưng tôi không thể thay đổi thuộc tính của nó như màu thanh màu, tiêu đề, vv
Jaydip

Không liên quan đến câu hỏi này nhưng bạn có thể tìm thấy câu trả lời ở đây stackoverflow.com/questions/26008536/...
Tal Zion

23

Bạn có thể sử dụng:

[self.navigationController pushViewController:controller animated:YES];

Quay trở lại (tôi nghĩ):

[self.navigationController popToRootViewControllerAnimated:YES];

3
Cảm ơn bạn, cách tốt nhất để làm điều đó nếu bạn đã có thiết kế bộ điều khiển điều hướng trong bảng phân cảnh của mình. Bạn đã giúp tôi rất nhiều
phyzalis

quay lại là [self.navigationController popViewControllerAnimated: YES]; popToRoot - quay trở lại bộ điều khiển chế độ xem đầu tiên
Boris Gafurov

2

Tôi đã gặp vấn đề tương tự trên ios7. Tôi đã gọi nó trong bộ chọn và nó hoạt động trên cả ios7 và ios8.

[self performSelector: @selector(showMainView) withObject: nil afterDelay: 0.0];

- (void) showMainView {
    HomeViewController * homeview = [
        [HomeViewController alloc] initWithNibName: @
        "HomeViewController"
        bundle: nil];
    UINavigationController * navcont = [
        [UINavigationController alloc] initWithRootViewController: homeview];
    navcont.navigationBar.tintColor = [UIColor whiteColor];
    navcont.navigationBar.barTintColor = App_Theme_Color;
    [navcont.navigationBar
    setTitleTextAttributes: @ {
        NSForegroundColorAttributeName: [UIColor whiteColor]
    }];
    navcont.modalPresentationStyle = UIModalPresentationFullScreen;
    navcont.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.navigationController presentViewController: navcont animated: YES completion: ^ {

    }];
}

1

Tất cả những gì [self.navigationController pushViewController:controller animated:YES];cần làm là tạo hiệu ứng chuyển tiếp và thêm nó vào ngăn xếp bộ điều khiển điều hướng và một số nội dung hoạt ảnh thanh điều hướng thú vị khác. Nếu bạn không quan tâm đến hoạt ảnh thanh, thì mã này sẽ hoạt động. Thanh này xuất hiện trên bộ điều khiển mới và bạn nhận được một cử chỉ pop tương tác!

//Make Controller
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                    bundle:[NSBundle mainBundle]];  
//Customize presentation
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.modalPresentationStyle = UIModalPresentationCurrentContext;

//Present controller
[self presentViewController:controller 
                   animated:YES 
                 completion:nil];
//Add to navigation Controller
[self navigationController].viewControllers = [[self navigationController].viewControllers arrayByAddingObject:controller];
//You can't just [[self navigationController].viewControllers addObject:controller] because viewControllers are for some reason not a mutable array.

Chỉnh sửa: Xin lỗi, presentViewController sẽ lấp đầy toàn màn hình. Bạn sẽ cần thực hiện một chuyển đổi tùy chỉnh, với CGAffineTransform.translation hoặc một cái gì đó, tạo hiệu ứng cho bộ điều khiển với quá trình chuyển đổi, sau đó thêm nó vào viewControllers của điều hướng.


1

Swift 3

        let vc0 : ViewController1 = ViewController1()
        let vc2: NavigationController1 = NavigationController1(rootViewController: vc0)
        self.present(vc2, animated: true, completion: nil)

Cách thêm nút QUAY LẠI vào UIViewController được trình bày
zulkarnain shah

1

Phiên bản Swift: Điều này trình bày một ViewController được nhúng trong Bộ điều khiển Điều hướng.

    override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //  Identify the bundle by means of a class in that bundle.
    let storyboard = UIStoryboard(name: "Storyboard", bundle: NSBundle(forClass: SettingsViewController.self))

    // Instance of ViewController that is in the storyboard.
    let settingViewController = storyboard.instantiateViewControllerWithIdentifier("SettingsVC")

    let navController = UINavigationController(rootViewController: settingViewController)

    presentViewController(navController, animated: true, completion: nil)

}

1

Tôi sử dụng mã này. Nó hoạt động tốt trong iOS 8.

MyProfileEditViewController *myprofileEdit=[self.storyboard instantiateViewControllerWithIdentifier:@"myprofileeditSid"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myprofileEdit];
[self presentViewController:navigationController animated:YES completion:^{}];

0

Một cách giải quyết

DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                        bundle:[NSBundle mainBundle]];  

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
navController.modalPresentationStyle = UIModalPresentationCurrentContext;



[self.navigationController presentViewController:navController 
                                        animated:YES 
                                        completion:nil];

0

Nếu bạn không đặt thuộc tính modalPresentationStyle (như UIModalPresentationFormSheet), thanh điều hướng sẽ luôn được hiển thị. Để đảm bảo, hãy luôn làm

[[self.navigationController topViewController] presentViewController:vieController 
                                                            animated:YES 
                                                          completion:nil];

Thao tác này sẽ luôn hiển thị thanh điều hướng.


Hmm.. ngay cả với tham chiếu cố định đến 'topViewController', tôi vẫn thấy hành vi tương tự. Tôi không nghĩ rằng tôi đang thêm các bộ điều khiển chế độ xem khác vào ngăn xếp điều hướng theo bất kỳ cách đặc biệt nào.
Jonas Gardner

0

Nếu bạn sử dụng NavigationController trong Swift 2.x

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let targetViewController = storyboard.instantiateViewControllerWithIdentifier("targetViewControllerID") as? TargetViewController
self.navigationController?.pushViewController(targetViewController!, animated: true)

0

thử cái này

     let transition: CATransition = CATransition()
    let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.duration = 1
    transition.timingFunction = timeFunc
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromRight
    self.view.window!.layer.addAnimation(transition, forKey: kCATransition)
    self.presentViewController(vc, animated:true, completion:nil)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.