presentViewController และการแสดงแถบนำทาง


102

ฉันมีลำดับชั้นของตัวควบคุมมุมมองและตัวควบคุมด้านบนสุดจะแสดงเป็นโมดอลและต้องการทราบวิธีแสดงแถบนำทางเมื่อใช้

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

เอกสารสำหรับ 'presentViewController: animated: complete:' note:

'บน iPhone และ iPod touch มุมมองที่นำเสนอจะเป็นแบบเต็มหน้าจอเสมอ บน iPad งานนำเสนอจะขึ้นอยู่กับค่าในคุณสมบัติ modalPresentationStyle '

สำหรับ 'modalPresentationStyle' เอกสารจะกล่าวว่า:

รูปแบบการนำเสนอเป็นตัวกำหนดว่าจะแสดงตัวควบคุมมุมมองที่นำเสนอแบบโมดูลาร์อย่างไรบนหน้าจอ บน iPhone และ iPod touch ตัวควบคุมมุมมองแบบโมดอลจะแสดงแบบเต็มหน้าจอเสมอ แต่บน iPad มีตัวเลือกการนำเสนอที่แตกต่างกันมากมาย

มีวิธีใดบ้างที่จะทำให้แน่ใจว่าแถบนำทางสามารถมองเห็นได้ด้านล่างแถบสถานะเมื่อตัวควบคุมมุมมองแสดงขึ้นเอง ฉันควรตีความเอกสารว่าคุณไม่ได้รับตัวเลือกใด ๆ ของ iPhone / iPod และเฉพาะบน iPad

ก่อนหน้านี้ฉันใช้'UIViewController:presentModalViewController:animated'ซึ่งใช้งานได้ดี แต่ตั้งแต่ iOS 5.0 เป็นต้นมา API ได้เลิกใช้งานแล้วฉันจึงเปลี่ยนไปใช้อันใหม่

มองเห็นสิ่งที่ฉันต้องการทำคือให้ตัวควบคุมใหม่เลื่อนเข้ามาจากด้านล่างของหน้าจอเช่นเดียวกับ API เก่าที่เคยทำ

[อัปเดตด้วยรหัส]:

// 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];

คำตอบ:


193

เป็นความจริงที่ว่าหากคุณนำเสนอตัวควบคุมมุมมองแบบโมเดิร์นบน iPhone มันจะแสดงแบบเต็มหน้าจอเสมอไม่ว่าคุณจะนำเสนอบนคอนโทรลเลอร์มุมมองด้านบนของตัวควบคุมการนำทางหรือวิธีอื่น ๆ ก็ตาม แต่คุณสามารถแสดงแถบนำทางได้ตลอดเวลาด้วยวิธีแก้ปัญหาดังต่อไปนี้:

แทนที่จะนำเสนอตัวควบคุมมุมมองนั้นนำเสนอตัวควบคุมการนำทางแบบโมฆะโดยใช้ตัวควบคุมมุมมองรูทที่ตั้งค่าเป็นตัวควบคุมมุมมองที่คุณต้องการ:

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:^{

                        }];

คุณควรเห็นแถบนำทางเมื่อมุมมองของคุณถูกนำเสนอแบบโมฆะ


นั่นคือสิ่งที่ฉันเริ่มต้นด้วย แต่สาเหตุที่ฉันไม่ใช้ 'presentModalViewController' นั้นเป็นเพราะมันถูกระบุว่าเป็น API ที่เลิกใช้แล้ว
Jonas Gardner

นี่คือสิ่งที่เขียนในคลาส UIViewController: // แสดงตัวควบคุมมุมมองอื่นเป็นลูกโมดอล ใช้การเปลี่ยนแผ่นงานในแนวตั้งหากเป็นภาพเคลื่อนไหววิธีนี้ถูกแทนที่ด้วย presentViewController: เคลื่อนไหว: เสร็จสิ้น: // มันจะถูกยกเลิกวางแผนตามนั้น - (โมฆะ) presentModalViewController: (UIViewController *) ภาพเคลื่อนไหว modalViewController: (BOOL) เคลื่อนไหว; ดังนั้นเพียงแค่เรียกวิธีการใหม่และส่งศูนย์เพื่อให้เสร็จสมบูรณ์และคุณควรจะดี
Manish Ahuja

