简体   繁体   English

执行函数以从另一个类调用performSegueWithIdentifier

[英]Execute function to call performSegueWithIdentifier from another class

I've spent a few hours on this trying to work it out myself but I give up! 我已经花了几个小时试图自己解决这个问题,但是我放弃了!

I have a master-detail arrangement where the user input screen needs to call a function on another class to post to a web service. 我有一个主从布局,其中用户输入屏幕需要调用另一个类上的函数以发布到Web服务。 Upon completion of the asynchronous call, the class will then call a specified function. 异步调用完成后,该类将调用指定的函数。 In this case, I'm just testing and all I want to do is go back to the main screen after the user input is accepted by the web service. 在这种情况下,我只是测试,我要做的就是在Web服务接受用户输入后返回主屏幕。

When the uses taps a button on the input screen (SetLocationViewController), the asynchronous operation is called in the class APIPostClass. 当用户点击输入屏幕上的按钮(SetLocationViewController)时,将在APIPostClass类中调用异步操作。 After it is complete, I want SetLocationViewController to segue back to MasterViewController. 完成后,我想让SetLocationViewController选回到MasterViewController。

In APIPostClass.m in (called after the asynchronous op finishes) 在APIPostClass.m中(在异步操作完成后调用)

-(void)callWhenDone {
NSLog(@"callWhenDone loaded.");

SetLocationViewController *SLVClassInstance = [[SetLocationViewController alloc] init];
[SLVClassInstance doSegue];
}

In SetLocationViewController.m 在SetLocationViewController.m中

-(void) doSegue {
NSLog(@"doSegue loaded");
[self performSegueWithIdentifier:@"SetLocationViewControllerManualUnwind" sender:self];
}

Calling doSegue from an action on SetLocationViewController.m does work so I know my segue is ok but the above doesn't work. 从SetLocationViewController.m上的操作调用doSegue确实可以,所以我知道我的命令是可以的,但是以上方法不起作用。 I get the error reason: 'Receiver () has no segue with identifier 'SetLocationViewControllerManualUnwind'' 我收到错误原因:'Receiver()与标识符'SetLocationViewControllerManualUnwind'没有关联

I'm guessing the reason is because of the alloc init way of initialising of the VC, but I don't know any better. 我猜测原因是由于VC初始化的alloc init方式,但是我不知道有什么更好的方法。 Thus, how can I call a function on another class as if it was being called by it's own class? 因此,如何在另一个类上调用函数,就像它是由自己的类调用一样?

Create a delegate it would be much more reliable and fast than Notifications. 创建一个委托,它将比通知更加可靠和快捷。

@protocol APIPostDelegate <NSObject>
@required
-(void)OnRequestSucess;
@end

In your APIPost add new property for delegate 在您的APIPost中添加代表的新属性

@interface APIPost : NSObject

@property (weak) id<APIPostDelegate> delegate;

In SetLocationViewController implement APIPostDelegate 在SetLocationViewController中实现APIPostDelegate

SetLocationViewController.h SetLocationViewController.h

SetLocationViewController :NSObject<APIPostDelegate>

SetLocationViewController.m SetLocationViewController.m

-(void)OnRequestSucess
{
   [self doSegue];
}

before you make call to method on APIPost, assign self to delegate property. 在APIPost上调用方法之前,请将self分配给委托属性。

APIPost *apipost=[[APIPost alloc]init];
apipost.delegate=self;

[apipost <your api method>];

APIPost.m APIPost.m

[self.delegate OnRequestSucess];

Hope this helps. 希望这可以帮助。

There are a few methods to make it happens:- 有几种方法可以实现:-

  1. Use Delegate 使用Delegate
  2. Use NSNotification . 使用NSNotification
  3. The way described by Artur above (For SplitViewController Only - iPad) 上面Artur所描述的方式(仅适用于SplitViewController -iPad)

You should use delegate whenever it is possible but it might not be too straight forward. 您应该尽可能使用委托,但可能不会太直接。 NSNotification is more straight forward but it is not a good practice and not a good programming style. NSNotification更直接,但这不是一个好习惯,也不是一个好的编程风格。

I will only share the NSNotification method as it is easier to implement. 我将只分享NSNotification方法,因为它更易于实现。

