Bagaimana cara memunculkan dua tampilan sekaligus dari pengontrol navigasi?


92

Saya ingin memunculkan tampilan ketiga di tumpukan navigasi kembali ke tampilan pertama.

Saya tahu cara memunculkan satu tampilan sekaligus:

[self.navigationController popViewControllerAnimated:YES];

Tapi bagaimana saya melakukan dua sekaligus?


2
Komentar meta: @lubilis, jawaban semuanya di bawah sana adalah yang terbaik. Jawaban peringkat teratas bagus pada masanya tetapi tidak lagi relevan.
n13

Jawaban:


133

Anda juga dapat mencoba ini untuk Langsung di antara tumpukan pengontrol navigasi

NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
for (UIViewController *aViewController in allViewControllers) {
    if ([aViewController isKindOfClass:[RequiredViewController class]]) {
        [self.navigationController popToViewController:aViewController animated:NO];
    }
}

6
imo ini adalah metode terbaik sejauh ini, tetapi Anda harus merujuk pengontrol uinavigation Anda menggunakan self.navigationcontroller
henghonglee

2
Saya setuju, ini adalah solusi terbaik jika pengguna ingin mengembalikan tumpukan ke viewcontroller tertentu. Katakanlah Anda tidak tahu yang mana viewcontroller itu, Anda masih bisa mengimplementasikan sistem di mana Anda akan menentukan berapa banyak viewcontrollers yang ingin Anda lepaskan dari tumpukan dan mendapatkan viewcontroller target dari larik allViewControllers dengan objectAtIndex: (allViewControllers.count - 1 - jumlah). -1 karena array adalah jalur berbasis nol.
Jovan

1
Suka solusi ini. Persis yang saya cari
Designer023

3
Berfungsi juga saat melakukan iterasi pada larik navigator-> viewControllers asli (tidak perlu mengubahnya menjadi larik yang bisa berubah)
Arik Segal

CATATAN! Bahwa ini akan mengulang tumpukan dari awal -> ke akhir, agar tepat Anda harus membalikkan tumpukan. Karena jika Anda memiliki beberapa VC dengan jenis yang sama, Anda akan menghapus VC yang salah dengan urutan yang salah di tumpukan.
StackUnderflow

72

Berikut dua UINavigationControllerekstensi yang dapat menyelesaikan masalah Anda. Saya akan merekomendasikan menggunakan yang pertama yang muncul ke UIViewControllerkelas tertentu:

extension UINavigationController {

  func popToViewController(ofClass: AnyClass, animated: Bool = true) {
    if let vc = viewControllers.filter({$0.isKind(of: ofClass)}).last {
      popToViewController(vc, animated: animated)
    }
  }

  func popViewControllers(viewsToPop: Int, animated: Bool = true) {
    if viewControllers.count > viewsToPop {
      let vc = viewControllers[viewControllers.count - viewsToPop - 1]
      popToViewController(vc, animated: animated)
    }
  }

}

dan gunakan seperti ini:

// pop to SomeViewController class
navigationController?.popToViewController(ofClass: SomeViewController.self)

// pop 2 view controllers
navigationController?.popViewControllers(viewsToPop: 2)

3
Untuk Swift (opsi 1), Anda dapat mengganti keduanya removeLastdengan file removeLast(2).
Dominic K

Bagaimana dengan memanggil metode siklus hidup pengontrol? DidAppear dan ect
Mike Glukhov

1
(Swift 4) Anda kehilangan tanda kurung di baris ini let vc = viewControllers[viewControllers.count - viewsToPop + 1], untuk bekerja dengan benar Anda perlu menggantinya dengan: let vc = viewControllers[viewControllers.count - (viewsToPop + 1)]ataulet vc = viewControllers[viewControllers.count - viewsToPop - 1]
MMiroslav

@MMiroslav Anda benar. Saya telah memperbarui jawaban saya. Terima kasih / Hvala;)
budidino

1
Jawaban ini telah diperbarui setelah saya memposting jawaban saya di bawah ini. Pada dasarnya salinan kode saya ^ _ ^
lubilis

44

Anda dapat membuka pengontrol tampilan "root" (pertama) dengan popToRootViewControllerAnimated:

[self.navigationController popToRootViewControllerAnimated:YES];

// If you want to know what view controllers were popd:
// NSArray *popdViewControllers = [self.navigationController popToRootViewControllerAnimated:YES];

UINavigationControllerReferensi :

