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

时间:2014-06-15 04:29:45

标签: ios objective-c xcode

我花了几个小时试图自己解决这个问题,但我放弃了!

我有一个主 - 细节安排,其中用户输入屏幕需要调用另一个类上的函数以发布到Web服务。完成异步调用后,该类将调用指定的函数。在这种情况下,我只是进行测试,我想要做的就是在Web服务接受用户输入后返回主屏幕。

当用户点击输入屏幕上的按钮(SetLocationViewController)时,将在类APIPostClass中调用异步操作。完成后,我希望SetLocationViewController能够转回MasterViewController。

在APIPostClass.m中(在异步操作完成后调用)

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

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

在SetLocationViewController.m

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

从SetLocationViewController.m上的一个动作调用doSegue确实有效,所以我知道我的segue没问题但是上面的工作没有用。我得到错误原因:' Receiver()没有带标识符的segue' SetLocationViewControllerManualUnwind''

我猜测原因是因为初始化VC的alloc init方式,但我不知道更好。因此,我如何在另一个类上调用一个函数,好像它被它自己的类调用一样?

3 个答案:

答案 0 :(得分:3)

创建一个委托,它比通知更可靠,更快。

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

在您的APIPost中为代理添加新属性

@interface APIPost : NSObject

@property (weak) id<APIPostDelegate> delegate;

在SetLocationViewController中实现APIPostDelegate

<强> SetLocationViewController.h

SetLocationViewController :NSObject<APIPostDelegate>

SetLocationViewController.m

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

在调用APIPost上的方法之前,将self分配给delegate属性。

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

[apipost <your api method>];

<强> APIPost.m

[self.delegate OnRequestSucess];

希望这有帮助。

答案 1 :(得分:0)

有几种方法可以实现: -

  1. 使用Delegate
  2. 使用NSNotification
  3. 以上Artur描述的方式(仅适用于SplitViewController - iPad)
  4. 您应该尽可能使用委托,但可能不会太直接。 NSNotification更直接,但这不是一个好习惯,也不是一个好的编程风格。

    我只会共享NSNotification方法,因为它更容易实现。

    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];
    }
    

    APIPostClass.m

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

    上述代码应该可以工作,但这不是一个好习惯。您应该尝试学习Delegate方法。

答案 2 :(得分:0)

答案在这里:Performing segue from another class

在我的APIPostClass.h中,我设置了视图控制器:

@interface APIPostClass : NSObject  {
    SetLocationViewController *setLocationViewController;
}

@property(nonatomic, strong) SetLocationViewController *setLocationViewController;

@end

在我的APIPostClass.m中,我合成了它:

@synthesize setLocationViewController;

然后,而不是这(在我的问题中):

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

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

我有:

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

在SetLocationViewController.m中,segue方法保持不变:

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

但是当我调用我的API时,我需要&#34;附加&#34; (原谅我的术语)视图控制器。这就是我所拥有的:

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

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

但这是在带来以上所有内容之后的作用:

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

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

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

    [APIPostClassInstance APICall: ... ...

我希望这能帮助别人!