How to load a url link that is inside a web view and keep it in that web view in SWIFT
In the webview delegate you are going to want to navigate to the new url using that same webview.
For you this means that inside your switch case you should use
loadRequest
loadRequest documentation
To fix your issue you should remove the line using UIApplication.sharedApplication().openURL(request.URL!)
and replace it with a call to loadRequest
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
switch navigationType {
case .LinkClicked:
// Open links in Safari
guard let newRequest = request as? URLRequest else { return false }
webView.loadRequest(newRequest)
return false
default:
// Handle other navigation types...
return true
}
}
Hope this helps! Have a nice day!
How to open external link with WKWebView once already inside WebView?
You need to conform to the WKUIDelegate
as well.
webView.uiDelegate = self
Because you haven't, this delegate method isn't firing.
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?
How to open another View from links within UIWebview in Swift 3?
From inside if block, you need to return false, and it should work.
By returning false the delegate method tells that the webView should not start loading the url.
public func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if request.url?.scheme == "myapp" {
// do your work here
UIApplication.shared.open(request.url!, options: [:], completionHandler: nil)
//Add the below line of code to the existing code
return false
}
return true
}
SwiftUI open a new View on link click inside of WKWebView
I finally found a solution to my problem. You have to use the Coordinator to know when there is a click on a link and to retrieve the link.
Using Binding I transfer the url to the view and I open a sheetView and inside I have my my webview which opens the url
struct PostDetailView: View {
var p: Post
@ObservedObject var dataManager: DataManager
let preferences:Preferences = parsePreferences()
let contentWebView = ArticleCustomView()
@State var showComments = false
@Binding var favorite: Bool
@State var activeSheet: Bool = false
@State var urlToOpenInSheet: String = ""
@Environment(\.colorScheme) var colorScheme
var body: some View {
let content: String = contentWebView.contentArticle(title: p.title.rendered.stringByDecodingHTMLEntities, content: p.content.rendered, date: formatDateDetailPost(dateToChange: p.date), author: p.author_meta.nickname)
ZStack{
BackgroundView()
articleWebView(text: content, color: colorScheme, activeSheet: $activeSheet, urlToOpenInSheet: $urlToOpenInSheet)
}
.navigationBarTitle(...)
.navigationBarItems(...)
.sheet(isPresented: $activeSheet) {
if !urlToOpenInSheet.isEmpty {
ExternalWebView(urlToVisite: urlToOpenInSheet, activeButtons: true, fromSheet: true, closeSheet: $activeSheet)
.ignoresSafeArea()
.accentColor(.white)
}
}
.onChange(of: urlToOpenInSheet) { newValue in
print("url changed to \(urlToOpenInSheet)!")
}
}
}
struct articleWebView: UIViewRepresentable {
@State var text: String
@State var color: ColorScheme
@Binding var activeSheet: Bool
@Binding var urlToOpenInSheet: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let WKWebView = WKWebView()
WKWebView.navigationDelegate = context.coordinator
return WKWebView
}
func updateUIView(_ uiView: WKWebView, context: Context) {
var html = ""
var normalizeCSS: String = ""
var articlesCSS: String = ""
//let articlesDarkCSS: String
let altCSS: String
guard let fileURL = Bundle.main.url(forResource: "articles", withExtension: "html") else { return print("articles.html introuvable")}
guard let fileURLNormalizeCss = Bundle.main.url(forResource: "normalize", withExtension: "css") else { return print("normalize.css introuvable")}
guard let fileURLArticlesCss = Bundle.main.url(forResource: "articles\(altCSS)", withExtension: "css") else { return print("articles\(altCSS).css introuvable")}
do {
html = try String(contentsOf: fileURL)
} catch {
print("Unable to get the articles.html")
}
do {
normalizeCSS = try String(contentsOf: fileURLNormalizeCss)
} catch {
print("Unable to get the normalize.css")
}
do {
articlesCSS = try String(contentsOf: fileURLArticlesCss)
} catch {
print("Unable to get the articles.css")
}
html = html.replacingOccurrences(of: "[article:content]", with: text)
html = html.replacingOccurrences(of: "[normalize:CSS]", with: normalizeCSS)
html = html.replacingOccurrences(of: "[style:articles]", with: articlesCSS)
//print(html)
uiView.loadHTMLString(html, baseURL: nil)
//---------------------- Activer /Desactiver certaines options sur la Webview -------------------------//
uiView.allowsBackForwardNavigationGestures = true
uiView.isOpaque = false
uiView.backgroundColor = .clear
uiView.scrollView.backgroundColor = UIColor.clear
uiView.scrollView.showsVerticalScrollIndicator = false // indicateur de scroll
uiView.scrollView.pinchGestureRecognizer?.isEnabled = false // zommer-dezommer avec le doigt
}
class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
var parent: articleWebView
init(_ parent: articleWebView) {
self.parent = parent
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url {
if UIApplication.shared.canOpenURL(url) {
//UIApplication.shared.open(url)
print(url)
parent.urlToOpenInSheet = url.absoluteString
print(self.parent.urlToOpenInSheet)
parent.activeSheet = true
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
} else {
//print("not a user click")
decisionHandler(.allow)
}
}
}
}
How to pass different URL to webView from some buttons in swift?
What you need to do is use prepareForSegue:sender:
to set a property in your destination view controller. prepareForSegue:sender:
will be called before your initial view controller segues to any destination view controller. Within this function, we can check which button was pressed and set the appropriate URL in the destination view controller accordingly.
This approach will allow you to use any segue between your buttons and your destination view controller. This means, you simply have to drag the blue line from the buttons to the view controller you want to segue to.
1. Within your storyboard, create a segue between your first view controller and your destination view controller. This is done by holding control, clicking on the first view controller in the interface builder, and dragging over the destination view controller. Then choose a segue type:
Now, select this segue and give it the Identifier
"InitialVCToDestinationVC" in the attributes inspector:
2. Make a property called urlToPass
of type URL
in your initial view controller:
class InitialViewController: UIViewController {
var urlToPass: URL!
@IBAction func googleButtonPressed(_ sender: Any) {
}
@IBAction func facebookButtonPressed(_ sender: Any) {
}
}
3. Make a property called receivedUrl
in the destination view controller:
class DestinationViewController: UIViewController {
var receivedUrl: URL!
@IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: receivedUrl)
webView.load(request)
}
}
4. Set the urlToPass
depending on which button is pressed and use the prepareForSegue:sender:
function to set the destination view controller's url accordingly. Then, make use of performSegue(withIdentifier:sender:)
to perform the segue with identifier InitialVCToDestinationVC
.
class InitialViewController: UIViewController {
var urlToPass: URL!
@IBAction func googleButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.google.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
@IBAction func facebookButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.facebook.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let destination = segue.destination as? DestinationViewController else { return }
destination.receivedUrl = urlToPass
urlToPass = nil
}
}
5. (optional) Make use of the shouldPerformSegueWithIdentifier:sender:
method within InitialViewController
and check whether or not urlToPass
is valid. If urlToPass
is valid, perform the segue, else present an alert.
class InitialViewController: UIViewController {
...
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if let urlToPass = urlToPass {
// check if your application can open the NSURL instance
if !UIApplication.shared.canOpenURL(urlToPass) {
let alertController = UIAlertController(title: "Cannot open URL.", message: "This is an invalid URL.", preferredStyle: .alert)
let ok = UIAlertAction(title: "Okay", style: .cancel, handler: nil)
alertController.addAction(ok)
present(alertController, animated: true, completion: nil)
}
return UIApplication.shared.canOpenURL(urlToPass)
}
return false
}
}
End result:
Here's a link to the Xcode project I made the above gif from: https://github.com/ChopinDavid/PrepareForSegue
How to load URL on WKWebView?
First of all you need to import
import WebKit
Following code is enough to open URL with WKWebView
let webView = WKWebView(frame: <#AnyRect#>)
let link = URL(string:"https://developer.apple.com/videos/play/wwdc2019/239/")!
let request = URLRequest(url: link)
webView.load(request)
Related Topics
Swift Formatting String to Have 2 Decimal Numbers If It Is Not a Whole Number
Wkwebview Page Height Issue on iPhone X
Paging Uiscrollview in Increments Smaller Than Frame Size
Dynamic Size Uicollectionview Cell
Ios7 Status Bar Hide/Show on Select Controllers
Uicollectionview Update a Single Cell
Method Load() Defines Objective-C Class Method 'Load', Which Is Not Permitted by Swift 1.2
How to Make the View Update Instant in Swiftui
Swift - Apply Local CSS to Web View
Fixing Xcode 9 Issue: "iPhone Is Busy: Preparing Debugger Support for Iphone"
Xcode 8/Swift 3: "Expression of Type Uiviewcontroller? Is Unused" Warning
How to Change the Color of the Text in a Uipickerview Under iOS 7
Add Uipickerview in Uiactionsheet from iOS 8 Not Working
How to Set Cmake_C_Compiler and Cmake_Cxx_Compiler for Building Assimp for iOS