Munculkan semua pengontrol tampilan di tumpukan kecuali pengontrol tampilan root dan memperbarui tampilan.

Return Value
Array pengontrol tampilan yang muncul dari tumpukan.


1
ha, tidak percaya saya menghabiskan begitu lama mencari jawaban yang begitu sederhana, terima kasih!
Adam Waite

1
Swift 3: self.navigationController? .PopToRootViewController (animasi: true);
dianakarenms

Persis yang saya cari!
Canucklesandwich

29
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];   

objectAtIndex: 1 -> Anda dapat meneruskan indeks mana pun yang ingin Anda buka


Terima kasih atas triknya, saya baru saja akan melakukannya dengan cara yang salah.
Linus

18

Swift 2 - xCode 7.3

Ini bisa menjadi ekstensi yang sangat berguna untuk memunculkan UIViewControllers:

extension UINavigationController {

    func popToViewControllerOfType(classForCoder: AnyClass) {
        for controller in viewControllers {
            if controller.classForCoder == classForCoder {
                popToViewController(controller, animated: true)
                break
            }
        }
    }

    func popViewControllers(controllersToPop: Int, animated: Bool) {
        if viewControllers.count > controllersToPop {
            popToViewController(viewControllers[viewControllers.count - (controllersToPop + 1)], animated: animated)
        } else {
            print("Trying to pop \(controllersToPop) view controllers but navigation controller contains only \(viewControllers.count) controllers in stack")
        }
    }
}

2
Ini membutuhkan lebih banyak upvoting ... Saya baru saja akan menulis ekstensi itu. Saya hanya akan menggunakan milik Anda terima kasih;)
n13

1
@ n13 kenapa ini lebih baik dari jawaban budidino?
Crashalot

1
Menggunakan ekstensi membuat kode lebih bersih. Anda dapat mengambil jawaban budidino dan membuat perpanjangan darinya tetapi yang ini menghemat usaha Anda. Juga jawaban ini memeriksa kasus kesalahan, dan menangani kesalahan dengan baik (misalnya mencoba memunculkan lebih dari yang Anda miliki)
n13

1
Saya suka jawaban ini. Membuat saya memikirkan kembali dan memperbarui jawaban yang saya posting. Saya membuat kode saya muncul ke contoh terakhir dari kelas yang dicari dalam array viewControllers karena itu mungkin perilaku yang diinginkan.
budidino

15

Jika Anda hanya ingin memunculkan 2 sekaligus karena rootViewController Anda (cara) 'lebih dalam' maka 2 Anda dapat mempertimbangkan untuk menambahkan kategori ke UIviewController misalnya:

UINavigationController + popTwice.h

#import <UIKit/UIKit.h>
@interface UINavigationController (popTwice)

- (void) popTwoViewControllersAnimated:(BOOL)animated;

@end

UINavigationController + popTwice.m

#import "UINavigationController+popTwice.h"

@implementation UINavigationController (popTwice)

- (void) popTwoViewControllersAnimated:(BOOL)animated{
    [self popViewControllerAnimated:NO];
    [self popViewControllerAnimated:animated];
}

@end

Impor kategori #import "UINavigationController+popTwice.h"di suatu tempat dalam implementasi Anda dan gunakan baris kode ini untuk memunculkan 2 pengontrol sekaligus:

[self.navigationController popTwoViewControllersAnimated:YES];

Bukankah itu bagus? :)


6
bagaimana jika Anda perlu memunculkan tiga tampilan, Anda akan menulis "UINavigationController + popThrice.m" ??????
Temui

8
Anda bisa memasukkan parameter untuk jumlah viewControllers yang akan muncul, dan membungkus [self popViewControllerAnimated: NO]; dalam loop-ke, hitungan-1.
noRema

Ini bukan cara yang benar, jika Anda ingin melakukan pot ke 2,3, ... setiap pengontrol mengidentifikasinya dengan loop dan kemudian menggunakan [self.navigationController popToViewControllerAnimated: YES] ;. Ini disebutkan di atas adalah pengkodean yang sangat buruk dan mungkin menunjukkan UI yang berkedip-kedip dan pengalaman pengguna yang buruk.
Vicky Dhas

10

Cepat 4:

func popViewControllerss(popViews: Int, animated: Bool = true) {
    if self.navigationController!.viewControllers.count > popViews
    {
        let vc = self.navigationController!.viewControllers[self.navigationController!.viewControllers.count - popViews - 1]
         self.navigationController?.popToViewController(vc, animated: animated)
    }
}

Kemudian Gunakan Metode Ini

self.popViewControllerss(popViews: 2)

Bagus, Apa yang saya cari. Terima kasih.
maddysan

6

Anda juga dapat mencoba yang ini: -

[self.navigationController popToViewController:yourViewController animated:YES];

6
//viewIndex = 1;
//viewIndex = 2;
//viewIndex = 3;

// **[viewControllers objectAtIndex: *put here your viewindex number*]

NSArray *viewControllers = [self.navigationController viewControllers];
[self.navigationController popToViewController:[viewControllers objectAtIndex:viewIndex] animated:NO];

4
    NSMutableArray *newStack = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
    [newStack removeLastObject];
    [newStack removeLastObject];
    [self.navigationController setViewControllers:newStack animated:YES];

4

Di Swift 3 , Anda dapat memunculkan satu, dua atau lebih viewcontrollers dari pengontrol navigasi seperti itu

let viewControllers = self.navigationController!.viewControllers as [UIViewController]
    for aViewController:UIViewController in viewControllers {
        if aViewController.isKind(of: FromWhereYouWantToGoController.self) {
            _ = self.navigationController?.popToViewController(aViewController, animated: true)
        }
    }

Di sini FromWhereYouWantToGoController adalah pengontrol tujuan. Semoga membantu.


3

Anda dapat meneruskan pengontrol tampilan awal (yang ingin Anda lihat kembali) dan kemudian memanggil baris ini di tampilan terakhir:

[self.navigationController popToViewController:yourInitialViewController animated:YES];

L.


3

Saya tidak melihat jawaban ini di sini. Jika Anda hanya ingin memunculkan beberapa (tidak sampai ke root), Anda dapat mengulang melalui self.navigationController.viewControllers untuk memeriksa jenis kelas, atau jika Anda memiliki referensi yang digunakan:

for (UIViewController *aViewController in self.navigationController.viewControllers) {
   if ([aViewController isKindOfClass:[SMThumbnailViewController class]]) {
      [self.navigationController popToViewController:aViewController animated:YES];
   }
}

2

Anda dapat kembali ke pengontrol tampilan root

[self.navigationController popToRootViewControllerAnimated:YES];

atau, jika tampilan yang Anda inginkan bukan yang pertama muncul, Anda harus memunculkan lagi di tampilan sebelumnya.


2

Ini sedikit fungsi yang saya gunakan untuk kembali ke X ViewControllers:

-(void)backMultiple:(id)data {
    int back = 2; //Default to go back 2 
    int count = [self.navigationController.viewControllers count];

    if(data[@"count"]) back = [data[@"count"] intValue];

    //If we want to go back more than those that actually exist, just go to the root
    if(back+1 > count) {
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    //Otherwise go back X ViewControllers 
    else {
        [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:count-(back+1)] animated:YES];
    }
}

2

Versi Swift pada (Swift 1.2 / Xcode 6.3.1) muncul dua kali atau lebih

 var viewControllers = self.navigationController?.viewControllers
 viewControllers?.removeLast()
 viewControllers?.removeLast()
 self.navigationController?.setViewControllers(viewControllers, animated: true)

atau

 var viewControllers = self.navigationController?.viewControllers
 var viewsToPop = 2
 var end = (viewControllers?.count)!
 var start = end - viewsToPop
 viewControllers?.removeRange(Range<Int>(start: start, end: end))
 self.navigationController?.setViewControllers(viewControllers, animated: true)

1

Anda dapat menggunakan tumpukan UIViewControllers. 1. Ambil array dari semua viewControllers di tumpukan. 2. Iterasi melalui seluruh larik dan temukan viewController yang diinginkan
dengan mencocokkan tipe kelas. 3. Munculkan viewController.

func popToSpecificViewC
{
let viewControllers: [UIViewController] = self.navigationController!.viewControllers as [UIViewController];
        for viewController:UIViewController in viewControllers
        {
            if viewController.isKind(of: WelcomeViewC.self)
            {
                _ = self.navigationController?.popToViewController(viewController, animated: true)
            }
        }
}

0

Menggunakan ekstensi UINavigationController sederhana :

extension UINavigationController {
    func popViewControllers(_ count: Int) {
        guard viewControllers.count > count else { return }
        popToViewController(viewControllers[viewControllers.count - count - 1], animated: true)
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.