আমার কাছে একটি নেভিগেশন স্ট্যাক রয়েছে, যেখানে 5 টি ইউআইভিউকন্ট্রোলার রয়েছে। আমি 5 তম ভিউ কনট্রোলারের একটি বোতামের ক্লিকের স্ট্যাকের তৃতীয় এবং চতুর্থ ভিউ কনট্রোলারগুলি সরিয়ে দিতে চাই। এটা করা কি সম্ভব? যদি তাই হয়, কিভাবে?
আমার কাছে একটি নেভিগেশন স্ট্যাক রয়েছে, যেখানে 5 টি ইউআইভিউকন্ট্রোলার রয়েছে। আমি 5 তম ভিউ কনট্রোলারের একটি বোতামের ক্লিকের স্ট্যাকের তৃতীয় এবং চতুর্থ ভিউ কনট্রোলারগুলি সরিয়ে দিতে চাই। এটা করা কি সম্ভব? যদি তাই হয়, কিভাবে?
উত্তর:
এই কোডটি ব্যবহার করুন এবং উপভোগ করুন:
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
আপনি প্রথমে অ্যারেতে সমস্ত ভিউ কন্ট্রোলার পেতে পারেন এবং তারপরে সংশ্লিষ্ট ভিউ কন্ট্রোলার ক্লাসের সাথে চেক করার পরে আপনি যা চান সেটি মুছতে পারেন।
এখানে কোডের একটি ছোট অংশ রয়েছে:
NSArray* tempVCA = [self.navigationController viewControllers];
for(UIViewController *tempVC in tempVCA)
{
if([tempVC isKindOfClass:[urViewControllerClass class]])
{
[tempVC removeFromParentViewController];
}
}
আমি মনে করি এটি আপনার কাজকে আরও সহজ করে দেবে।
সুইফট 3 এবং 4/5
self.navigationController!.viewControllers.removeAll()
self.navigationController?.viewControllers.remove(at: "insert here a number")
সুইফট 2.1
সব মুছে ফেলুন:
self.navigationController!.viewControllers.removeAll()
সূচকে অপসারণ
self.navigationController?.viewControllers.removeAtIndex("insert here a number")
অপসারণের সম্ভাব্য ক্রিয়াগুলির একগুচ্ছ যেমন রিমুভাল ফার্স্ট, রেঞ্জ ইত্যাদি
সুইফট 5:
navigationController?.viewControllers.removeAll(where: { (vc) -> Bool in
if vc.isKind(of: MyViewController.self) || vc.isKind(of: MyViewController2.self) {
return false
} else {
return true
}
})
return !vc.isKind(of: MyViewController.self) && !vc.isKind(of: MyViewController2.self)
কাজটি এক লাইনে করবে :-)
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];
। এটি অদ্ভুত আচরণ করে, সরানো ভিউকন্ট্রোলার নেভিগেশন এখনও দেখায় যখন পপ ব্যাক লাইক @ রবিন-এলার্কম্যান দ্বারা রিপোর্ট করা হয়েছে
setViewControllers(_:animated:)
কৌশলটি উভয় উপায়েই ব্যবহার করছি : একাধিক কন্ট্রোলার পপ করতে এবং একাধিক নিয়ামককে ধাক্কা দেওয়ার জন্য।
সুইফট ২.০:
var navArray:Array = (self.navigationController?.viewControllers)!
navArray.removeAtIndex(navArray.count-2)
self.navigationController?.viewControllers = navArray
if var navArray = ... { ... }
সুইফ্ট 5, এক্সকোড 11.3
আপনি নেভিগেশন স্ট্যাক থেকে কোন ভিউ কন্ট্রোলার (গুলি) মুছে ফেলতে চান তা নির্দিষ্ট করে এই পদ্ধতির সন্ধান পেয়েছি।
extension UINavigationController {
func removeViewController(_ controller: UIViewController.Type) {
if let viewController = viewControllers.first(where: { $0.isKind(of: controller.self) }) {
viewController.removeFromParent()
}
}
}
উদাহরণ ব্যবহার:
navigationController.removeViewController(YourViewController.self)
যদি আপনি 5 তম ভিউ কন্ট্রোলার (3 য় এবং 4 র্থ এড়ানো) থেকে দ্বিতীয় দর্শন নিয়ন্ত্রকের কাছে যাওয়ার চেষ্টা করছেন, আপনি ব্যবহার করতে চান [self.navigationController popToviewController:secondViewController]
।
আপনি secondViewController
নেভিগেশন নিয়ামক স্ট্যাক থেকে এটি পেতে পারেন ।
secondViewController = [self.navigationController.viewControllers objectAtIndex:yourViewControllerIndex];
এটা ব্যবহার কর
if let navVCsCount = navigationController?.viewControllers.count {
navigationController?.viewControllers.removeSubrange(Range(2..<navVCsCount - 1))
}
এটি নেভিগেশনকন্ট্রোলারের ভিউকন্ট্রোলারদের যত্ন নেবে। ভিউকন্ট্রোলার এবং একটি নেভিগেশন আইটেমগুলি নেভিগেশনবারে স্ট্যাক করা আছে।
দ্রষ্টব্য: কমপক্ষে ভিডিড অ্যাপের পরে এটিকে কল করতে ভুলবেন না
সুইফ্ট 5.1, এক্সকোড 11
extension UINavigationController{
public func removePreviousController(total: Int){
let totalViewControllers = self.viewControllers.count
self.viewControllers.removeSubrange(totalViewControllers-total..<totalViewControllers - 1)
}}
পূর্ববর্তী কন্ট্রোলারের ভিডিডিস্পায়ার () বা নতুন নিয়ামকের ভিউডিডঅ্যাপার () এর পরে এই ইউটিলিটি ফাংশনটি কল করতে ভুলবেন না
extension UIViewController {
func removeFromNavigationController() { navigationController?.removeController(.last) { self == $0 } }
}
extension UINavigationController {
enum ViewControllerPosition { case first, last }
enum ViewControllersGroupPosition { case first, last, all }
func removeController(_ position: ViewControllerPosition, animated: Bool = true,
where closure: (UIViewController) -> Bool) {
var index: Int?
switch position {
case .first: index = viewControllers.firstIndex(where: closure)
case .last: index = viewControllers.lastIndex(where: closure)
}
if let index = index { removeControllers(animated: animated, in: Range(index...index)) }
}
func removeControllers(_ position: ViewControllersGroupPosition, animated: Bool = true,
where closure: (UIViewController) -> Bool) {
var range: Range<Int>?
switch position {
case .first: range = viewControllers.firstRange(where: closure)
case .last:
guard let _range = viewControllers.reversed().firstRange(where: closure) else { return }
let count = viewControllers.count - 1
range = .init(uncheckedBounds: (lower: count - _range.min()!, upper: count - _range.max()!))
case .all:
let viewControllers = self.viewControllers.filter { !closure($0) }
setViewControllers(viewControllers, animated: animated)
return
}
if let range = range { removeControllers(animated: animated, in: range) }
}
func removeControllers(animated: Bool = true, in range: Range<Int>) {
var viewControllers = self.viewControllers
viewControllers.removeSubrange(range)
setViewControllers(viewControllers, animated: animated)
}
func removeControllers(animated: Bool = true, in range: ClosedRange<Int>) {
removeControllers(animated: animated, in: Range(range))
}
}
private extension Array {
func firstRange(where closure: (Element) -> Bool) -> Range<Int>? {
guard var index = firstIndex(where: closure) else { return nil }
var indexes = [Int]()
while index < count && closure(self[index]) {
indexes.append(index)
index += 1
}
if indexes.isEmpty { return nil }
return Range<Int>(indexes.min()!...indexes.max()!)
}
}
removeFromParent()
navigationController?.removeControllers(in: 1...3)
navigationController?.removeController(.first) { $0 != self }
navigationController?.removeController(.last) { $0 != self }
navigationController?.removeControllers(.all) { $0.isKind(of: ViewController.self) }
navigationController?.removeControllers(.first) { !$0.isKind(of: ViewController.self) }
navigationController?.removeControllers(.last) { $0 != self }
সমাধান কোডটি এখানে পেস্ট করতে ভুলবেন না
import UIKit
class ViewController2: ViewController {}
class ViewController: UIViewController {
private var tag: Int = 0
deinit { print("____ DEINITED: \(self), tag: \(tag)" ) }
override func viewDidLoad() {
super.viewDidLoad()
print("____ INITED: \(self)")
let stackView = UIStackView()
stackView.axis = .vertical
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
stackView.addArrangedSubview(createButton(text: "Push ViewController() white", selector: #selector(pushWhiteViewController)))
stackView.addArrangedSubview(createButton(text: "Push ViewController() gray", selector: #selector(pushGrayViewController)))
stackView.addArrangedSubview(createButton(text: "Push ViewController2() green", selector: #selector(pushController2)))
stackView.addArrangedSubview(createButton(text: "Push & remove previous VC", selector: #selector(pushViewControllerAndRemovePrevious)))
stackView.addArrangedSubview(createButton(text: "Remove first gray VC", selector: #selector(dropFirstGrayViewController)))
stackView.addArrangedSubview(createButton(text: "Remove last gray VC", selector: #selector(dropLastGrayViewController)))
stackView.addArrangedSubview(createButton(text: "Remove all gray VCs", selector: #selector(removeAllGrayViewControllers)))
stackView.addArrangedSubview(createButton(text: "Remove all VCs exept Last", selector: #selector(removeAllViewControllersExeptLast)))
stackView.addArrangedSubview(createButton(text: "Remove all exept first and last VCs", selector: #selector(removeAllViewControllersExeptFirstAndLast)))
stackView.addArrangedSubview(createButton(text: "Remove all ViewController2()", selector: #selector(removeAllViewControllers2)))
stackView.addArrangedSubview(createButton(text: "Remove first VCs where bg != .gray", selector: #selector(dropFirstViewControllers)))
stackView.addArrangedSubview(createButton(text: "Remove last VCs where bg == .gray", selector: #selector(dropLastViewControllers)))
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if title?.isEmpty ?? true { title = "First" }
}
private func createButton(text: String, selector: Selector) -> UIButton {
let button = UIButton()
button.setTitle(text, for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: selector, for: .touchUpInside)
return button
}
}
extension ViewController {
private func createViewController<VC: ViewController>(backgroundColor: UIColor = .white) -> VC {
let viewController = VC()
let counter = (navigationController?.viewControllers.count ?? -1 ) + 1
viewController.tag = counter
viewController.title = "Controller \(counter)"
viewController.view.backgroundColor = backgroundColor
return viewController
}
@objc func pushWhiteViewController() {
navigationController?.pushViewController(createViewController(), animated: true)
}
@objc func pushGrayViewController() {
navigationController?.pushViewController(createViewController(backgroundColor: .lightGray), animated: true)
}
@objc func pushController2() {
navigationController?.pushViewController(createViewController(backgroundColor: .green) as ViewController2, animated: true)
}
@objc func pushViewControllerAndRemovePrevious() {
navigationController?.pushViewController(createViewController(), animated: true)
removeFromNavigationController()
}
@objc func removeAllGrayViewControllers() {
navigationController?.removeControllers(.all) { $0.view.backgroundColor == .lightGray }
}
@objc func removeAllViewControllersExeptLast() {
navigationController?.removeControllers(.all) { $0 != self }
}
@objc func removeAllViewControllersExeptFirstAndLast() {
guard let navigationController = navigationController, navigationController.viewControllers.count > 1 else { return }
let lastIndex = navigationController.viewControllers.count - 1
navigationController.removeControllers(in: 1..<lastIndex)
}
@objc func removeAllViewControllers2() {
navigationController?.removeControllers(.all) { $0.isKind(of: ViewController2.self) }
}
@objc func dropFirstViewControllers() {
navigationController?.removeControllers(.first) { $0.view.backgroundColor != .lightGray }
}
@objc func dropLastViewControllers() {
navigationController?.removeControllers(.last) { $0.view.backgroundColor == .lightGray }
}
@objc func dropFirstGrayViewController() {
navigationController?.removeController(.first) { $0.view.backgroundColor == .lightGray }
}
@objc func dropLastGrayViewController() {
navigationController?.removeController(.last) { $0.view.backgroundColor == .lightGray }
}
}
এই সমাধানটি আমার পক্ষে দ্রুত 4 এ কাজ করেছে:
let VCCount = self.navigationController!.viewControllers.count
self.navigationController?.viewControllers.removeSubrange(Range(VCCount-3..<VCCount - 1))
স্ট্যাকের মধ্যে আপনার বর্তমান দর্শন নিয়ামক সূচকটি হ'ল:
self.navigationController!.viewControllers.count - 1
আমি পদ্ধতি সহ একটি এক্সটেনশন লিখেছি যা অন্যথায় নির্দিষ্ট না করা থাকলে মূল এবং শীর্ষের মধ্যে থাকা সমস্ত কন্ট্রোলারকে সরিয়ে দেয়।
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)
আইওএস 12.2, সুইফট 5 এ পরীক্ষিত
// স্ট্যাক থেকে শ্রেণি নাম দিয়ে ভিউ কন্ট্রোলারগুলি সরিয়ে এবং তারপরে বর্তমান ভিউটি খারিজ করে।
self.navigationController?.viewControllers.removeAll(where: { (vc) -> Bool in
if vc.isKind(of: ViewController.self) || vc.isKind(of: ViewController2.self)
{
return true
}
else
{
return false
}
})
self.navigationController?.popViewController(animated: false)
self.dismiss(animated: true, completion: nil)