gpt4 book ai didi

ios - 如何以编程方式重新排序我的 UINavigationController 项目?

转载 作者:搜寻专家 更新时间:2023-10-30 23:09:47 24 4
gpt4 key购买 nike

在我的 TabBarViewController 中,我正在创建一个导航并以模态方式呈现它。

func viewDidLoad(){ 
super.viewDidLoad();
//Create a present this view controller in viewDidLoad
self.navController = UINavigationController()
self.presentViewController(self.navController, animated: true, completion: nil)
}

//This method gets called when TabBarVC gets a NSNotification
func showMessageForUser(user_id: Int){
let mvc = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
mvc.user_id = user_id //set this user

//display this to the user.
self.navController.pushViewController(mvc, animated: true)
}

这很简单。但是,我想这样做:

  • 如果 user_id 已经在堆栈中,将其移动到堆栈的末尾,以便用户可以看到它。没有重复。我该怎么做?
  • 否则,只需创建一个新的 View Controller 实例并将其添加到堆栈的顶部。我想我已经在上面这样做了。

重新排序后,所有“后退”按钮都应按预期工作。

最佳答案

您可以使用 setViewControllers(_:animated:) 重新排列 View Controller 堆栈。您无需执行任何特殊操作即可使后退按钮正常工作。导航 Controller 根据其 viewControllers 数组中的第二项设置后退按钮(如果有第二项),并在更新 viewControllers 时更新后退按钮数组。

下面是我将如何做到这一点。首先,我们向 UIViewController 添加一个方法来询问它是否是特定 userId 的 View Controller 。由于大多数 View Controller 不是(也不可能是)正确的 View Controller ,它只返回 false:

extension UIViewController {
func isViewControllerForUserId(userId: Int) -> Bool {
return false
}
}

然后我们在 MessagesViewController 中覆盖此方法以在适当的时候返回 true:

extension MessagesViewController {
override func isViewControllerForUserId(userId: Int) -> Bool {
return self.userId == userId
}
}

现在,为了向特定用户显示 View Controller ,我们在导航 Controller 的堆栈中搜索现有的 View Controller 。我们采取的行动取决于我们是否找到它:

func showMessageForUserId(userId: Int) {
if let index = navController.viewControllers.indexOf({ $0.isViewControllerForUserId(userId) }) {
navController.moveToTopOfNavigationStack(viewControllerAtIndex: index)
} else {
pushNewViewControllerForUserId(userId)
}
}

如果我们没有找到它,我们会创建一个新的 View Controller 并推送它:

    private func pushNewViewControllerForUserId(userId: Int) {
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("MessagesViewController") as! MessagesViewController
vc.userId = userId
self.navController.pushViewController(vc, animated: true)
}

如果我们确实找到了它,我们就用这个方法把它移到导航栈的顶部:

extension UINavigationController {

func moveToTopOfNavigationStack(viewControllerAtIndex index: Int) {
var stack = viewControllers
if index == stack.count - 1 {
// nothing to do because it's already on top
return
}
let vc = stack.removeAtIndex(index)
if (reorderingIsBuggy) {
setViewControllers(stack, animated: false)
}
stack.append(vc)
setViewControllers(stack, animated: true)
}

private var reorderingIsBuggy: Bool {
// As of iOS 9.3 beta 3, `UINavigationController` drops the prior top-of-stack
// when you use `setViewControllers(_:animated:)` to move a lower item to the
// top with animation. The workaround is to remove the lower item from the stack
// without animation, then add it to the top of the stack with animation. This
// makes it display a push animation instead of a pop animation and avoids
// dropping the prior top-of-stack.
return true
}

}

关于ios - 如何以编程方式重新排序我的 UINavigationController 项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35400795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com