คำตอบที่ดี อัปเดตเพื่อใช้งาน(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne

2
เมื่อฉันพยายามนำเสนอตัวควบคุมการนำทางมันขัดข้อง ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported') วิธีการทำงานนี้?
oarfish

ในกรณีของฉันมันแสดงแถบ แต่เนื้อหาอื่น ๆ วางไม่ถูกต้องในการนำเสนอภาพเคลื่อนไหว และหลังจากภาพเคลื่อนไหวนี้เท่านั้นภาพเคลื่อนไหวจะกระโดดเข้าสู่ตำแหน่งที่ถูกต้อง
Vyachaslav Gerchicov

48

Swift 5.*

การนำทาง:

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

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

จะกลับไป:

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

Swift 2.0

การนำทาง:

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

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

จะกลับไป:

self.dismissViewControllerAnimated(true, completion: nil)

1
แต่วิธีการตั้งค่าเมื่อฉันลองใช้รหัสของคุณแล้วจะตั้งค่าแถบนำทางเท่านั้น แต่ฉันไม่สามารถเปลี่ยนคุณสมบัติของมันได้เช่นสีของแถบสีชื่อเรื่อง ฯลฯ
Jaydip

ไม่เกี่ยวกับคำถามนี้ แต่คุณสามารถหาคำตอบได้ที่นี่stackoverflow.com/questions/26008536/…
Tal Zion

23

คุณสามารถใช้:

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

ย้อนกลับไป (ฉันคิดว่า):

[self.navigationController popToRootViewControllerAnimated:YES];

3
ขอบคุณวิธีที่ดีที่สุดหากคุณมีการออกแบบตัวควบคุมการนำทางในสตอรีบอร์ดของคุณแล้ว คุณช่วยฉันได้มาก
ไฟซาลิส

ย้อนกลับไปคือ [self.navigationController popViewControllerAnimated: YES]; popToRoot - ย้อนกลับไปที่ตัวควบคุมมุมมองที่ 1
Boris Gafurov

2

ฉันมีปัญหาเดียวกันกับ ios7 ฉันเรียกมันในตัวเลือกและมันทำงานได้ทั้งบน ios7 และ 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

สิ่งที่ต้อง[self.navigationController pushViewController:controller animated:YES];ทำคือทำให้การเปลี่ยนแปลงเป็นภาพเคลื่อนไหวและเพิ่มลงในสแต็กตัวควบคุมการนำทางและแอนิเมชั่นแถบการนำทางที่น่าสนใจอื่น ๆ หากคุณไม่สนใจเกี่ยวกับการเคลื่อนไหวของแถบรหัสนี้ควรใช้งานได้ แถบจะปรากฏบนคอนโทรลเลอร์ใหม่และคุณจะได้รับท่าทางป๊อปโต้ตอบ!

//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.

แก้ไข: ขออภัย presentViewController จะเต็มหน้าจอ คุณจะต้องทำการเปลี่ยนแปลงแบบกำหนดเองโดยใช้ CGAffineTransform.translation หรือบางสิ่งบางอย่างทำให้ตัวควบคุมเคลื่อนไหวด้วยการเปลี่ยนจากนั้นเพิ่มลงใน viewControllers ของ navigationController


1

สวิฟต์ 3

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

วิธีเพิ่มปุ่ม BACK ใน UIViewController ที่นำเสนอ
zulkarnain shah

1

เวอร์ชัน Swift: แสดง ViewController ซึ่งฝังอยู่ในตัวควบคุมการนำทาง

    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

ฉันใช้รหัสนี้ ใช้งานได้ดีใน iOS 8

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

0

ทางออกเดียว

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

หากคุณไม่ได้ตั้งค่าคุณสมบัติ modalPresentationStyle (เช่น UIModalPresentationFormSheet) แถบการนำทางจะแสดงเสมอ เพื่อให้แน่ใจว่าควรทำเสมอ

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

ซึ่งจะแสดงแถบนำทางเสมอ


อืม.. แม้จะมีการอ้างอิงคงที่ไปที่ 'topViewController' ฉันก็ยังคงเห็นพฤติกรรมเดิม ๆ ฉันไม่คิดว่าฉันกำลังเพิ่มตัวควบคุมมุมมองอื่น ๆ ในสแต็ก nav ด้วยวิธีพิเศษใด ๆ
Jonas Gardner

0

หากคุณใช้ NavigationController ใน Swift 2.x

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

0

ลองดู

     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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.