ios 强制 WebView 链接启动 Safari?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2532453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:04:23  来源:igfitidea点击:

Force a WebView link to launch Safari?

iphoneiosuiwebviewmobile-safari

提问by tbacos

I have a UIWebView embedded within an iPhone app of mine. I want to be able to have certain links within that webview open into the full Mobile Safari app (i.e. not my embedded version of it).

我在我的 iPhone 应用程序中嵌入了一个 UIWebView。我希望能够将该 webview 中的某些链接打开到完整的 Mobile Safari 应用程序中(即不是我的嵌入式版本)。

Is there a simple way to structure some of my hrefs to force this, instead of every link opening within my embedded webview?

有没有一种简单的方法来构造我的一些 href 来强制执行此操作,而不是在我的嵌入式 web 视图中打开每个链接?

Thanks.

谢谢。

回答by Brad Larson

To expand upon what Randy said, this is what I use in my application to make every http://, https://, and mailto:// URL open in the external Safari or Mail applications:

为了扩展 Randy 所说的内容,这就是我在我的应用程序中使用的内容,用于在外部 Safari 或邮件应用程序中打开每个 http://、https:// 和 mailto:// URL:

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 
{
    NSURL *requestURL =[ [ request URL ] retain ]; 
    if ( ( [ [ requestURL scheme ] isEqualToString: @"http" ] || [ [ requestURL scheme ] isEqualToString: @"https" ] || [ [ requestURL scheme ] isEqualToString: @"mailto" ]) 
        && ( navigationType == UIWebViewNavigationTypeLinkClicked ) ) { 
        return ![ [ UIApplication sharedApplication ] openURL: [ requestURL autorelease ] ]; 
    } 
    [ requestURL release ]; 
    return YES; 
}

As Randy says, you'll want to implement this within whatever class you set to be the delegate of the UIWebView. To have only select URLs launch Safari, you could change their scheme from http:// to safari://, or something similar, and only kick those URLs off to the system (after replacing the custom URL scheme with http://).

正如 Randy 所说,您将希望在您设置为 UIWebView 的委托的任何类中实现它。要仅选择 URL 启动 Safari,您可以将其方案从 http:// 更改为 safari:// 或类似内容,并且只将这些 URL 踢到系统中(在将自定义 URL 方案替换为 http:// 之后) .

I do this within my internal help documentation, which is HTML displayed in a UIWebView, so that I don't run into issues in the review process with having a general-purpose web browser embedded in my application.

我在我的内部帮助文档中执行此操作,该文档是显示在 UIWebView 中的 HTML,这样我就不会在过程中遇到在我的应用程序中嵌入通用 Web 浏览器的问题。

回答by aqm

Ok I got it. Maybe its not the perfect solution, but you can do it like this:

好,我知道了。也许它不是完美的解决方案,但你可以这样做:

Only in your WebViewController.m:

仅在您的WebViewController.m

add the line webView.delegate = self;to the viewDidLoadprocedure:

将这一行添加webView.delegate = self;viewDidLoad程序中:

- (void)viewDidLoad {
    webView.delegate = self;
    .... your code ....
}

Then you can add as described above somewhere in the Controller.mFile following boolean resulting function:

然后,您可以按照上述Controller.m布尔结果函数在File 中的某处添加 :

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if (navigationType == UIWebViewNavigationTypeLinkClicked) {
        [[UIApplication sharedApplication] openURL:request.URL];
        return false;
    }
    return true;
}

回答by Randy Simon

I haven't tried this myself but I think that you can implement the UIWebViewDelegate method

我自己没有尝试过,但我认为你可以实现 UIWebViewDelegate 方法

webView:shouldStartLoadWithRequest:navigationType 

which will be called anytime a link in the UIWebView is clicked on. In that method you just need to determine if the clicked link should result in launching Safari or not and use openURL if it should.

任何时候点击 UIWebView 中的链接都会调用它。在该方法中,您只需要确定单击的链接是否应导致启动 Safari,并在应该时使用 openURL。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    // Check if this was a click event and then some other criteria for determining if you want to launch Safari.
    if (navigationType == UIWebViewNavigationTypeLinkClicked && [Some other criteria]) {
        [[UIApplication sharedApplication] openURL:request.URL];

        // Return false to indicate to the UIWebView to not navigate to the linked target
        return false;
    }

    // Return true so that the UIWebView loads the link target
    return true;
}

Don't forget that you need to set your UIWebView delegate property to an instance of the class that implements the UIWebViewDelegate.

不要忘记,您需要将 UIWebView 委托属性设置为实现 UIWebViewDelegate 的类的实例。

回答by Dwight Mix

This is how we solved it, add this to your ViewController.m file:

这就是我们解决它的方法,将其添加到您的 ViewController.m 文件中:

    - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    first.delegate = (id)self;
                [first loadRequest:[NSURLRequest requestWithURL:[NSURL     URLWithString:@"http://my.FellowshipNWA.org?publicapp"]]];
}

// Add section below so that external links & PDFs will open in Safari.app
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request     navigationType:(UIWebViewNavigationType)navigationType {
    if (navigationType == UIWebViewNavigationTypeOther) {
        NSString *checkURL = @"http://my.fellowshipnwa.org/?givenowsafari";
        NSString *reqURL = request.URL.absoluteString;
        if ([reqURL isEqualToString:checkURL])
             {
                 [[UIApplication sharedApplication] openURL:request.URL];
            return false;
    }
        else {
            return true;
        }
    }
    return true;
}

回答by Carl Sharman

Swift version of Brad Larson's answer:

Brad Larson 答案的 Swift 版本:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {

    var url: NSURL = request.URL!
    var isExternalLink: Bool = url.scheme == "http" || url.scheme == "https" || url.scheme == "mailto"
    if (isExternalLink && navigationType == UIWebViewNavigationType.LinkClicked) {
        return !UIApplication.sharedApplication().openURL(request.URL!)
    } else {
        return true
    }
}