从另一个 class 加载 webView 上的 NSURLRequest。

Loading NSURLRequest on webView from a different class.

我在故事板中创建了一个带有 webView 的视图控制器,名为 GoogleSearchController。当然,webView 的 属性 是在 GoogleSearchController 中声明的。

我正在尝试访问 MapViewController 中的合成 webView 属性,即 *googleWebView,以便我可以将我的点注释附加到 google 搜索。这里的输出是正确的。我得到了附加的和想要的 URL,但我没有真正加载它。在 leftButtonAnnotationPressed 方法的末尾,您会注意到我尝试在 self.classObj.googleWebView 上调用 loadRequest。有些事情没有按预期进行。这是我第一次尝试使用@synthesize,我愿意接受所有建议。

我的问题分为两部分。答:我是否按预期使用了@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);

}

@sythesize 不再是 required/mandatory。没有 @synthesize iOS/XCode 会自动为你创建一个实例变量 _[属性Name]

如果您的 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];

        }
    }

}

想知道这是否适合您

将 NSURLRequest 存储在数据源中似乎是一个相当简单的解决方案。在 DataSource.h 中,我们所做的只是声明一个类型为 NSURLRequest *searchURL 的 public 属性。

+(instancetype) sharedInstance;

@property (nonatomic, strong) NSURLRequest *searchURL;

sharedInstance 将用于我们的单例模式,这确保我们只获得一个 DataSource 实例。在 DataSource.m 中,我们将像这样实现我们的 sharedInstance:(post 部分是教科书)。

+ (instancetype) sharedInstance {
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });

    return sharedInstance;
}

这就是我们存储 NSURLRequest 所需的全部内容。

在 MapViewController 中,我们使用 sharedInstance 从 DataSource 中访问 NSURLRequest 属性 并将其设置为等于附加的 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];
}

我们在这里所做的只是使用现在存储在数据源中的 NSURLRequest 在我们的 webView 上调用 loadRequest。我们完成了。我喜欢这种方法,我希望阅读这篇文章的其他人也喜欢。您甚至可以学到一些关于单例和数据源的知识。