Ale*_*ber 64 iphone objective-c ios segue uistoryboardsegue
我有一个小的iPhone应用程序,它使用导航控制器显示3个视图(这里全屏):

首先,它显示社交网络列表(Facebook,Google +等):

然后它会显示一个OAuth对话框,询问凭据:

和(之后,同样UIWebView)权限:

最后,它显示了具有用户详细信息的最后一个视图控制器(在真实应用程序中,这将是可以启动多人游戏的菜单):

这一切都运作良好,但我有一个问题,当用户想要返回并选择另一个社交网络时:
用户触摸后退按钮而不显示第一个视图,显示第二个视图,再次询问OAuth凭据/权限.
我能在这做什么?Xcode 5.0.2显示了一个非常有限的segues选择 - 推送,模态(我无法使用,因为它模糊了我的游戏所需的导航栏)和自定义.
我是一个iOS编程新手,但早些时候我开发了一个Adobe AIR移动应用程序,并且可以1)替换视图而不是推送2)从导航堆栈中删除不需要的视图.
如何在原生应用程序中做同样的事情?
ima*_*747 59
为了扩展上面的各种细分,这是我的解决方案.它具有以下优点:
Segue Code:
- (void)perform {
// Grab Variables for readability
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
UINavigationController *navigationController = sourceViewController.navigationController;
// Get a changeable copy of the stack
NSMutableArray *controllerStack = [NSMutableArray arrayWithArray:navigationController.viewControllers];
// Replace the source controller with the destination controller, wherever the source may be
[controllerStack replaceObjectAtIndex:[controllerStack indexOfObject:sourceViewController] withObject:destinationController];
// Assign the updated stack with animation
[navigationController setViewControllers:controllerStack animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ele 37
您可以使用自定义segue:要做到这一点,您需要创建一个子类UIStoryboardSegue(示例MyCustomSegue)的类,然后您可以用这样的东西覆盖"perform"
-(void)perform {
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
UINavigationController *navigationController = sourceViewController.navigationController;
// Pop to root view controller (not animated) before pushing
[navigationController popToRootViewControllerAnimated:NO];
[navigationController pushViewController:destinationController animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
此时转到Interface Builder,选择"custom"segue,并输入您的类的名称(示例MyCustomSegue)
chr*_*ton 24
自定义segue对我不起作用,因为我有一个Splash视图控制器,我想替换它.由于列表中只有一个视图控制器,因此popToRootViewController仍然将Splash留在堆栈中.我使用以下代码替换单个控制器
-(void)perform {
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
UINavigationController *navigationController = sourceViewController.navigationController;
[navigationController setViewControllers:@[destinationController] animated:YES];
}
Run Code Online (Sandbox Code Playgroud)
现在在Swift 4中:
class ReplaceSegue: UIStoryboardSegue {
override func perform() {
source.navigationController?.setViewControllers([destination], animated: true)
}
}
Run Code Online (Sandbox Code Playgroud)
现在在Swift 2.0中
class ReplaceSegue: UIStoryboardSegue {
override func perform() {
sourceViewController.navigationController?.setViewControllers([destinationViewController], animated: true)
}
}
Run Code Online (Sandbox Code Playgroud)
Dr.*_*gos 17
快速2版的ima747回答:
override func perform() {
let navigationController: UINavigationController = sourceViewController.navigationController!;
var controllerStack = navigationController.viewControllers;
let index = controllerStack.indexOf(sourceViewController);
controllerStack[index!] = destinationViewController
navigationController.setViewControllers(controllerStack, animated: true);
}
Run Code Online (Sandbox Code Playgroud)
正如他所提到的,它具有以下优点:
小智 16
对于这个问题,我认为答案很简单
然后将ViewControllers数组设置为如下所示的navigationController:
if let navController = self.navigationController {
let newVC = DestinationViewController(nibName: "DestinationViewController", bundle: nil)
var stack = navController.viewControllers
stack.remove(at: stack.count - 1) // remove current VC
stack.insert(newVC, at: stack.count) // add the new one
navController.setViewControllers(stack, animated: true) // boom!
}
Run Code Online (Sandbox Code Playgroud)与Swift 3完美配合.
希望它有助于一些新人.
干杯.
使用展开segue将是解决此问题的最合适的解决方案.我同意劳罗.
以下是从detailsViewController [或viewController3]到myAuthViewController [或viewController1]设置展开segue的简要说明
这基本上就是你如何通过代码执行unwind segue.
在要解除的viewController中实现IBAction方法(在本例中为viewController1).方法名称可以是任何长的,它需要一个UIStoryboardSegue类型的参数.
@IBAction func unwindToMyAuth(segue: UIStoryboardSegue) {
println("segue with ID: %@", segue.Identifier)
}
Run Code Online (Sandbox Code Playgroud)在要从其中展开的viewController(3)中链接此方法.要链接,请右键单击(双指点击)viewController顶部的退出图标,此时"unwindToMyAuth"方法将显示在弹出框中.控制单击此方法到第一个图标,viewController图标(也出现在viewController的顶部,与退出图标位于同一行).选择弹出的"手动"选项.
在Document outline中,对于相同的视图(viewController3),选择刚刚创建的展开segue.转到属性检查器并为此展开segue分配唯一标识符.我们现在有一个通用的展开segue准备使用.
现在,unwind segue可以像代码中的任何其他segue一样执行.
performSegueWithIdentifier("unwind.to.myauth", sender: nil)
Run Code Online (Sandbox Code Playgroud)这种方法将使您从viewController3转到viewController1,而无需从导航层次结构中删除viewController2.
与其他segue不同,展开segue不会实例化视图控制器,它们只会转到导航层次结构中的现有视图控制器.
正如之前的回答中提到的那样,弹出不动画然后推送动画看起来不太好,因为用户会看到实际的过程。我建议你先推送动画,然后删除之前的vc。像这样:
extension UINavigationController {
func replaceCurrentViewController(with viewController: UIViewController, animated: Bool) {
pushViewController(viewController, animated: animated)
let indexToRemove = viewControllers.count - 2
if indexToRemove >= 0 {
viewControllers.remove(at: indexToRemove)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个快速的 Swift 4/5 解决方案,通过创建一个自定义序列,用新的(无动画)替换(顶部堆栈)视图控制器:
class SegueNavigationReplaceTop: UIStoryboardSegue {
override func perform () {
guard let navigationController = source.navigationController else { return }
navigationController.popViewController(animated: false)
navigationController.pushViewController(destination, animated: false)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
77996 次 |
| 最近记录: |