无法调用委托方法

时间:2014-12-12 10:46:11

标签: ios objective-c delegates

在我的应用程序中,我有一个视图控制器,其中有一个表视图,当我点击其中一个表视图行时,它应该忽略实际的视图控制器传回一个URL以在Web视图中加载它。我认为正确的方法是实现一个委托,所以我做了但是当我尝试运行应用程序时,当我点击表视图的行时,它不会调用委托方法。 我在这里添加了一些代码来理解错误:

HistoryNotificationViewController.h

#import <UIKit/UIKit.h>

@protocol HistoryNotificationDelegate;

@interface HistoryNotificationViewController : UIViewController

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

@end

@protocol HistoryNotificationDelegate <NSObject>

- (void) updateWebViewWithURL:(NSString*)url;

@end

HistoryNotificationViewController.m (我只发布我调用委托方法的方法)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.delegate updateWebViewWithURL:[sortedArray[indexPath.row] objectForKey:@"url"]];
    [self dismissViewControllerAnimated:YES completion:nil];
}

HomeViewController.m (查看应该实现HistoryNotificationViewController.m的委托方法的控制器)

#import "HomeViewController.h"
#import "SSKeychain.h"
#import "SSKeychainQuery.h"
#import "MBProgressHUD.h"
#import "HistoryNotificationViewController.h"

#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

@interface HomeViewController () <UIWebViewDelegate, HistoryNotificationDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webView;
- (IBAction)buttonForward:(UIButton *)sender;
- (IBAction)buttonBack:(UIButton *)sender;
@property(nonatomic,strong)MBProgressHUD *hud;

@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.hud = [[MBProgressHUD alloc]init];
    self.hud.labelText = @"Loading";
    self.hud.mode = MBProgressHUDModeIndeterminate;
    [self.view addSubview:self.hud];

    NSURL *url = [[NSURL alloc]init];
    NSURLRequest *request = [[NSURLRequest alloc]init];

    if (!self.website) {
        url = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] objectForKey:@"website" ]];
        request = [NSURLRequest requestWithURL:url];
    } else {
        [[NSUserDefaults standardUserDefaults] setObject:self.website forKey:@"website"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        url = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] objectForKey:@"website"]];
        request = [NSURLRequest requestWithURL:url];
    }
    [self.webView loadRequest:request];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    HistoryNotificationViewController *historyNotificationViewController = [[HistoryNotificationViewController alloc]init];
    [historyNotificationViewController setDelegate:self];   
}

#pragma mark HistoryNotificationDelegate
- (void)updateWebViewWithURL:(NSString *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self.webView loadRequest:request];
}

#pragma mark UIWebViewDelegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
    [self.hud show:YES];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.hud hide:YES];
}


- (IBAction)buttonForward:(UIButton *)sender {
    [self.webView goForward];
}

- (IBAction)buttonBack:(UIButton *)sender {
    [self.webView goBack];
}
@end

我班上有什么问题?为什么它不执行委托方法?

3 个答案:

答案 0 :(得分:2)

试试这个,

通过

HistoryNotificationViewController创建一个属性
@property (nonatomic, strong) HistoryNotificationViewController *historyNotificationViewController;

并在prepareForSegue :

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    UIViewController *destinationVC = [segue destinationViewController];
    if ([destinationVC isKindOfClass:[HistoryNotificationViewController class]]) {

        self.historyNotificationViewController = destinationVC;
        [self.historyNotificationViewController setDelegate:self]; 
    }
}

答案 1 :(得分:1)

您需要从destinationViewController获取prepareForSegue中的HistoryNotificationViewControllers,而不是分配新对象...

#import "HomeViewController.h"
#import "SSKeychain.h"
#import "SSKeychainQuery.h"
#import "MBProgressHUD.h"
#import "HistoryNotificationViewController.h"

#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

@interface HomeViewController () <UIWebViewDelegate, HistoryNotificationDelegate>{

}
@property (weak, nonatomic) IBOutlet UIWebView *webView;
- (IBAction)buttonForward:(UIButton *)sender;
- (IBAction)buttonBack:(UIButton *)sender;
@property(nonatomic,strong)MBProgressHUD *hud;

@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.hud = [[MBProgressHUD alloc]init];
    self.hud.labelText = @"Loading";
    self.hud.mode = MBProgressHUDModeIndeterminate;
    [self.view addSubview:self.hud];

    NSURL *url = [[NSURL alloc]init];
    NSURLRequest *request = [[NSURLRequest alloc]init];

    if (!self.website) {
        url = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] objectForKey:@"website" ]];
        request = [NSURLRequest requestWithURL:url];
    } else {
        [[NSUserDefaults standardUserDefaults] setObject:self.website forKey:@"website"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        url = [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] objectForKey:@"website"]];
        request = [NSURLRequest requestWithURL:url];
    }
    [self.webView loadRequest:request];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"YOUR_SEGUE_NAME_HERE_FOR_HISTORY_NOTIFICATION_VIEWCONTROLLER"])
    {
        // Get reference to the destination view controller
        HistoryNotificationViewController *vc = [segue destinationViewController];

        // Pass any objects to the view controller here, like...
        [vc setDelegate:self];
    }
}


#pragma mark HistoryNotificationDelegate
- (void)updateWebViewWithURL:(NSString *)url {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self.webView loadRequest:request];
}

#pragma mark UIWebViewDelegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
    [self.hud show:YES];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.hud hide:YES];
}


- (IBAction)buttonForward:(UIButton *)sender {
    [self.webView goForward];
}

- (IBAction)buttonBack:(UIButton *)sender {
    [self.webView goBack];
}

答案 2 :(得分:0)

在这种情况下,您根本不需要也不应该使用delegate。否则你会让事情变得复杂。

只需在HomeViewController

中定义公开方法即可
- (void)updateWebViewWithURL:(NSString *)url 
{

}

与您定义的方法名称相同的方法名称应该没问题,但不能作为委托方法!

然后,在HistoryNotificationViewController.m中,您将能够轻松获得HomeViewController的引用。这样的事情会发生,

NSArray *viewControllers = self.navigationController.viewControllers;
    HomeViewController *homeViewController = [viewControllers objectAtIndex:0];
    [homeViewController updateWebViewWithURL:url];