У меня есть стек навигации, и, скажем, 5 UIViewControllers. Я хочу удалить 3-й и 4-й просмотрторы в стеке одним нажатием кнопки на 5-м контроллере. Можно ли сделать это? Если да, то как?
Удаление диспетчеров просмотра из стека навигации
Ответ 1
Используйте этот код и наслаждайтесь:
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];
Надеюсь, это поможет вам.
Изменение: быстрый код
guard let navigationController = self.navigationController else { return }
var navigationArray = navigationController.viewControllers // To get all UIViewController stack as Array
navigationArray.remove(at: navigationArray.count - 2) // To remove previous UIViewController
self.navigationController?.viewControllers = navigationArray
Ответ 2
Сначала вы можете получить все контроллеры представлений в массиве, а затем после проверки с помощью соответствующего класса контроллера класса вы можете удалить тот, который вы хотите.
Вот небольшой фрагмент кода:
NSArray* tempVCA = [self.navigationController viewControllers];
for(UIViewController *tempVC in tempVCA)
{
if([tempVC isKindOfClass:[urViewControllerClass class]])
{
[tempVC removeFromParentViewController];
}
}
Я думаю, что это облегчит вашу работу.
Ответ 3
Свифт 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 и т.д.
Ответ 4
Swift 2.0:
var navArray:Array = (self.navigationController?.viewControllers)!
navArray.removeAtIndex(navArray.count-2)
self.navigationController?.viewControllers = navArray
Ответ 5
Свифт 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
Использование функции setViewControllers
из UINavigationController
- лучший способ. Также есть animated
параметр для включения анимации.
func setViewControllers(_ viewControllers: [UIViewController], animated: Bool)
Пример в стремительном вопросе
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];
, Это делает странное поведение, удаленная навигация ViewController, все еще показывающая когда всплывающее окно, как сообщает @robin-ellerkmann
Ответ 7
Если вы пытаетесь перейти на контроллер 2-го представления с 5-го контроллера (пропуска 3-го и 4-го), вы хотели бы использовать [self.navigationController popToviewController:secondViewController]
.
Вы можете получить secondViewController
из стека контроллера навигации.
secondViewController = [self.navigationController.viewControllers objectAtIndex:yourViewControllerIndex];
Ответ 8
Использовать этот
if let navVCsCount = navigationController?.viewControllers.count {
navigationController?.viewControllers.removeSubrange(Range(2..<navVCsCount - 1))
}
Это позаботится о ViewControllers из navigationController. viewControllers, а также элементы навигации, расположенные в навигационной панели.
Примечание. Обязательно вызывайте его хотя бы после viewDidAppear.
Ответ 9
Это решение работало для меня в Swift 4:
let VCCount = self.navigationController!.viewControllers.count
self.navigationController?.viewControllers.removeSubrange(Range(VCCount-3..<VCCount - 1))
Ваш текущий индекс контроллера представления в стеке:
self.navigationController!.viewControllers.count - 1
Ответ 10
Swift 5.1, Xcode 11
extension UINavigationController{
public func removePreviousController(total: Int){
let totalViewControllers = self.viewControllers.count
self.viewControllers.removeSubrange(totalViewControllers-total..<totalViewControllers - 1)
}}
Обязательно вызывайте эту служебную функцию после viewDidDisappear() предыдущего контроллера или viewDidAppear() нового контроллера
Ответ 11
Swift 5, Xcode 10.2
Я нашел этот подход простым, указав, какие контроллеры представления вы хотите удалить из стека навигации.
extension UINavigationController {
func removeViewController(_ controller: UIViewController.Type) {
if let viewController = viewControllers.first(where: { $0.isKind(of: controller.self) }) {
viewController.removeFromParent()
}
}
}
Пример использования:
navigationController.removeViewController(YourViewController.self)
Ответ 12
Я написал расширение с методом, который удаляет все контроллеры между root и top, если не указано иное.
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