我正在使用相机应用程序,其中相机视图以模态显示。完成裁剪后。我执行MainPageViewController
的展开segue。 (请参见截图)
MainPageViewController
内的我的展开功能如下:
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
self.performSegueWithIdentifier("Categories", sender: self)
}
其中"类别"是从MainPageViewController
到CategoriesTableViewController
的推送segue标识符。
程序进入unwindToMainMenu
功能,但不执行push segue。知道如何解决这个问题吗?
注意:我找到了相同的question,但答案建议更改故事板结构。
答案 0 :(得分:45)
派对有点晚了,但我发现了一种不使用状态标志的方法
注意:这仅适用于iOS 9+,因为只有自定义segues支持iOS9之前的类名,并且您无法在故事板中将exit segue声明为自定义segue
class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
var completion: (() -> Void)?
override func perform() {
super.perform()
if let completion = completion {
completion()
}
}
}
注意:此segue的操作应为unwindToMainMenu
以匹配原始问题
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
if let segue = segue as? UIStoryboardSegueWithCompletion {
segue.completion = {
self.performSegueWithIdentifier("Categories", sender: self)
}
}
}
您的代码现在将在退出segue完成转换后执行
答案 1 :(得分:11)
我想暂时为这个问题提供自己的解决方案。任何进一步的答案总是受欢迎的。
我将一个布尔变量和viewDidAppear函数放到MainPageViewController
。
var fromCamera = false
override func viewDidAppear(animated: Bool) {
if fromCamera {
self.performSegueWithIdentifier("categorySelection", sender: self)
self.fromCamera = false
}
}
在我从fromCamera
执行展开segue之前,我将true
设置为CropViewController
。通过这种方式,只有在执行裁剪视图的展开segue时才执行segue到类别屏幕。
答案 2 :(得分:6)
前进this answer(我只有Objective-C代码)
子类UIStoryBoardSegue
#import <UIKit/UIKit.h>
@interface MyStoryboardSegue : UIStoryboardSegue
/**
This block is called after completion of animations scheduled by @p self.
*/
@property (nonatomic, copy) void(^completion)();
@end
完成动画后调用此完成块。
@implementation MyStoryboardSegue
- (void)perform {
[super perform];
if (self.completion != nil) {
[self.destinationViewController.transitionCoordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![context isCancelled]) {
self.completion();
}
}];
}
}
@end
答案 3 :(得分:5)
前面两个答案,这里有关于目标c版本的更多细节(我也只有Objective-C代码)
子类UIStoryboardSegue与UIStoryboardSegueWithCompletion
class UIStoryboardSegueWithCompletion:UIStoryboardSegue { var completion:(() - &gt; Void)?
override func perform() {
super.perform()
if let completion = completion {
completion()
}
}
}
UIStoryboardSegueWithCompletion.h
#import <UIKit/UIKit.h>
@interface MyStoryboardSegue : UIStoryboardSegueWithCompletion
@property (nonatomic, copy) void(^completion)();
@end
UIStoryboardSegueWithCompletion.m
#import "UIStoryboardSegueWithCompletion.h"
@implementation UIStoryboardSegueWithCompletion
- (void)perform {
[super perform];
if (self.completion != nil) {
[self.destinationViewController.transitionCoordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![context isCancelled]) {
self.completion();
}
}];
}
}
@end
注意:此segue的操作应该是unwindToMainMenu以匹配原始问题 [图像显示segue ui] [1] [图像显示segue ui 2] [2]
从故事板中选择退出segue添加自定义类
-(IBAction)unwindToMainMenu(UIStoryboardSegue *)segue {
if([segue isKindOfClass:[UIStoryboardSegueWithCompletion class]]){
UIStoryboardSegueWithCompletion *segtemp = segue;// local prevents warning
segtemp.completion = ^{
NSLog(@"segue completion");
[self performSegueWithIdentifier:@"Categories" sender:self];
};
}
}
您的代码现在将在退出segue完成转换后执行
答案 4 :(得分:4)
我猜测performSegue没有触发因为unwind segue还没有完成。我目前唯一能想到的就是延迟使用dispatch_after
调用performSegue。这看起来非常&#34; hacky&#34;对我而言。
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
dispatch_after(1, dispatch_get_main_queue()) { () -> Void in
self.performSegueWithIdentifier("Categories", sender: self)
}
}
答案 5 :(得分:3)
退出segue IBAction方法在实际展开segue完成之前发生。我有同样的问题并以这种方式解决(如果你不介意我的代码解释)。它避免了依赖ViewDidAppear的额外时间和动画。
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
let categoriesTable = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("CategoryTableViewController")
self.navigationController?.viewControllers.append(categoriesTable)
self.navigationController?.showViewController(categoriesTable, sender: self)
}
希望这对遇到这种情况并且只是想要瞬间过渡的其他人有帮助!
答案 6 :(得分:3)
更新了@moride对 Swift 5 的回答。过渡协调器现在是可选的,因此在这种情况下,我们将立即运行完成。
class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
var completion: (() -> Void)?
override func perform() {
super.perform()
guard let completion = completion else { return }
guard let coordinator = destination.transitionCoordinator else {
completion()
return
}
coordinator.animate(alongsideTransition: nil) { context in
guard !context.isCancelled else { return }
completion()
}
}
}