Загрузка NSURLRequest на webView из другого класса.
Я создал контроллер представления с webView в раскадровке под названием GoogleSearchController. Свойство для webView, конечно же, было объявлено в GoogleSearchController.
Я пытаюсь получить доступ к синтезированному свойству webView, которое является *googleWebView, в MapViewController, чтобы я мог добавить свои точечные аннотации к поиску Google. Вывод здесь правильный. Я получаю добавленный и нужный URL, но мне не удается его загрузить. В конце метода leftButtonAnnotationPressed вы заметите, что я пытаюсь вызвать loadRequest для self.classObj.googleWebView. Что-то идет не так, как должно. Это первый раз, когда я пытался использовать @synthesize, и я открыт для всех предложений.
Мой вопрос состоит из двух частей. A: я использую @synthesize, как это задумано? и B: Если это правильное использование, почему мой webView не загружает запрос?
GoogleSearchController.h
@interface GoogleSearchController : UIViewController <UIWebViewDelegate>
@property (strong, nonatomic) IBOutlet UIWebView *googleWebView;
@end
GoogleSearchController.m
@synthesize googleWebView;
- (void)viewDidLoad {
[super viewDidLoad];
self.googleWebView = [[UIWebView alloc] init];
self.googleWebView.delegate = self;
}
MapViewController.m
@property (nonatomic, strong) GoogleSearchController *classObj;
-(void)leftButtonAnnotationPressed:(UIButton *)sender {
[self performSegueWithIdentifier:@"googleSearch" sender:nil];
self.classObj = [[GoogleSearchController alloc] init]; <--------
MKPointAnnotation *annotation = [self.mapView.selectedAnnotations objectAtIndex:([self.mapView.selectedAnnotations count]) -1];
NSString *appendString = annotation.title;
NSString *googleString = @"http://www.google.com/search?q=";
NSString *appendedUrlString = [googleString stringByAppendingString:appendString];
if ([appendedUrlString containsString:@" "]) {
appendedUrlString = [appendedUrlString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
NSURL *url = [NSURL URLWithString:appendedUrlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.classObj.googleWebView loadRequest:request];<------
NSLog(@"appended string: %@", request);
}
2 ответа
Хранение NSURLRequest в источнике данных казалось довольно простым решением. В DataSource.h все, что мы делали, это объявляли открытое свойство типа NSURLRequest * searchURL.
+(instancetype) sharedInstance;
@property (nonatomic, strong) NSURLRequest *searchURL;
SharedInstance будет использоваться для нашего одноэлементного шаблона, который гарантирует, что мы получим только один экземпляр нашего DataSource. В DataSource.m мы будем реализовывать наш sharedInstance следующим образом: (который для части публикации является учебником).
+ (instancetype) sharedInstance {
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Это все, что нам нужно для хранения нашего NSURLRequest.
В MapViewController мы используем нашу sharedInstance для доступа к свойству NSURLRequest из DataSource и устанавливаем его равным добавленному NSURLRequest.
- (void) leftAnnotationButtonPressed:(UIButton *)sender {
MKPointAnnotation *annotation = [self.mapView.selectedAnnotations objectAtIndex:([self.mapView.selectedAnnotations count]) -1];
NSString *appendString = annotation.title;
NSString *googleString = @"http://www.google.com/search?q=";
NSString *appendedUrlString = [googleString stringByAppendingString:appendString];
if ([appendedUrlString containsString:@" "]) {
appendedUrlString = [appendedUrlString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
NSURL *url = [NSURL URLWithString:appendedUrlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[DataSource sharedInstance].searchURL = request; <----
NSLog(@"appended string: %@", request);
}
[self performSegueWithIdentifier:@"googleSearch" sender:nil];
}
Осталось только загрузить webView. Это можно сделать ввиду того, что загрузил в GoogleSearchController, где находится это свойство. (который снимает всю головную боль).
- (void)viewDidLoad {
[super viewDidLoad];
[self.googleWebView loadRequest:[DataSource sharedInstance].searchURL];
}
Все, что мы делаем здесь, это просто вызываем loadRequest в нашем веб-представлении с NSURLRequest, который теперь хранится в нашем источнике данных. И мы закончили. Мне нравится этот подход, и я надеюсь, что кто-нибудь еще, читающий это, сделает это. Вы даже получите небольшой урок о синглетах и источнике данных.
@sythesize
больше не требуется / обязательно. Без @synthesize
iOS/XCode автоматически создаст переменную экземпляра для вас _[propertyName]
Если ваш UIWebView создан в IB, вам не нужно инициализировать его программно. Убедитесь, что ваше webView и свойство ViewController IBOutlet связаны. Этого должно быть достаточно.
Я думаю, что важная причина, по которой ваш запрос не загружается, заключается в том, что вы загружаете URL-адрес в другом экземпляре, чем тот, который отображается в вашем GoogleSearchViewController
Вы делаете это
[self performSegueWithIdentifier:@"googleSearch" sender:nil];
self.classObj = [[GoogleSearchController alloc] init]; <--------
в первой строке вы просите раскадровку выполнить переход. Итак, раскадровка создаст экземпляр контроллера представления с представлениями и всеми подпредставлениями и отображением.
Во второй строке вы создаете свой собственный экземпляр контроллера представления. Кто его отображает? -- Ни один. Никто.
Ваша загрузка URL в неправильном экземпляре.
Хорошо, теперь, как мне получить доступ к отображаемому контроллеру представления?
Xcode / iOS дает вам возможность сделать это с prepareForSegue
Вы можете получить доступ к VC и веб-представлению, как показано ниже, чтобы загрузить запрос.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:@"googleSearch"]){
GoogleSearchViewController *vc = nil;
if([segue.destinationViewController isKindOfClass:[UINavigationController class]]){
UINavigationController *navVC = (UINavigationController *)segue.destinationViewController;
vc = (GoogleSearchViewController *)navVC.viewControllers[0];
}else{
vc = segue.destinationViewController;
}
if(vc){
NSURL *url = [NSURL URLWithString:appendedUrlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[vc.googleWebView loadRequest:request];
}
}
}
Было бы интересно узнать, сработало ли это для вас