2010-03-28 13 views
40

Mam wbudowany UIWebView w mojej aplikacji na iPhone'a. Chcę mieć możliwość otwierania niektórych linków w tej przeglądarce internetowej w pełnej wersji mobilnej przeglądarki Safari (to znaczy nie mojej osadzonej wersji).Wymuszenie łącza WebView w celu uruchomienia Safari?

Czy istnieje prosty sposób na uporządkowanie niektórych moich hrefów, aby wymusić to, zamiast na każdym otwarciu linku w mojej wbudowanej przeglądarce internetowej?

Dzięki.

+0

[http://stackoverflow.com/questions/4452719/jak-do-i-open-linki-in-safari-zamiast-of-UIWebView/12103579 # 12103579] [1] [1]: http: // stackoverflow.com/questions/4452719/how-do-i-open-links-in-safari-zamiast-uiwebview/12103579 # 12103579 –

Odpowiedz

12

nie próbowałem to sobie, ale myślę, że można wdrożyć metodę UIWebViewDelegate

webView:shouldStartLoadWithRequest:navigationType 

która zostanie wywołana w każdej chwili ogniwem w UIWebView jest kliknął. W tej metodzie wystarczy określić, czy kliknięty link powinien spowodować uruchomienie Safari, czy nie, i użyć openURL, jeśli powinien.

- (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; 
} 

Nie zapomnij, że trzeba ustawić właściwość UIWebView delegata do instancji klasy, która implementuje UIWebViewDelegate.

61

Aby rozwinąć na co Randy powiedział, to co używam w mojej aplikacji, aby każdy http: //, https: //, a mailto: // URL otwarte w zewnętrznej aplikacji Safari lub Mail:

-(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; 
} 

Jak mówi Randy, będziesz chciał zaimplementować to w dowolnej klasie, którą określisz jako delegata UIWebView. Aby tylko niektóre adresy URL uruchamiały Safari, możesz zmienić ich schemat z http: // na safari: // lub coś podobnego, i tylko wykopać te adresy URL do systemu (po zamianie niestandardowego schematu URL na http: //) .

Robię to w ramach mojej wewnętrznej dokumentacji pomocy, która jest HTML wyświetlana w interfejsie UIWebView, więc nie napotykam problemów w procesie recenzji, mając wbudowaną w moją aplikację przeglądarkę internetową ogólnego przeznaczenia.

+0

Czy zachowanie i zwolnienie adresu URL nie jest naprawdę paranoiczne? – morningstar

+0

@morningstar - Być może, i jest już przestarzałe w ARC, ale w tamtym czasie zmagałem się z awariami związanymi z wątkami w innych miejscach (autoreleased obiekty, które zostały przekazane do metod, w których różne wątki zostały zwolnione w środku tej metody), więc myliłem się po stronie paranoi. Znowu robi to dla ciebie teraz ARC, więc mój kod już go nie zawiera. –

+0

Tak, dobrze, widzę, jak to może być konieczne z powodu problemów z wątkami. – morningstar

20

Ok Mam to. Może to nie jest idealne rozwiązanie, ale można to zrobić tak:

Tylko w swojej WebViewController.m:

dodać linię webView.delegate = self; procedurze viewDidLoad:

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

Następnie można dodać jak opisano powyżej gdzieś w pliku Controller.m Następująca po funkcji wynikowa funkcja boolowska:

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

Dla początkujących ważne jest ustawienie nieco o delegacie :) – firecall

+0

Thanku tak bardzo :) –

1

ten sposób rozwiązaliśmy go dodać do pliku 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; 
} 
1

Swift wersji odpowiedzi Brad Larson:

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 
    } 
} 
Powiązane problemy