【问题标题】:UIWebView Delegate ConfusionUIWebView 委托混淆
【发布时间】:2016-05-04 10:58:22
【问题描述】:

在过去的几天里,我一直在研究 UIWebViews 和 Delegates,但我完全感到困惑。我想创建一个包含 Web 视图的故事板视图控制器。在 Web 视图中单击按钮时,我想根据对此的答案在视图控制器中触发一些代码:

How to invoke Objective C method from Javascript and send back data to Javascript in iOS?

但是我对如何设置我的委托感到困惑(老实说,我对委托是什么感到困惑,它是与视图控制器相关的 webview 吗?)。我一直在阅读和观看一些教程,但我并不真正理解这个过程,我认为我做得不对。这是我目前所拥有的。

MyViewController.h

#import <UIKit/UIKit.h>

@protocol MyViewControllerDelegate;

@interface MyViewController : UIViewController
@property (nonatomic, weak) id<MyViewControllerDelegate> delegate;

@property (strong, nonatomic) IBOutlet UIWebView *MyWebView;

@end

@protocol MyViewControllerDelegate <NSObject>

-(bool)myWebView:(UIWebView*)myWebView
shouldStartLoadWithRequest:(NSURLRequest*)request
                  navigationType:(UIWebViewNavigationType)navigationType;

@end

MyViewController.m

#import "MyViewController.h"

@interface MyViewController ()
@end

@implementation MyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [_MyWebView setDelegate:self];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewWillAppear:(BOOL)animated
{   
}

@end

我不太确定在哪里实现:

-(bool)myWebView:(UIWebView*)myWebView
shouldStartLoadWithRequest:(NSURLRequest*)request
                  navigationType:(UIWebViewNavigationType)navigationType;

应该去。

如果有人能提供帮助,将不胜感激。

【问题讨论】:

    标签: ios objective-c uiwebview delegates


    【解决方案1】:

    首先,您需要了解委托的概念。委托可以是一个对象,当在该对象中遇到事件或动作时,它可以代表另一个对象做出反应。

    例如,你可以有一个 UIViewController 里面有一个 UITbleView。 UIViewController 可以有一个 UITableViewDelegate。在这种情况下,所有 UITableViewDelegate 方法(heightForRow、ViewForFooter、didSelectRowAtIndexPath、...)都可以通过 UIViewController 实现。因此,例如,当一个单元格被选中时(didSelectRowAtIndexPath),UIViewController 可以查看选择了哪个单元格并决定如何处理该选择。

    在您的情况下,您的 UIViewController 中有一个 UIWebView 实例。您的 UIViewController 需要成为 UIWebView 的代表。

    @interface UIViewController () <UIWebViewDelegate>
    

    然后在 viewDidLoad 中将 UIWebView 属性的委托设置为您自己。

    [self.webView setDelegate:self];
    

    现在您可以在 viewController 中调用委托方法了。

    -(bool)myWebView:(UIWebView*)myWebView shouldStartLoadWithRequest (NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType;
    

    在您的视图控制器的 .m 文件中,并决定您想对从 Web 视图接收到的信息做什么。

    【讨论】:

    • 这是一个非常有用的解释!所以在我的例子中,有没有我不需要的东西?
    • 你是说在.m文件中我只是在@implementation中创建一个函数-(bool)myWebView:(UIWebView*)myWebView shouldStartLoadWithRequest (NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{ ... }
    • 您需要删除 @property (nonatomic, weak) id delegate; 并添加 @interface MyViewController : UIViewController 然后您可以实现 UIWebViewDelegate 的任何方法。您可以通过按住命令并单击 Xcode 上的 UIWebViewDelegate 名称来查看这些方法的列表。如果对您有帮助,请接受我的回答。
    • 那么如果视图控制器中有多个 webviews,这会代表它们控制操作吗?
    • 只要您将它们的代表全部设置为自己,就可以。然后,您将区分委托方法以查看正在调用哪个 webView: if (self.webview1) { //then do this ....} else { //do else}
    【解决方案2】:

    代表提供不同事件的沟通方式。当您使用给定的 url 加载 webview 时,就像上述方法一样。

    - (void)viewDidLoad {
        [super viewDidLoad];
        [_MyWebView setDelegate:self];
        NSString *urlString = @"http://google.com";
        //Create a URL object.
        NSURL *url = [NSURL URLWithString: urlString];
        //URL Request Object
        NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
        //Load the request in the UIWebView.
        [_MyWebView loadRequest:requestObj];
    }
    

    现在使用委托 webview 将与您的控制器进行通信。当 webview 将开始加载新框架时,它将调用您提到的上述方法。此方法的目的是获得您的许可,是否应该加载数据?在特定情况下,如果您不想加载 webView,则可以在此方法中返回 no。

    还有一些其他的委托方法可以更新你关于某些阶段的信息,比如如果 webview 已经加载了你提到的 url 的内容,它会通过调用这个方法告诉控制器。

    - (void)webViewDidFinishLoad:(UIWebView *)webView{
     //if you want to do anything else after loading the content of webview you can write code here. for example after loading the content you want to show a button on controller you can show it here. 
    }
    

    万一 webview 由于网络连接不足或 URL 无效或其他原因而无法加载网页或框架。它通过调用另一个委托方法告诉控制器。

    - (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{
    
    }
    

    【讨论】:

    • 感谢您的回答,我不想加载任何视图,但我希望能够调用一些objective-c 功能,然后继续我的下一个视图。我只是对如何在代码中实际实现这一点感到困惑。
    • 你为什么使用 UIWebView?你在里面装什么? Segues 可以通过使用单行来实现。假设您已使用 segue 将当前 viewController 与下一个 ViewController 链接起来,并且您有它的标识符。 [self performSegueWithIdentifier:@"NextViewSegueIdentifier" sender:self];
    • 我将 UIWebView 用于跨平台内容并通过 Web 应用程序方便地更新内容。但是我随后需要能够使用相机叠加层切换到视图,但它需要从 Web 视图中按下的按钮中获取一些信息。
    • 你能分享你需要从那个按钮获得什么样的信息吗?是您需要打开的下一个链接还是其他链接。
    • 我需要为初始屏幕获取图像的 url,然后我需要加载一个基于按钮的自定义覆盖的相机,然后我需要打开一个基于内容的新 Web 视图关于那个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 2013-01-25
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多