Moim rozwiązaniem jest anulowanie nawigacji i ponowne załadowanie żądania za pomocą loadRequest:. Będzie to podobne zachowanie jak UIWebView, który zawsze otwiera nowe okno w bieżącej ramce.
Zaimplementuj WKUIDelegatedelegata i ustaw go na _webview.uiDelegate. Następnie zastosuj:
To jest poprawna odpowiedź. Wypróbowaliśmy zaakceptowaną odpowiedź bez powodzenia. Ale odpowiedź @ Cloud działa, a ta odpowiedź na forach deweloperów wyjaśnia dlaczego.
Christopher Pickslay
5
To rozwiązanie zadziałało dla mnie. Nie zapomnij ustawić UIDelegatewłaściwości, ponieważ te metody są zadeklarowane w WKUIDelegatenot WKNavigationDelegate.
Taketo Sano
1
Ok, widzę, że ludzie chcą używać WKWebView w ten sposób. Zaimplementowałem możliwość otwarcia target = _blank-Links w tym samym WKWebView (jak pokazano powyżej) w moim projekcie github.com/sticksen/STKWebKitViewController .
stk
5
@ChristopherPickslay podczas korzystania z tej metody z moim WKWebView adres URL żądania jest zawsze pusty, więc widok sieciowy kieruje do pustej białej strony. Masz jakieś pomysły?
Jason Murray,
1
Kiedy żądanie „_blank” jest wysyłane z formularza zawierającego dane wiadomości, stwierdzam, że dane wiadomości zostaną utracone !!! Jakaś pomoc? @Cloud Wu
Andrew
66
Odpowiedź od @Cloud Xu jest poprawna. Tylko w celach informacyjnych, tutaj jest w języku Swift:
// this handles target=_blank links by opening them in the same view
func webView(webView:WKWebView!, createWebViewWithConfiguration configuration:WKWebViewConfiguration!, forNavigationAction navigationAction:WKNavigationAction!, windowFeatures:WKWindowFeatures!)->WKWebView!{if navigationAction.targetFrame ==nil{
webView.loadRequest(navigationAction.request)}returnnil}
To nie jest prawdziwy duplikat. Istnieją różnice w opcjonalności parametrów, które nie są zgodne z protokołem Swift 4.1 WKUIDelegate w odpowiedzi, z którą utworzono łącze.
yakattack
Cześć, Kiedy ładuję WKWebview z adresem URL Pinterest, nie mogę otworzyć „Kontynuuj z Facebookiem”. Teraz mogę kliknąć i uzyskać informacje o „Kontynuuj z Google”. Pomóż mi proszę.
Nrv
Mam ten sam problem z wkwebview; logowanie i przekierowanie nie działały w mojej aplikacji. Jakaś pomoc ?
Jamshed Alam
1
proszę, każdy może mi pomóc, przypisałem delegata uiDelegate do wkwebview, ale jego metoda tworzenia widoku internetowego z konfiguracją nie jest wywoływana
chetan panchal
25
Dodaj siebie jako delegata WKNavigationDelegate
_webView.navigationDelegate =self;
i zaimplementuj następujący kod w wywołaniu zwrotnym delegata choosePolicyForNavigationAction: DecisionHandler:
-(void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler
{//this is a 'new window action' (aka target="_blank") > open this URL externally. If we´re doing nothing here, WKWebView will also just do nothing. Maybe this will change in a later stage of the iOS 8 Betaif(!navigationAction.targetFrame){
NSURL *url = navigationAction.request.URL;UIApplication*app =[UIApplication sharedApplication];if([app canOpenURL:url]){[app openURL:url];}}
decisionHandler(WKNavigationActionPolicyAllow);}
PS: Ten kod pochodzi z mojego małego projektu STKWebKitViewController, który otacza użyteczny interfejs użytkownika wokół WKWebView.
Jest literówka. Brakuje kropki między WKNavigationActionPolicy a Allow
kurczak,
@stk Jak mogę się dowiedzieć, czy UIApplication otworzy łącze w aplikacji Safari? Jeśli jest to link do Appstore - muszę otworzyć w aplikacji Appstore, ale jeśli jest to zwykła strona internetowa - muszę ją otworzyć w tym samym stackoverflow
WKWebView.com/questions/29056854/ ...
1
@LeoKoppelkamm To nie jest literówka, a raczej Objective-C, a nie Swift. ;)
Ayan Sengupta
1
Działa to w przypadku linków, ale wydaje się, że nie wykrywa nowych okien otwieranych za pomocą JavaScript, tj.window.open(url, "_blank")
Crashalot
@Crashalot Czy znalazłeś rozwiązanie dla window.open?
Sam,
14
Jeśli ustawiłeś już WKWebView.navigationDelegate
WKWebView.navigationDelegate = self;
wystarczy zaimplementować:
-(void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler
{
BOOL shouldLoad =[self shouldStartLoadWithRequest:navigationAction.request];// check the url if necessaryif(shouldLoad && navigationAction.targetFrame ==nil){// WKWebView ignores links that open in new window[webView loadRequest:navigationAction.request];}// always pass a policy to the decisionHandler
decisionHandler(shouldLoad ?WKNavigationActionPolicyAllow:WKNavigationActionPolicyCancel);}
w ten sposób nie musisz implementować metody WKUIDelegate.
Potwierdzam, że kod Swift Billa Weinmana jest poprawny. Ale trzeba wspomnieć, że musisz również delegować UIDelegate, aby działał, na wypadek, gdybyś był nowy w programowaniu iOS, tak jak ja.
Coś takiego:
self.webView?.UIDelegate=self
Są więc trzy miejsca, w których musisz wprowadzić zmiany.
Nie jestem pewien, czy jest to domniemane, ale aby ten wiersz kodu działał w iOS 10, musisz ViewControllerdziedziczyć WKUIDelegate. ieclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
ltrainpr
4
Możesz także nacisnąć inny kontroler widoku lub otworzyć nową kartę itp:
Czy konieczne jest ustawienie vc.url? Nie ustawiam tego, a widok sieciowy ładuje się poprawnie. Z mojego doświadczenia wynika, że widzę createWebViewWithConfigurationwezwanie tylko wtedy, gdy navigationAction.targetFramejest nil. Czy możesz opisać scenariusz, w którym to nie byłoby prawdą?
Mason G. Zhwiti
@ MasonG.Zhwiti Jesienią aktywnie korzystałem z WKWebViews w projekcie, ale od tamtej pory nic z nimi nie zrobiłem - więc naprawdę nie mogę odpowiedzieć na twoje pytanie. W momencie, gdy opublikowałem powyższe, zadziałało. Nie mogę jednak pojąć, jak to działa bez ustawienia vc.url.
David H
Myślę, że działa bez, ponieważ zwracasz utworzony widok sieciowy, a następnie (zgaduję), cokolwiek poprosiło Cię o utworzenie, zajmuje się używaniem widoku internetowego do załadowania danego adresu URL.
cześć, po zalogowaniu się na Facebooku, jak w podobny sposób otworzyć okno udostępniania dla udostępniania na Facebooku? Zalogowałem się podczas tworzenia nowego wkwebview, teraz użytkownik jest zalogowany. Jak teraz śledzić okno udostępniania?
Jak widać, po prostu otwieramy webViewnowy adres URL z nowym adresem i kontrolujemy możliwość zamknięcia, tylko jeśli potrzebujesz odpowiedzi z tego, second webviewaby była wyświetlana jako pierwsza.
Napotkałem pewne problemy, których nie można rozwiązać za pomocą samego narzędzia webView.load(navigationAction.request). Więc używam tworzenia nowego webView do zrobienia i po prostu działa dobrze.
**Use following function to create web view**
func initWebView(configuration:WKWebViewConfiguration){let webView =WKWebView(frame:UIScreen.main.bounds, configuration: configuration)
webView.uiDelegate =self
webView.navigationDelegate =self
view.addSubview(webView)self.webView = webView
}**InViewDidLoad:**if webView ==nil{ initWebView(configuration:WKWebViewConfiguration())}
webView?.load(url: url1)**WKUIDelegateMethod need to be implemented**
extension WebViewController:WKUIDelegate{
func webView(_ webView:WKWebView, createWebViewWith configuration:WKWebViewConfiguration,for navigationAction:WKNavigationAction, windowFeatures:WKWindowFeatures)->WKWebView?{// push new screen to the navigation controller when need to open url in another "tab"print("url:\(String(describing: navigationAction.request.url?.absoluteString))")iflet url = navigationAction.request.url, navigationAction.targetFrame ==nil{let viewController =WebViewController()
viewController.initWebView(configuration: configuration)
viewController.url1 = url
DispatchQueue.main.async{[weak self]inself?.navigationController?.pushViewController(viewController, animated:true)}return viewController.webView
}returnnil}}
extension WKWebView{
func load(url: URL){ load(URLRequest(url: url))}}
Odpowiedzi:
Moim rozwiązaniem jest anulowanie nawigacji i ponowne załadowanie żądania za pomocą loadRequest:. Będzie to podobne zachowanie jak UIWebView, który zawsze otwiera nowe okno w bieżącej ramce.
Zaimplementuj
WKUIDelegate
delegata i ustaw go na_webview.uiDelegate
. Następnie zastosuj:źródło
UIDelegate
właściwości, ponieważ te metody są zadeklarowane wWKUIDelegate
notWKNavigationDelegate
.Odpowiedź od @Cloud Xu jest poprawna. Tylko w celach informacyjnych, tutaj jest w języku Swift:
źródło
Aby korzystać z najnowszej wersji Swift 4.2+
Rozszerz swoją klasę dzięki WKUIDelegate
Ustaw delegata dla widoku internetowego
Implementuj metodę protokołu
źródło
Dodaj siebie jako delegata WKNavigationDelegate
i zaimplementuj następujący kod w wywołaniu zwrotnym delegata choosePolicyForNavigationAction: DecisionHandler:
PS: Ten kod pochodzi z mojego małego projektu
STKWebKitViewController
, który otacza użyteczny interfejs użytkownika wokół WKWebView.źródło
window.open(url, "_blank")
Jeśli ustawiłeś już WKWebView.navigationDelegate
WKWebView.navigationDelegate = self;
wystarczy zaimplementować:
w ten sposób nie musisz implementować metody WKUIDelegate.
źródło
Żadne z tych rozwiązań nie zadziałało, problem rozwiązałem przez:
1) Wdrażanie WKUIDelegate
2) Ustawienie delegata UIDelegate wkWebview
3) Implementacja metody createWebViewWithConfiguration
źródło
Cloud xu
odpowiedź rozwiązuje mój problem.Jeśli ktoś potrzebuje równoważnej wersji Swift (4.x / 5.0), oto ona:
Oczywiście najpierw musisz ustawić
webView.uiDelegate
.źródło
Potwierdzam, że kod Swift Billa Weinmana jest poprawny. Ale trzeba wspomnieć, że musisz również delegować UIDelegate, aby działał, na wypadek, gdybyś był nowy w programowaniu iOS, tak jak ja.
Coś takiego:
Są więc trzy miejsca, w których musisz wprowadzić zmiany.
źródło
self.webView.UIDelegate = self
ViewController
dziedziczyćWKUIDelegate
. ieclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
Możesz także nacisnąć inny kontroler widoku lub otworzyć nową kartę itp:
źródło
vc.url
? Nie ustawiam tego, a widok sieciowy ładuje się poprawnie. Z mojego doświadczenia wynika, że widzęcreateWebViewWithConfiguration
wezwanie tylko wtedy, gdynavigationAction.targetFrame
jestnil
. Czy możesz opisać scenariusz, w którym to nie byłoby prawdą?Na podstawie odpowiedzi Allena Huanga
Detale
Cele
target=“_blank”
push
Wyświetl kontroler z webView, jeśli obecny kontroler manavigationController
present
Wyświetl kontroler z webView we wszystkich innych przypadkachRozwiązanie
Pełna próbka
dodaj swoje ustawienia bezpieczeństwa transportu Info.plist
Scenorysy
Wersja 1
Wersja 2
źródło
To zadziałało dla mnie:
Jak widać, po prostu otwieramy
webView
nowy adres URL z nowym adresem i kontrolujemy możliwość zamknięcia, tylko jeśli potrzebujesz odpowiedzi z tego,second webview
aby była wyświetlana jako pierwsza.źródło
Napotkałem pewne problemy, których nie można rozwiązać za pomocą samego narzędzia
webView.load(navigationAction.request)
. Więc używam tworzenia nowego webView do zrobienia i po prostu działa dobrze.źródło
źródło