0

我正在尝试按照这个问题为登录序列设置一个委托:-如何设置一个简单的委托以在两个视图控制器之间进行通信?

在我的应用程序中,我有一个主视图(MESHomeViewController)。我还有一个登录结构如下:

  1. MESLoginNavController
  2. 带有 MESWelcomeViewController 的根视图控制器
  3. 还有可以推送到堆栈的 MESLoginViewController 和 MESSignupViewControllers。

我的目标是拥有一个仅在用户登录时调用的委托方法。我正在使用委托,因为我不能使用 viewDidLoad,因为视图经常在不同的场合重新加载/显示,所以我需要查看用户何时完成登录。

用户可以通过 Welcome 控制器(通过 Facebook)或登录控制器(通过普通方法)和 Signup(通过 signup ;)登录。

这是我试图在下面实现的: MESHomeViewController.h

#import "MESWelcomeViewController.h"

@interface MESHomeViewController : UIViewController <LoginViewControllerDelegate>

@end

MESHomeViewController.m中,我检查用户是否已登录,如果他们未完成以下操作:

NSLog(@"not logged in");
MESWelcomeViewController *loginNavVC = [self.storyboard instantiateViewControllerWithIdentifier:@"WelcomeVC"];
    loginNavVC.delegate = self;
[self presentModalViewController:loginNavVC animated:NO];

MESWelcomeViewController.h我有以下内容:

@protocol LoginViewControllerDelegate;

@interface MESWelcomeViewController : UIViewController <NSURLConnectionDataDelegate>

@property (nonatomic, weak) id<LoginViewControllerDelegate> delegate;

@end



@protocol LoginViewControllerDelegate <NSObject>

- (void)didLoginUser;

@end

一旦用户通过自定义方法完全登录。用户登录后,MESWelcomeViewController.m

   NSLog(@"%@",self.delegate);
    if ([self.delegate respondsToSelector:@selector(didLoginUser)]) {
        [self.delegate didLoginUser];
    }

但是,没有调用委托方法,对于welcomeViewController,self.delegate 似乎为空。我在想可能我应该根据上述设置将委托设置为登录导航控制器,但是我不确定如何从当前推送到导航上的视图控制器调用委托方法?

4

2 回答 2

0

要么你ViewController被它的容器释放,要么你delegate太快设置属性。

我建议将此添加到第一个视图控制器:

- (void) dealloc
{
  NSLog(@"deallocing");
}

只是为了排除第一个选项。

要检查第二个选项,请loginNavVC在设置后立即打印delegate,确保它不是nil.

于 2013-05-10T13:21:32.167 回答
0

所以只是为了确认一下,你有 MESHomeViewController,这是你的主要视图。从这里,您将 MESWelcomeViewController 推送到堆栈上。MESWelcomeViewController 可以执行一些登录操作,一旦完成,就会调用 [self.delegate didLoginUser]。

如果是这种情况,在初始化MESWelcomeViewController时,需要设置delegate。您可以通过多种方式轻松做到这一点。您可以为 MESWelcomeViewController 提供一个 init 函数,该函数接受一个 id

-(id) init:(id<LoginViewControllerDelegate>)myDelegate {
    self = [super init];
    if (self){
        self.delegate = myDelegate;
        etc...
    }
}

或者,在创建 MESWelcomeViewController 之后,但在推送它之前,设置委托属性

MESWelcomeViewController *welcomeView = [[MESWelcomeViewController alloc] init];
[welcomeView setDelegate:self];
// push view stuff

编辑:

我在那里提供的 init 函数不会自动调用,它必须显式调用而不是默认初始化程序。如果您使用情节提要,您可能应该使用设置委托属性的替代方法。我以前从未使用过情节提要,但您应该可以执行以下操作:

MESWelcomeViewController *welcomeView = [self.storyboard instantiateViewControllerWithIdentifier:@"WelcomeVC"];
[welcomeView setDelegate:self];
[self presentModalViewController:welcomeView animated:NO];

编辑 2:最好的选择是使用通知。任何想要监听的东西都会在 NSNotificationCenter 中添加一个观察者,当事件发生时,发布通知。

例子:

在 MESHomeViewController 的 initialize 或 viewDidLoad 中,放入以下内容:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLoginUser) name:@"LoginCompleteNotification" object:nil];

然后,每当您完成登录时,请执行以下操作:

[[NSNotificationCenter defaultCenter] postNotificationName:@"LoginCompleteNotification" object:nil];

最后,确保您停止在 Dealloc 中收听任何正在收听的内容

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LoginCompleteNotification object:nil]
于 2013-05-10T15:05:25.210 回答