Benim uygulama paketinden içerik ile çok basit bir UIWebView var. Web görünümünde herhangi bir bağlantının web görünümü yerine Safari'de açılmasını istiyorum. Mümkün mü?
Benim uygulama paketinden içerik ile çok basit bir UIWebView var. Web görünümünde herhangi bir bağlantının web görünümü yerine Safari'de açılmasını istiyorum. Mümkün mü?
Yanıtlar:
Bunu UIWebView temsilcisine ekleyin:
(gezinme türünü kontrol etmek için düzenlenmiştir. file://
göreli bağlantılar olabilecek istekleri de aktarabilirsiniz )
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Hızlı Sürüm:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}
Swift 3 sürümü:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.linkClicked {
UIApplication.shared.openURL(request.url!)
return false
}
return true
}
Swift 4 sürümü:
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
}
Güncelleme
As openURL
iOS 10'da kaldırıldı:
- (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
enum türleri için tercih edilebilir
Birisi merak ederse, Drawnonward'ın çözümü Swift'te şöyle görünür :
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL)
return false
}
return true
}
UIWebViewDelegate
User306253'ün cevabına hızlı bir yorum: UIWebView'e (yani koddan bile) bir şey yüklemeye çalıştığınızda, bununla dikkat edin, bu yöntem bunun olmasını önleyecektir.
Bunu önlemek için yapabileceğiniz (teşekkürler Wade):
if (inType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
Ayrıca UIWebViewNavigationTypeFormSubmitted
ve UIWebViewNavigationTypeFormResubmitted
türlerini işlemek de isteyebilirsiniz .
Diğer cevapların bir sorunu var: Safari'de mi yoksa web görünümünde mi yükleyeceğinize karar vermek için bağlantının kendisine değil, yaptığınız eyleme güveniyorlar.
Şimdi bazen bu tam olarak istediğiniz şey, ki bu iyi; ancak diğer bazı zamanlarda, özellikle sayfanızda bağlantı bağlantıları varsa, Safari'de yalnızca dahili bağlantıları değil, yalnızca harici bağlantıları açmak istersiniz. Bu durumda URL.host
, isteğinizin mülkünü kontrol etmelisiniz .
Ben ayrıştırılmakta olan URL'de bir ana bilgisayar adı olup olmadığını veya html gömülü olup olmadığını kontrol etmek için bu kod parçası kullanın:
- (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;
}
}
Elbette normal ifadeyi ihtiyaçlarınıza göre uyarlayabilirsiniz.
if (request.URL?.scheme != "file")
Swift'te aşağıdaki kodu kullanabilirsiniz:
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
}
}
URL değerini ve navigationType öğesini kontrol ettiğinizden emin olun.
İşte drawnonward'ın cevabının Xamarin iOS eşdeğeri.
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;
}
}
Kabul edilen cevap çalışmıyor.
Javascript aracılığıyla sayfa yüklendiğinde URL'ler, varsa navigationType
olacak UIWebViewNavigationTypeOther
. Maalesef, analitik gibi arka plan sayfa yüklerini de içerir.
Sayfa navigasyonu algılamak için, karşılaştırmak gerek [request URL]
için [request mainDocumentURL]
.
Bu çözüm her durumda işe yarar:
- (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;
}
}
Uygulama reddi Not:
Sonunda UIWbView
öldü ve Apple artık kabul etmeyecek.
Apple, halen kullanılmakta olan tüm Uygulama sahibine e-posta göndermeye başladı UIWebView
:
Kullanımdan Kaldırılmış API Kullanımı - Apple, API kullanan uygulamaların gönderilmesini kabul etmeyecek UIWebView
.
Apple, Kullanıcı Gizliliğini çok ciddiye almaktadır ve güvenli olmayan web görüntülemesine izin vermeyecekleri açıktır .
Bu yüzden mümkün olan en kısa sürede UIWebView uygulamasını uygulamanızdan kaldırın. UIWebView
yeni oluşturulan uygulamada kullanmayı deneyin ve WKWebView
mümkünse kullanmayı tercih ederim
ITMS-90809: Kullanımdan Kaldırılmış API Kullanımı - Apple, UIWebView API'lerini kullanan uygulamaların gönderilmesini kabul etmeyecek. Daha fazla bilgi için https://developer.apple.com/documentation/uikit/uiwebview adresine bakın .
Misal:
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")
}
}
Benim durumumda, web görünümündeki her şeyin ilk yükleme dışında Safari'yi açtığından emin olmak istiyorum ve bu yüzden kullanıyorum ...
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if(inType != UIWebViewNavigationTypeOther) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}