我的导航为:
List of Friends with messages Controller
(点击撰写) - > List of friends to select chatting
(选择朋友) - > Show chat with friend
目前,如果在Show chat with friend
内且用户选择back
,则会将其带到List of friends to select chatting
控制器。
我希望跳过此控制器,并在返回选择后导航到List of Friends with messages Controller
注意:List of Friends with messages Controller
是嵌入在标签中的。
我尝试在self.navigationController?.viewControllers.removeLast()
之间的segue
内使用List of friends to select chatting
将其从堆栈中删除。但是在导航到Show chat with friend
之后,后退按钮消失了......
如何允许我描述的导航?
答案 0 :(得分:3)
如果您的目标是跳过第二个UIViewController
并从第三个UIViewController
回到第一个UIViewController
。请尝试以下代码:
// This count will return how many view controllers are there in navigation stack
let controllersInNavigationCount = self.navigationController?.viewControllers.count
// This will pop to first UIViewController skipping second UIViewController
self.navigationController?.popToViewController(self.navigationController?.viewControllers[controllersInNavigationCount!-2] as! FirstViewController, animated: true)
答案 1 :(得分:0)
这有点棘手。我如何处理这个问题是
在ViewWillAppear下显示与朋友View Controller的聊天时,我会设置一个名为pageViewed的NSUserDefault,并将其值设置为1.
现在在朋友列表中选择聊天ViewWillAppear下的View Controller我会查看pageViewed NSUserDefault的值是否为1.如果是,则将其设置为0并调用make a将其从堆栈中删除。
//Remove from Nav-Stack [self.navigationController popViewControllerAnimated:YES];
再次它有点棘手,但绝对可行。
答案 2 :(得分:0)
Xcode 7.2.1
iOS 9.2
斯威夫特2.1.1
OSX 10.10.5
以下对我有用:
您可以在循环中使用navigationController?.popViewControllerAnimated(true)
来跳过任意数量的视图控制器。
如果要返回的ViewController是UINavigationController堆栈中的第一个ViewController,则可以使用navigationController?.popToRootViewControllerAnimated(true)
返回第一个视图控制器。
该应用程序仍然通过跳过的ViewController进行动画处理,因此您可以在前往目标ViewController的途中看到跳过的View幻灯片。
嗯......好像应该有用。从前一个ViewController的我尝试过使用: self.navigationController?.viewControllers.removeLast(),在 朋友列表之间的segue选择聊天删除它 从堆栈。但之后导航到Show聊天 朋友,后退按钮消失......
navigationItem
属性中检索后退按钮信息。之前的ViewController navigationItem.backBarButtonItem
包含您看到的后退按钮的信息。那么,当您从堆栈中删除ViewController时,为什么UINavigationController不会从早期的ViewController中检索navigationItem.backBarButtonItem
信息?
听起来目标ViewController可能已经获得了对前一个ViewController的弱引用 - 你从堆栈中删除的那个。然后,当您从viewControllers数组中删除以前的ViewController时,前一个ViewController消失了,弱引用被指定为nil - 这阻止了目标ViewController获取后退按钮的信息;因此没有显示后退按钮。
<强> AppDelegate.swift 强>:
//
// AppDelegate.swift
// NavigationBarExample
//
// Copyright © 2016 7stud. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let navController = window!.rootViewController as! UINavigationController
let friendsController = navController.topViewController as! FriendsTableViewController
friendsController.friendStore = FriendStore(names: ["Joe", "Cathy", "Bobo"])
return true
}
...
...
<强> FriendsTableViewController.swift 强>:
// FriendsTableViewController.swift
// NavigationBarExample
//
//
// Copyright © 2016 7stud. All rights reserved.
//
import UIKit
class FriendsTableViewController: UITableViewController {
var friendStore: FriendStore!
override func viewDidLoad() {
super.viewDidLoad()
//Prevent TableView from underlapping the status bar:
let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
let insets = UIEdgeInsets(
top: statusBarHeight, left: 0, bottom: 0, right: 0
)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets
}
//MARK: - UITableViewDataSource methods:
override func tableView(tableView: UITableView,
numberOfRowsInSection section: Int)
-> Int
{
return friendStore.allFriends.count
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath
indexPath: NSIndexPath)
-> UITableViewCell
{
let friend = friendStore.allFriends[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier(
"UITableViewCell-Default",
forIndexPath: indexPath
)
cell.textLabel?.text = friend.name
return cell
}
//MARK: - Segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowFriend" {
if let row = tableView.indexPathForSelectedRow?.row {
let viewController2 = segue.destinationViewController as! ViewController2
viewController2.friend = friendStore.allFriends[row]
viewController2.previousTitle = navigationItem.title
}
}
}
}
<强> FriendStore.swift 强>:
//
// FriendStore.swift
// NavigationBarExample
//
// Copyright © 2016 7stud. All rights reserved.
//
import Foundation
class FriendStore {
var allFriends: [Friend] = []
init(names: [String]) {
for name in names {
allFriends.append(Friend(name: name) )
}
}
}
<强> Friend.swift 强>:
//
// Friend.swift
// NavigationBarExample
//
// Copyright © 2016 7stud. All rights reserved.
//
import Foundation
class Friend: NSObject {
var name: String
init(name: String) {
self.name = name
super.init()
}
}
<强> ViewController2.swift 强>:
//
// ViewController2.swift
// NavigationBarExample
//
// Copyright © 2016 7stud. All rights reserved.
//
import UIKit
class ViewController2: UIViewController {
var friend: Friend! {
didSet {
navigationItem.title = friend.name
}
}
var previousTitle: String!
override func viewDidLoad() {
//Set the correct title for the back button on the next view controller:
let myBackButtonItem = UIBarButtonItem(
title: previousTitle,
style: .Plain,
target: nil,
action: nil //An action specified here won't get called--I
//think the NavigationController must overwrite this sometime later.
)
navigationItem.backBarButtonItem = myBackButtonItem
}
}
<强> ViewController3.swift 强>:
//
// ViewController3.swift
// NavigationBarExample
//
// Copyright © 2016 7stud. All rights reserved.
//
import UIKit
class ViewController3: UIViewController {
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
let goBackCount = 2
if let navController = navigationController {
let viewControllers = navController.viewControllers
if viewControllers.count >= goBackCount {
for _ in 1...goBackCount {
navController.popViewControllerAnimated(true)
}
}
}
}
}
完成同样事情的一般方法是:如果要返回的控制器是根ViewController,即它是UINavigationController堆栈中的第一个控制器,那么在viewWillDisappear()
你只需拨打navigationController?.popToRootViewControllerAnimated(true)
Main.storyboard:
在故事板中创建Table View
后,我选择了Table View
,在Xcode菜单栏中,我选择了Editor>Embed In>NavigationController
。 Navigation Controller
是initial view controller
。我还双击了Table View
导航栏的中间位置,并将标题设置为Friends
。
然后我控制+从Prototype Cell
中的Table View
拖动到View Controller2
;从我选择的弹出窗口Selection Segue->Show
。
然后我控制+从View Controller2
的按钮拖动到View Controller3
;从我选择的弹出窗口Action Segue->Show
。
答案 3 :(得分:0)
返回N个视图控制器的最佳方法是使用navigationController.viewControllers。当您到达最后一个viewController时,将删除N个以前的viewController,如下所示:
let previousViewControllerIndex = navigationController.viewControllers.count - N
navigationController.viewControllers.remove(at: previousViewControllerIndex)
此后,当您按返回时,将导航到所需的控制器,而不会看到已删除的先前视图控制器的弹出动画。