Saya memiliki UIWebView yang sangat sederhana dengan konten dari bundel aplikasi saya. Saya ingin tautan apa pun dalam tampilan web dibuka di Safari alih-alih dalam tampilan web. Apakah ini mungkin?
Saya memiliki UIWebView yang sangat sederhana dengan konten dari bundel aplikasi saya. Saya ingin tautan apa pun dalam tampilan web dibuka di Safari alih-alih dalam tampilan web. Apakah ini mungkin?
Jawaban:
Tambahkan ini ke delegasi UIWebView:
(diedit untuk memeriksa jenis navigasi. Anda juga dapat melewati file://
permintaan yang merupakan tautan relatif)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Versi Swift:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}
Versi Swift 3:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.linkClicked {
UIApplication.shared.openURL(request.url!)
return false
}
return true
}
Versi Swift 4:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
guard let url = request.url, navigationType == .linkClicked else { return true }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return false
}
Memperbarui
Seperti yang openURL
telah ditinggalkan di iOS 10:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
UIApplication *application = [UIApplication sharedApplication];
[application openURL:[request URL] options:@{} completionHandler:nil];
return NO;
}
return YES;
}
switch
lebih disukai untuk tipe enum
Jika ada yang bertanya-tanya, solusi Drawnonward akan terlihat seperti ini di Swift :
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL)
return false
}
return true
}
UIWebViewDelegate
Satu komentar cepat untuk jawaban user306253: hati-hati dengan ini, ketika Anda mencoba memuat sesuatu di UIWebView sendiri (yaitu, bahkan dari kode), metode ini akan mencegahnya terjadi.
Yang dapat Anda lakukan untuk mencegah hal ini (terima kasih Wade) adalah:
if (inType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
Anda mungkin juga ingin menangani UIWebViewNavigationTypeFormSubmitted
dan UIWebViewNavigationTypeFormResubmitted
jenisnya.
Jawaban lain memiliki satu masalah: mereka bergantung pada tindakan yang Anda lakukan dan bukan pada tautan itu sendiri untuk memutuskan apakah akan memuatnya di Safari atau di tampilan web.
Sekarang kadang-kadang inilah yang Anda inginkan, yang baik-baik saja; tetapi di lain waktu, terutama jika Anda memiliki tautan jangkar di halaman Anda, Anda benar-benar ingin membuka hanya tautan eksternal di Safari, dan bukan yang internal. Dalam hal ini Anda harus memeriksa URL.host
properti permintaan Anda.
Saya menggunakan potongan kode itu untuk memeriksa apakah saya memiliki nama host di URL yang sedang diuraikan, atau apakah html yang disematkan:
- (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;
}
}
Tentu saja Anda dapat menyesuaikan ekspresi reguler agar sesuai dengan kebutuhan Anda.
if (request.URL?.scheme != "file")
Di Swift Anda dapat menggunakan kode berikut:
extension YourViewController: UIWebViewDelegate {
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
if let url = request.url, navigationType == UIWebView.NavigationType.linkClicked {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return false
}
return true
}
}
Pastikan Anda memeriksa nilai URL dan Tipe navigasi.
Inilah Xamarin iOS yang setara dengan jawaban drawonward.
class WebviewDelegate : UIWebViewDelegate {
public override bool ShouldStartLoad (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType) {
if (navigationType == UIWebViewNavigationType.LinkClicked) {
UIApplication.SharedApplication.OpenUrl (request.Url);
return false;
}
return true;
}
}
Jawaban yang diterima tidak berfungsi.
Jika halaman Anda memuat URL melalui Javascript, itu navigationType
akan menjadi UIWebViewNavigationTypeOther
. Yang, sayangnya, juga mencakup pemuatan laman latar belakang seperti analitik.
Untuk mendeteksi navigasi halaman, Anda perlu membandingkannya [request URL]
dengan [request mainDocumentURL]
.
Solusi ini akan berfungsi dalam semua kasus:
- (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;
}
}
Catatan penolakan aplikasi:
Akhirnya UIWbView
mati dan Apple tidak akan lagi menerimanya.
Apple mulai mengirim email ke semua pemilik Aplikasi yang masih menggunakan UIWebView
:
Penggunaan API yang Tidak Digunakan - Apple akan berhenti menerima pengiriman aplikasi yang menggunakan UIWebView
API.
Apple memperlakukan Privasi Pengguna dengan sangat serius dan jelas bahwa mereka tidak akan mengizinkan tampilan web yang tidak aman .
Jadi jangan hapus UIWebView dari aplikasi Anda sesegera mungkin. jangan gunakan coba gunakan UIWebView
di aplikasi baru yang dibuat dan saya lebih suka menggunakan WKWebView
jika mungkin
ITMS-90809: Penggunaan API yang Tidak Digunakan - Apple akan berhenti menerima pengajuan aplikasi yang menggunakan API UIWebView. Lihat https://developer.apple.com/documentation/uikit/uiwebview untuk informasi lebih lanjut.
Contoh:
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")
}
}
Dalam kasus saya, saya ingin memastikan bahwa semua yang ada di tampilan web membuka Safari kecuali beban awal dan jadi saya menggunakan ...
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if(inType != UIWebViewNavigationTypeOther) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}