func cleanUpNavigationStack() {
guard let previousRoomVCIndex = self.navigationController?.viewControllers.firstIndex(where:
{ $0 is RoomViewController }) else {return}
self.navigationController?.viewControllers.remove(at: previousRoomVCIndex)
}
Index 3 should be deallocated after index 4 has been appended to the stack, I do not need index 3 which is the previous room.
func cleanUpNavigationStack() { guard let previousRoomVCIndex = self.navigationController?.viewControllers.firstIndex(where: { $0 is RoomViewController }) else {return} self.navigationController?.viewControllers.remove(at: previousRoomVCIndex) }
I call this method right after pushing the new RoomViewController onto the navigation stack. So what I've expected to happen is:
1 -> Pushing a new RoomViewController
2 -> Now the navigation stack contains 2 RoomViewControllers, the last one which is the relevant one, and the first one which is the previous irrelevant room.
3 -> I remove the previous irrelevant room from my navigation stack.
4 -> It is being deallocated from memory as well, and if I pop one VC back, it should take me to the LoadingViewController.
But after calling print(navigationController?.viewControllers)
when I am done cleaning up the navigation stack, I still see the previous RoomViewController, so the removal didn't work for some reason.
What could be the reason for this? and how should I approach it?
My main goal at the end is to deallocate the current RoomVC when pushing a new RoomVC.
You remove screen from array (of Nav Stack), that means this array doesn't hold reference to this screen anymore. But UINavigationController
still holds a ref childVC
(this screen), UIWindow's subview
still holds a ref to this screen's view. It can not be deallocated. That is why we need to call navigationController.pop...
The best UX is showing the room list as a Horizontal Page View.
You will need to make a PageItem (can be UICollectionViewCell) and then setup like normal UICollectionView logic.
Or you can use this trick:
Code in RoomListScreen.swift
import UIKit
class RoomListScreen: UIViewController {
@IBOutlet weak var buttonOpenRoom: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func actionDisplayRoomDetail(_ sender: Any) {
let roomScreen = RoomScreen()
roomScreen.onOpenNextRoom = { [unowned self] in
self.handleOnOpenNextRoom()
}
self.navigationController?.pushViewController(roomScreen, animated: true)
}
func handleOnOpenNextRoom() {
let roomScreen = RoomScreen()
roomScreen.onOpenNextRoom = { [unowned self] in
self.handleOnOpenNextRoom()
}
// pop current screen (RoomScreen) without animation -> slient popping.
self.navigationController?.popViewController(animated: false)
// If you want to have a nature animation like push new screen, pass true to animated: ..., but the RoomListScreen be visible in 0.2-0.3 seconds, so, it is not good UI/UX. It is acceptable but still confuse user sometime.
self.navigationController?.pushViewController(roomScreen, animated: false)
}
}
Code in RoomScreen.swift
import UIKit
class RoomScreen: UIViewController {
@IBOutlet weak var buttonNextRoom: UIButton!
var onOpenNextRoom: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func actionClickNextRoom(_ sender: Any) {
self.onOpenNextRoom?()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print(self.navigationController?.viewControllers ?? [])
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.