जवाबों:
मेरा समाधान नेविगेशन को रद्द करना और लोडरकेस के साथ अनुरोध को लोड करना है: फिर से। यह UIWebView के समान व्यवहार आएगा जो हमेशा वर्तमान फ्रेम में नई विंडो खोलते हैं।
WKUIDelegate
प्रतिनिधि को लागू करें और इसे सेट करें _webview.uiDelegate
। फिर लागू करें:
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
if (!navigationAction.targetFrame.isMainFrame) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
UIDelegate
संपत्ति सेट करना न भूलें , क्योंकि यह विधियाँ घोषित WKUIDelegate
नहीं की गई हैं WKNavigationDelegate
।
@ क्लॉड जू का जवाब सही उत्तर है। बस संदर्भ के लिए, यहाँ यह स्विफ्ट में है:
// 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)
}
return nil
}
स्विफ्ट के नवीनतम संस्करण का उपयोग करने के लिए 4.2+
import WebKit
WKUIDelegate के साथ अपनी कक्षा बढ़ाएँ
Webview के लिए प्रतिनिधि सेट करें
self.webView.uiDelegate = self
प्रोटोकॉल विधि को लागू करें
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
WKNavigationDelegate के रूप में खुद को जोड़ें
_webView.navigationDelegate = self;
और प्रतिनिधि कॉलबैक निश्चय में निम्नलिखित कोड लागू करें
- (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 Beta
if (!navigationAction.targetFrame) {
NSURL *url = navigationAction.request.URL;
UIApplication *app = [UIApplication sharedApplication];
if ([app canOpenURL:url]) {
[app openURL:url];
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}
PS: यह कोड मेरी छोटी परियोजना से है STKWebKitViewController
, जो WKWebView के चारों ओर प्रयोग करने योग्य UI को लपेटता है।
window.open(url, "_blank")
यदि आप WKWebView.navigationDelegate पहले ही सेट कर चुके हैं
WKWebView.navigationDelegate = self;
आपको बस लागू करने की आवश्यकता है:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
BOOL shouldLoad = [self shouldStartLoadWithRequest:navigationAction.request]; // check the url if necessary
if (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);
}
इस तरह आपको WKUIDelegate पद्धति को लागू करने की आवश्यकता नहीं है।
उन समाधानों में से किसी ने भी मेरे लिए काम नहीं किया, मैंने इस मुद्दे को हल किया:
1) WKUIDelegate लागू करना
@interface ViewController () <WKNavigationDelegate, WKUIDelegate>
2) wkWebview के UIDelegate प्रतिनिधि की स्थापना
self.wkWebview.UIDelegate = self;
3) createWebViewWithConfiguration विधि को लागू करना
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
if (!navigationAction.targetFrame.isMainFrame) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[[UIApplication sharedApplication] openURL:[navigationAction.request URL]];
}
return nil; }
Cloud xu
जवाब मेरा मुद्दा हल करती है।
यदि किसी को समकक्ष स्विफ्ट (4.x / 5.0) संस्करण की आवश्यकता है, तो यह है:
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if let frame = navigationAction.targetFrame,
frame.isMainFrame {
return nil
}
// for _blank target or non-mainFrame target
webView.load(navigationAction.request)
return nil
}
बेशक आपको webView.uiDelegate
सबसे पहले सेट करना होगा ।
मैं पुष्टि करता हूं कि बिल वेनमैन का स्विफ्ट कोड सही है। लेकिन यह उल्लेख करने की आवश्यकता है कि आपको भी काम करने के लिए UIDelegate को सौंपना होगा, यदि आप मेरे जैसे iOS के विकास के लिए नए हैं।
कुछ इस तरह:
self.webView?.UIDelegate = self
इसलिए तीन जगह हैं जिन्हें आपको बदलाव करने की आवश्यकता है।
self.webView.UIDelegate = self
ViewController
विरासत में चाहिए WKUIDelegate
। यानीclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
आप किसी अन्य दृश्य नियंत्रक को भी धक्का दे सकते हैं, या एक नया टैब खोल सकते हैं, आदि:
func webView(webView: WKWebView, createWebViewWithConfiguration configuration: WKWebViewConfiguration, forNavigationAction navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
var wv: WKWebView?
if navigationAction.targetFrame == nil {
if let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController") as? ViewController {
vc.url = navigationAction.request.URL
vc.webConfig = configuration
wv = vc.view as? WKWebView
self.navigationController?.pushViewController(vc, animated: true)
}
}
return wv
}
vc.url
? मैं इसे सेट नहीं कर रहा हूं, और वेब दृश्य ठीक से लोड हो रहा है। इसके अलावा, मेरे अनुभव में मैं केवल यह देख रहा हूं कि createWebViewWithConfiguration
कब क्या navigationAction.targetFrame
है nil
। क्या आप ऐसे परिदृश्य का वर्णन कर सकते हैं जहाँ यह सच नहीं होगा?
एलन हुआंग जवाब के आधार पर
target=“_blank”
push
यदि वर्तमान नियंत्रक है, तो वेब व्यू के साथ कंट्रोलर देखें navigationController
present
अन्य सभी मामलों में वेब व्यू के साथ कंट्रोलर देखेंwebView.uiDelegate = self
// .....
extension ViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
guard navigationAction.targetFrame == nil,
let url = navigationAction.request.url else { return nil }
let vc = ViewController(url: url, configuration: configuration)
if let navigationController = navigationController {
navigationController.pushViewController(vc, animated: false)
return vc.webView
}
present(vc, animated: true, completion: nil)
return nil
}
}
Info.plist
अपने Info.plist परिवहन सुरक्षा सेटिंग में जोड़ें
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
ViewController
import UIKit
import WebKit
class ViewController: UIViewController {
private lazy var url = URL(string: "https://www.w3schools.com/html/tryit.asp?filename=tryhtml_links_target")!
private weak var webView: WKWebView!
init (url: URL, configuration: WKWebViewConfiguration) {
super.init(nibName: nil, bundle: nil)
self.url = url
navigationItem.title = ""
}
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
override func viewDidLoad() {
super.viewDidLoad()
initWebView()
webView.loadPage(address: url)
}
private func initWebView() {
let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
view.addSubview(webView)
self.webView = webView
webView.navigationDelegate = self
webView.uiDelegate = self
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
}
}
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
guard let host = webView.url?.host else { return }
navigationItem.title = host
}
}
extension ViewController: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
guard navigationAction.targetFrame == nil,
let url = navigationAction.request.url else { return nil }
let vc = ViewController(url: url, configuration: configuration)
if let navigationController = navigationController {
navigationController.pushViewController(vc, animated: false)
return vc.webView
}
present(vc, animated: true, completion: nil)
return nil
}
}
extension WKWebView {
func loadPage(address url: URL) { load(URLRequest(url: url)) }
func loadPage(address urlString: String) {
guard let url = URL(string: urlString) else { return }
loadPage(address: url)
}
}
संस्करण 1
संस्करण 2
यह मेरे लिए काम किया:
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
if (!navigationAction.targetFrame.isMainFrame) {
WKWebView *newWebview = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
newWebview.UIDelegate = self;
newWebview.navigationDelegate = self;
[newWebview loadRequest:navigationAction.request];
self.view = newWebview;
return newWebview;
}
return nil;
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)webViewDidClose:(WKWebView *)webView {
self.view = self.webView;
}
जैसा कि आप देख सकते हैं, हम यहां जो कुछ भी कर रहे हैं, वह केवल webView
नए url के साथ एक नया खोल रहा है और बंद होने की सकारात्मकता को नियंत्रित कर रहा है, बस अगर आपको second webview
पहले से प्रदर्शित होने के लिए उस से प्रतिक्रिया की आवश्यकता है ।
मुझे कुछ मुद्दों का सामना करना पड़ा, जिन्हें केवल उपयोग करके हल नहीं किया जा सकता है webView.load(navigationAction.request)
। इसलिए मैं एक नया वेबव्यू बनाने के लिए उपयोग करता हूं और यह ठीक काम करता है।
//MARK:- WKUIDelegate
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
NSLog(#function)
if navigationAction.targetFrame == nil {
NSLog("=> Create a new webView")
let webView = WKWebView(frame: self.view.bounds, configuration: configuration)
webView.uiDelegate = self
webView.navigationDelegate = self
self.webView = webView
return webView
}
return nil
}
**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
}
**In View Did Load:**
if webView == nil { initWebView(configuration: WKWebViewConfiguration()) }
webView?.load(url: url1)
**WKUIDelegate Method 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))")
if let url = navigationAction.request.url, navigationAction.targetFrame == nil {
let viewController = WebViewController()
viewController.initWebView(configuration: configuration)
viewController.url1 = url
DispatchQueue.main.async { [weak self] in
self?.navigationController?.pushViewController(viewController, animated: true)
}
return viewController.webView
}
return nil
}
}
extension WKWebView
{
func load(url: URL) { load(URLRequest(url: url)) }
}