web-dev-qa-db-ja.com

ナビゲーションスタックからViewControllerを削除する

ナビゲーションスタックがあり、たとえば5つのUIViewControllerがあります。 5番目のビューコントローラーのボタンをクリックして、スタック内の3番目と4番目のビューコントローラーを削除したい。これを行うことは可能ですか?もしそうならどのように?

77
Jean Paul Scott

このコードを使用してお楽しみください:

NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];

// [navigationArray removeAllObjects];    // This is just for remove all view controller from navigation stack.
[navigationArray removeObjectAtIndex: 2];  // You can pass your index here
self.navigationController.viewControllers = navigationArray;
[navigationArray release];

これがお役に立てば幸いです。

編集:Swiftコード

var navigationArray = self.navigationController?.viewControllers //To get all UIViewController stack as Array
navigationArray!.remove(at: (navigationArray?.count)! - 2) // To remove previous UIViewController
self.navigationController?.viewControllers = navigationArray!
144
Nit

最初にアレイ内のすべてのView Controllerを取得し、対応するView Controllerクラスで確認した後、必要なものを削除できます。

ここに小さなコードがあります:

NSArray* tempVCA = [self.navigationController viewControllers];

for(UIViewController *tempVC in tempVCA)
{
    if([tempVC isKindOfClass:[urViewControllerClass class]])
    {
        [tempVC removeFromParentViewController];
    }
}

これにより作業が楽になると思います。

46

Swift 3&4/5

self.navigationController!.viewControllers.removeAll()

self.navigationController?.viewControllers.remove(at: "insert here a number")

Swift 2.1

すべて削除する:

self.navigationController!.viewControllers.removeAll()

インデックスで削除

self.navigationController?.viewControllers.removeAtIndex("insert here a number")

RemoveFirst、rangeなどのより多くの可能なアクションがあります。

33
kuzdu

Swift 2.0:

  var navArray:Array = (self.navigationController?.viewControllers)!
  navArray.removeAtIndex(navArray.count-2)
  self.navigationController?.viewControllers = navArray
8
tahir raees

スイフト5:

        navigationController?.viewControllers.removeAll(where: { (vc) -> Bool in
            if vc.isKind(of: MyViewController.self) || vc.isKind(of: MyViewController2.self) {
                return false
            }
            else {
                return true
            }
        })
6
Niklas

setViewControllersからUINavigationController関数を使用するのが最善の方法です。アニメーションを有効にするanimatedパラメーターもあります。

func setViewControllers(_ viewControllers: [UIViewController], animated: Bool)

質問のSwiftの例

func goToFifthVC() {

    var currentVCStack = self.navigationController?.viewControllers
    currentVCStack?.removeSubrange(2...3)

    let fifthVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "fifthVC")
    currentVCStack?.append(fifthVC)

    self.navigationController?.setViewControllers(currentVCStack!, animated: true)
}

[tempVC removeFromParentViewController];のような他の方法を試しました。 @ robin-ellerkmannによって報告されたようにポップバックするときに表示されるViewControllerナビゲーションが削除され、奇妙な動作をする

5
Megamind

5番目のView Controllerから2番目のView Controllerに移動しようとしている場合(3番目と4番目をスキップ)、[self.navigationController popToviewController:secondViewController]を使用します。

Navigation ControllerスタックからsecondViewControllerを取得できます。

secondViewController =  [self.navigationController.viewControllers objectAtIndex:yourViewControllerIndex];
4
Vignesh

これを使って

if let navVCsCount = navigationController?.viewControllers.count {
    navigationController?.viewControllers.removeSubrange(Range(2..<navVCsCount - 1))
}

NavigationControllerのViewControllerを処理します。 viewControllers、およびnavigationBarにスタックされたnavigationItems。

注:少なくともviewDidAppearの後に必ず呼び出してください

4
Nikola Markovic

このソリューションは、Swift 4でうまくいきました:

let VCCount = self.navigationController!.viewControllers.count
self.navigationController?.viewControllers.removeSubrange(Range(VCCount-3..<VCCount - 1))

スタック内の現在のView Controllerインデックスは次のとおりです。

self.navigationController!.viewControllers.count - 1
2
babak

特に指定がない限り、ルートとトップの間のすべてのコントローラーを削除するメソッドを使用して拡張機能を作成しました。

extension UINavigationController {
func removeControllers(between start: UIViewController?, end: UIViewController?) {
    guard viewControllers.count > 1 else { return }
    let startIndex: Int
    if let start = start {
        guard let index = viewControllers.index(of: start) else {
            return
        }
        startIndex = index
    } else {
        startIndex = 0
    }

    let endIndex: Int
    if let end = end {
        guard let index = viewControllers.index(of: end) else {
            return
        }
        endIndex = index
    } else {
        endIndex = viewControllers.count - 1
    }
    let range = startIndex + 1 ..< endIndex
    viewControllers.removeSubrange(range)
}

}

範囲(たとえば、2〜5)を使用する場合は、使用できます。

    let range = 2 ..< 5
    viewControllers.removeSubrange(range)

IOS 12.2でテスト済み、Swift 5

0
Adam

Swift 5、Xcode 10.

extension UINavigationController{
public func removePreviousController(total: Int){
    let totalViewControllers = self.viewControllers.count
    self.viewControllers.removeSubrange(totalViewControllers-total..<totalViewControllers - 1)
}}

前のコントローラーのviewDidDisappear()または新しいコントローラーのviewDidAppear()の後に必ずこのユーティリティ関数を呼び出してください

0
Kedar Sukerkar