Xcode 7.2.1
iOS 9.2
斯威夫特 2.1.1
OSX 10.10.5
以下内容对我有用:
您可以在循环中使用navigationController?.popViewControllerAnimated(true) 来跳过任意数量的视图控制器。
如果要返回的 ViewController 是 UINavigationController 堆栈中的第一个 ViewController,则可以使用navigationController?.popToRootViewControllerAnimated(true) 返回第一个视图控制器。
应用仍然通过跳过的 ViewController 进行动画处理,因此您会看到跳过的 View 在到达目标 ViewController 的途中滑过。
我尝试过使用:
self.navigationController?.viewControllers.removeLast(),在
在朋友列表之间切换以选择聊天以将其删除
从堆栈中。但是在导航到 Show chat with 之后
朋友,后退按钮消失了……
嗯......这似乎应该工作。后退按钮信息是从前一个 ViewController 的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。
然后我控制+从Table View中的Prototype Cell拖动到View Controller2;从弹出窗口中我选择了Selection Segue->Show。
然后我控制+从View Controller2中的按钮拖动到View Controller3;从弹出窗口中我选择了Action Segue->Show。