Reputation: 2002
In my app I've a view controller in which there are a table view, when I tap on one of table view row it should dismiss the actual view controller an pass back an url to load it in a web view. I thought the right way to do that it's to implement a delegate, so I did it but when I try to run the app when I tap on the row of table view it doesn't call the delegate method. I add here some code to understand what's wrong:
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 (I post only the method in which I call the delegate method)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.delegate updateWebViewWithURL:[sortedArray[indexPath.row] objectForKey:@"url"]];
[self dismissViewControllerAnimated:YES completion:nil];
}
HomeViewController.m (view controller that should implement the delegate method of 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
What's wrong in my classes? Why it doesn't execute the delegate method?
Upvotes: 0
Views: 299
Reputation: 8461
You do not need and should not use delegate
at all in this case. Otherwise you're making thing complicated.
Just define a public method in your HomeViewController
,
- (void)updateWebViewWithURL:(NSString *)url
{
}
Same method name as the one you've defined should be ok, but not as a delegate method!
Then, in your HistoryNotificationViewController.m
, you'll be able to get a reference of HomeViewController
easily. Something like this will do,
NSArray *viewControllers = self.navigationController.viewControllers;
HomeViewController *homeViewController = [viewControllers objectAtIndex:0];
[homeViewController updateWebViewWithURL:url];
Upvotes: 0
Reputation: 11
You need to get HistoryNotificationViewControllers in prepareForSegue from destinationViewController instead of allocating a new object...
#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];
}
Upvotes: 1
Reputation: 5182
Try this,
Make a property for HistoryNotificationViewController
by
@property (nonatomic, strong) HistoryNotificationViewController *historyNotificationViewController;
and in prepareForSegue :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIViewController *destinationVC = [segue destinationViewController];
if ([destinationVC isKindOfClass:[HistoryNotificationViewController class]]) {
self.historyNotificationViewController = destinationVC;
[self.historyNotificationViewController setDelegate:self];
}
}
Upvotes: 2