【问题标题】:Set segue identifier programmatically以编程方式设置 segue 标识符
【发布时间】:2014-04-09 11:40:38
【问题描述】:

假设我有一个带有文本字段和按钮的 ViewController。

我想使用 unwind segue,这样我可以在单击按钮后将 textField 的信息发送到我的另一个 viewController。

我想使用 PrepareForSegue 方法,以便在我“展开”之前将 textField 中的文本保存在属性中。

如何手动为我的 segue 设置标识符?如果它是一个条形按钮项目,我可以使用 IB 设置标识符(例如“保存”)然后使用它。这不是这种情况,只是一个常规按钮。

【问题讨论】:

  • 为什么需要这样做?你是如何创建转场的...?
  • 当你使用 unwind segue 时你没有设置标识符.. 似乎
  • 您是说通过单击故事板中的转场线然后选择右侧的属性选择器来命名转场标识符吗?
  • 你可以命名 unwind segues...

标签: ios ios7 interface-builder


【解决方案1】:

无法以编程方式创建转场。没有故事板,它们就无法存在。

this question

【讨论】:

  • 谢谢,我缝好了。认为自 2012 年以来 xcode5 中的情况可能发生了变化。可能不会。还是谢谢。
  • 也许你应该检查这个答案是否正确。
  • 您可以通过编程方式创建转场。我在下面的回答中展示了如何做,我已经在 YouTube 上的视频中展示了这一点:
  • @JamesBush 感谢您的提醒!谁会想到 2.5 年后它会成为可能!
  • @JamesBush 我将忽略你对“其他人......”的陈述,以保持这个专业和仅关于代码。
【解决方案2】:

您可以轻松地以编程方式添加转场(无需使用情节提要)。在源视图控制器头文件中:

@property (nonatomic, strong) UIStoryboardSegue *segue;

在源视图控制器实现文件中,相应地设置 segue 属性:

self.segue = [UIStoryboardSegue segueWithIdentifier:[NSString stringWithFormat:@"%lu", indexPath.item] source:self destination:[PlayerViewController sharedPlayerViewController] performHandler:^{
       // Insert whatever; nothing is needed for a basic segue
    }];

另外,在源视图控制器中,在prepareForSegue 方法中添加目标视图控制器设置和过渡:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// The code in this method both sets up the destination view controller and transitions to it; you could optionally do set up here only, and then transition in an overridden -(void)perform method. This way is more convenient.
     [(PlayerViewController *)segue.destinationViewController setView:[PlayerView sharedPlayerView]];
     PHAsset *phAsset = (PHAsset *)AppDelegate.assetsFetchResults[segue.identifier.integerValue];
     [AppDelegate.cacheManager requestAVAssetForVideo:phAsset options:AppDelegate.videoOptions resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
         [[PlayerView sharedPlayerView] addSubview:[PlayerControls sharedPlayerControls]];
         [[PlayerControls sharedPlayerControls] setDelegate:(PlayerViewController *)segue.destinationViewController];
         [[PlayerView sharedPlayerView] addSubview:[AppDelegate playerControlsLabel]];
         [(PlayerViewController *)segue.destinationViewController setupPlaybackForAsset:asset completion:^{
             [((AssetsCollectionViewController *)sender).navigationController presentViewController:(PlayerViewController *)segue.destinationViewController animated:TRUE completion:^{
             }];
         }];
     }];
}

另外,在源视图控制器实现文件的任意位置添加此行以执行转场:

[self prepareForSegue:self.segue sender:self];

可以在 IBAction 处理程序和其他任何地方调用 prepareForSegue 方法。

请注意,呈现目标视图控制器的代码引用了未在情节提要中设置的视图控制器;获取此代码的项目不使用情节提要。但这并不重要,因为 segue 代码 将是相同的。

还请注意,您不必以任何方式、形状或形式修改目标视图控制器。以编程方式创建展开转场(换句话说,建立在此处显示的单向转场):

@implementation RootNavigationController

- (UIStoryboardSegue*)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier {
    return [toViewController segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
}

@结束

现在,这就是我在自己的应用中所做的;以下是其他人在不使用情节提要的情况下创建转场的做法(相对于根本没有情节提要):

- (void)presentSignupViewController {
    // Storyboard ID
    UIStoryboard *modalStoryboard = [UIStoryboard storyboardWithName:@"MyStoryboard" bundle:nil];
    UINavigationController *navController = [modalStoryboard instantiateViewControllerWithIdentifier:@"MySignupViewController"];
    MySignupViewController *controller = [navController viewControllers][0];

    // Configure your custom view controller, e.g. setting delegate
    controller.delegate = self;

    // Show VC
    navController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

    BlurryModalSegue *segue = [[BlurryModalSegue alloc] initWithIdentifier:@"SignupScene" source:self destination:navController];

    [segue perform];
}

区别仅在于perform和prepareForSegue的使用:当完全不使用storyboard时,你必须在performForSegue方法中调用你选择的过渡方法(push...或present...);但是,转换方法会被 perform 方法调用。

<iframe width="853" height="480" src="https://www.youtube.com/embed/y8Fu2PEO2zo?rel=0&showinfo=0" frameborder="0" allowfullscreen></iframe>

【讨论】:

  • 实际上,这种方法是一种 hack-y 方法。 prepareForSegue 方法应该做一些准备工作,例如数据传递、动画激活、清理等。但是在你的实现中,你是在prepareForSegue执行segue .这本身就是一种不好的做法,因为它与 API 的设计不一致。调用performSegueWithIdentifier: 方法后会自动调用该方法。因此,您绝不是在模拟真实 segue 的行为。
  • 没有数据传递、动画或清理——而且,这是一个真正的转场。没有模拟任何东西;并且,API 的设计是什么?
  • 嗯,没错 - 没有。但这正是函数prepareForSegue 应该服务的唯一目的。在您的实现中,您实际上是在 执行 prepareForSegue 中的转场 - 您的 navigationController presentViewController: 是您转场的模拟。这是一种错误的方法,并且会在您的代码库中造成不一致。当您有基于故事板的应用程序和 segue 时,您只需通过 self.performSegue... 调用 segue 并自动调用函数 prepareForSegue - 也就是 not 由您在您的代码中编写。这是 Apple 提供的 API 的设计。
  • @Michal Unwind Segue,示例代码,Apple 开发者连接:- (void)perform { if (self.unwind) { QuizContainerViewController containerVC = (QuizContainerViewController)[self.destinationViewController父视图控制器]; [containerVC popToViewController:self.destinationViewController 动画:YES]; }
  • 这与任何事物有什么关系?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
  • 2015-02-26
  • 2016-12-11
  • 2017-08-07
  • 2013-12-30
  • 2020-05-31
相关资源
最近更新 更多