我有一个非常简单的UIWebView,包含我的应用程序包中的内容。我想任何链接在web视图中打开Safari而不是在web视图。这可能吗?


当前回答

应用拒绝

最后,UIWbView已经死了,苹果将不再接受它。

苹果开始给所有还在使用UIWebView的App所有者发邮件:

弃用API使用——苹果将停止接受使用UIWebView API的应用程序提交。

苹果非常重视用户隐私,很明显他们不会允许不安全的webview。

所以要尽快从你的应用中移除UIWebView。不要尝试在新创建的应用程序中使用UIWebView,如果可能的话,我更喜欢使用WKWebView

ITMS-90809:废弃的API使用-苹果将停止接受 提交使用UIWebView api的应用程序。看到 https://developer.apple.com/documentation/uikit/uiwebview获取更多信息 信息。

例子:

import UIKit
import WebKit

class WebInfoController: UIViewController,WKNavigationDelegate {

    var webView : WKWebView = {
        var webview = WKWebView()
        return webview
    }()

    var _fileName : String!

    override func viewDidLoad() {
        self.view.addSubview(webView)
        webView.fillSuperview()
        let url = Bundle.main.url(forResource: _fileName, withExtension: "html")!
        webView.loadFileURL(url, allowingReadAccessTo: url)
        let request = URLRequest(url: url)
        webView.load(request)
    }


    func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
        print(error.localizedDescription)
    }
    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("Strat to load")
    }
    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
        print("finish to load")
    }
}

其他回答

其他答案有一个问题:它们依赖于你所做的操作,而不是链接本身来决定是在Safari中加载还是在webview中加载。

有时候这正是你想要的,这很好;但有些时候,特别是当你的页面中有锚点链接时,你想在Safari中只打开外部链接,而不是内部链接。在这种情况下,您应该检查URL。请求的主机属性。

我使用这段代码来检查正在解析的URL中是否有主机名,或者它是否是嵌入的html:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    static NSString *regexp = @"^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9])[.])+([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9])$";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regexp];

    if ([predicate evaluateWithObject:request.URL.host]) {
        [[UIApplication sharedApplication] openURL:request.URL];
        return NO; 
    } else {
        return YES; 
    }
}

当然,您可以调整正则表达式以满足您的需要。

应用拒绝

最后,UIWbView已经死了,苹果将不再接受它。

苹果开始给所有还在使用UIWebView的App所有者发邮件:

弃用API使用——苹果将停止接受使用UIWebView API的应用程序提交。

苹果非常重视用户隐私,很明显他们不会允许不安全的webview。

所以要尽快从你的应用中移除UIWebView。不要尝试在新创建的应用程序中使用UIWebView,如果可能的话,我更喜欢使用WKWebView

ITMS-90809:废弃的API使用-苹果将停止接受 提交使用UIWebView api的应用程序。看到 https://developer.apple.com/documentation/uikit/uiwebview获取更多信息 信息。

例子:

import UIKit
import WebKit

class WebInfoController: UIViewController,WKNavigationDelegate {

    var webView : WKWebView = {
        var webview = WKWebView()
        return webview
    }()

    var _fileName : String!

    override func viewDidLoad() {
        self.view.addSubview(webView)
        webView.fillSuperview()
        let url = Bundle.main.url(forResource: _fileName, withExtension: "html")!
        webView.loadFileURL(url, allowingReadAccessTo: url)
        let request = URLRequest(url: url)
        webView.load(request)
    }


    func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
        print(error.localizedDescription)
    }
    func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("Strat to load")
    }
    func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
        print("finish to load")
    }
}

对user306253的回答的一个快速评论:小心,当你自己尝试在UIWebView中加载一些东西时(即即使从代码中加载),这个方法将防止它发生。

你能做什么来防止这种情况(感谢韦德):

if (inType == UIWebViewNavigationTypeLinkClicked) {
    [[UIApplication sharedApplication] openURL:[inRequest URL]];
    return NO;
}

return YES;

你可能还想处理UIWebViewNavigationTypeFormSubmitted和UIWebViewNavigationTypeFormResubmitted类型。

在我的例子中,我想确保web视图中的所有东西都能打开Safari,除了初始加载,所以我使用。

- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
     if(inType != UIWebViewNavigationTypeOther) {
        [[UIApplication sharedApplication] openURL:[inRequest URL]];
        return NO;
     }
     return YES;
}

公认的答案行不通。

如果你的页面通过Javascript加载url, navigationType将是UIWebViewNavigationTypeOther。不幸的是,这也包括后台页面加载,如分析。

要检测页面导航,需要比较[request URL]和[request mainDocumentURL]。

这个解决方案将在所有情况下工作:

- (BOOL)webView:(UIWebView *)view shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)type
{
    if ([[request URL] isEqual:[request mainDocumentURL]])
    {
        [[UIApplication sharedApplication] openURL:[request URL]];
        return NO;
    }
    else
    {       
        return YES;
    }
}