In SetLocationViewController.m SetLocationViewController.m中

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSegue) name:@"calldoSegue" object:nil];
}

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"calldoSegue" object:nil];
}

-(void) doSegue {
    NSLog(@"doSegue loaded");
    [self performSegueWithIdentifier:@"SetLocationViewControllerManualUnwind" sender:self];
}

In APIPostClass.m APIPostClass.m中

-(void)callWhenDone {
    NSLog(@"callWhenDone loaded.");
    [[NSNotificationCenter defaultCenter]postNotificationName:@"calldoSegue" object:nil];
}

The above code should work but again, this is not a good practice. 上面的代码应该可以正常工作,但这不是一个好习惯。 You should try to learn the Delegate method. 您应该尝试学习Delegate方法。

The answer is here: Performing segue from another class 答案就在这里: 从另一堂课开始表演

In my APIPostClass.h, I setup the view controller: 在我的APIPostClass.h中,我设置了视图控制器:

@interface APIPostClass : NSObject  {
    SetLocationViewController *setLocationViewController;
}

@property(nonatomic, strong) SetLocationViewController *setLocationViewController;

@end

In my APIPostClass.m, I synthesize it: 在我的APIPostClass.m中,我将其合成:

@synthesize setLocationViewController;

then, instead of this (as in my question): 然后,代替这个(就像我的问题一样):

-(void)callWhenDone {
NSLog(@"callWhenDone loaded.");

SetLocationViewController *SLVClassInstance = [[SetLocationViewController alloc] init];
[SLVClassInstance doSegue];
}

I have: 我有:

-(void)callWhenDone {
    NSLog(@"callWhenDone loaded");
    [self.setLocationViewController doSegue];
}

Over in SetLocationViewController.m, the segue method remains unchanged: 在SetLocationViewController.m中,segue方法保持不变:

-(void) doSegue {
NSLog(@"doSegue loaded");
[self performSegueWithIdentifier:@"SetLocationViewControllerManualUnwind" sender:self];
}

But when I call my API, I need to "attach" (forgive my terminology) the view controller to it. 但是,当我调用我的API时,我需要“附加”(原谅我的术语)视图控制器。 This is what I had: 这就是我所拥有的:

- (IBAction)btnTestAPICall:(id)sender {
    NSLog(@"User tapped API button");

    APIPostClass *APIPostClassInstance = [[APIPostClass alloc] init];
    [APIPostClassInstance APICall: ... ....
}

But this is what works after bringing all of the above: 但这是在满足以上所有条件后起作用的:

- (IBAction)btnTestAPICall:(id)sender {
    NSLog(@"User tapped API button");

    APIPostClass *APIPostClassInstance= [[APIPostClass alloc] init];

    UIViewController *currentVC=self;
    APIPostClassInstance.setLocationViewController = currentVC;

    [APIPostClassInstance APICall: ... ...

I hope this will help someone else! 我希望这会帮助别人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否可以从另一个类调用performSegueWithIdentifier? - Is it possible to call a performSegueWithIdentifier from another class? 从didFinishPickingMediaWithInfo调用performSegueWithIdentifier - Call performSegueWithIdentifier from didFinishPickingMediaWithInfo 如何从XIB调用performSegueWithIdentifier? - How to call performSegueWithIdentifier from xib? 无法从UITableViewCell调用performSegueWithIdentifier - Cannot call performSegueWithIdentifier from a UITableViewCell 从一个类调用函数到另一类 - Call the function from one class to another class performSegueWithIdentifier无法在回调函数中工作? - performSegueWithIdentifier not work in call-back function? 如何从视图的子视图的视图的自定义类中调用performSegueWithIdentifier? - How to call performSegueWithIdentifier from within a custom class of a view that's a subview of view controller? 从AppDelegate调用之后,performSegueWithIdentifier NSInvalidArgumentException - performSegueWithIdentifier NSInvalidArgumentException after call from AppDelegate 使用performSegueWithIdentifier从TableViewCell导航到另一个视图 - Navigating from TableViewCell to another View with performSegueWithIdentifier SWIFT:如何使用来自不同类的performSegueWithIdentifier - SWIFT: how to use performSegueWithIdentifier from different class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM