탐색 스택의 세 번째보기에서 첫 번째보기로 돌아가고 싶습니다.
한 번에 하나의 뷰를 표시하는 방법을 알고 있습니다.
[self.navigationController popViewControllerAnimated:YES];
그러나 한 번에 두 가지를 어떻게합니까?
답변:
내비게이션 컨트롤러 스택 사이를 이동하는데도 시도 할 수 있습니다.
NSMutableArray *allViewControllers = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
for (UIViewController *aViewController in allViewControllers) {
if ([aViewController isKindOfClass:[RequiredViewController class]]) {
[self.navigationController popToViewController:aViewController animated:NO];
}
}
다음은 UINavigationController
문제를 해결할 수 있는 두 가지 확장 기능입니다. UIViewController
특정 클래스 의 첫 번째 항목을 사용하는 것이 좋습니다 .
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)
}
}
}
다음과 같이 사용하십시오.
// pop to SomeViewController class
navigationController?.popToViewController(ofClass: SomeViewController.self)
// pop 2 view controllers
navigationController?.popViewControllers(viewsToPop: 2)
removeLast
을 removeLast(2)
.
let vc = viewControllers[viewControllers.count - viewsToPop + 1]
올바르게 작동하려면 다음으로 교체해야합니다. let vc = viewControllers[viewControllers.count - (viewsToPop + 1)]
또는let vc = viewControllers[viewControllers.count - viewsToPop - 1]
다음을 사용하여 "루트"(첫 번째) 뷰 컨트롤러로 이동할 수 있습니다 popToRootViewControllerAnimated
.
[self.navigationController popToRootViewControllerAnimated:YES];
// If you want to know what view controllers were popd:
// NSArray *popdViewControllers = [self.navigationController popToRootViewControllerAnimated:YES];
루트 뷰 컨트롤러를 제외한 스택의 모든 뷰 컨트롤러를 팝하고 디스플레이를 업데이트합니다.
반환 값
스택에서 팝된 뷰 컨트롤러의 배열입니다.
스위프트 2-xCode 7.3
이것은 UIViewController를 팝하는 데 매우 유용한 확장이 될 수 있습니다.
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")
}
}
}
rootViewController가 (방법) '깊이'이기 때문에 한 번에 2를 팝하려는 경우 2를 예로 들면 UIviewController에 범주를 추가하는 것을 고려할 수 있습니다.
#import <UIKit/UIKit.h>
@interface UINavigationController (popTwice)
- (void) popTwoViewControllersAnimated:(BOOL)animated;
@end
#import "UINavigationController+popTwice.h"
@implementation UINavigationController (popTwice)
- (void) popTwoViewControllersAnimated:(BOOL)animated{
[self popViewControllerAnimated:NO];
[self popViewControllerAnimated:animated];
}
@end
#import "UINavigationController+popTwice.h"
구현의 어딘가에 범주를 가져 오고 다음 코드 줄을 사용하여 한 번에 두 개의 컨트롤러를 팝합니다.
[self.navigationController popTwoViewControllersAnimated:YES];
대단하지 않습니까? :)
스위프트 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)
}
}
그런 다음이 방법 사용
self.popViewControllerss(popViews: 2)
//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];
NSMutableArray *newStack = [NSMutableArray arrayWithArray:[self.navigationController viewControllers]];
[newStack removeLastObject];
[newStack removeLastObject];
[self.navigationController setViewControllers:newStack animated:YES];
Swift 3에서는 이와 같은 내비게이션 컨트롤러에서 하나, 둘 또는 그 이상의 뷰 컨트롤러를 팝할 수 있습니다.
let viewControllers = self.navigationController!.viewControllers as [UIViewController]
for aViewController:UIViewController in viewControllers {
if aViewController.isKind(of: FromWhereYouWantToGoController.self) {
_ = self.navigationController?.popToViewController(aViewController, animated: true)
}
}
여기서 FromWhereYouWantToGoController는 대상 컨트롤러입니다. 도움이 되었기를 바랍니다.
나는 여기 에서이 대답을 보지 못했습니다. 루트까지가 아니라 몇 개만 팝하려는 경우 self.navigationController.viewControllers에서 클래스 유형 확인을 반복하거나 참조가있는 경우 다음을 사용할 수 있습니다.
for (UIViewController *aViewController in self.navigationController.viewControllers) {
if ([aViewController isKindOfClass:[SMThumbnailViewController class]]) {
[self.navigationController popToViewController:aViewController animated:YES];
}
}
다음은 X ViewController로 돌아가는 데 사용하는 작은 함수입니다.
-(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];
}
}
(Swift 1.2 / Xcode 6.3.1)의 Swift 버전이 두 번 이상 튀어 나옴
var viewControllers = self.navigationController?.viewControllers
viewControllers?.removeLast()
viewControllers?.removeLast()
self.navigationController?.setViewControllers(viewControllers, animated: true)
또는
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)
UIViewController의 스택을 사용할 수 있습니다. 1. 스택에있는 모든 viewController의 배열을 가져옵니다. 2. 전체 배열을 반복
하고 클래스 유형을 일치시켜 원하는 viewController 를 찾습니다 . 3. 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)
}
}
}
간단한 UINavigationController 확장 사용 :
extension UINavigationController {
func popViewControllers(_ count: Int) {
guard viewControllers.count > count else { return }
popToViewController(viewControllers[viewControllers.count - count - 1], animated: true)
}
}