how o open link within webview if its come in webview(swift) - ios

I'm loading html string by WebView in my app. Current issue is that when my WebView load content that contains another link and when user click on that link, new view is not opening in my app - it opens in default browser. How can I open that link in WebView? Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = UIRectEdge.None
SVProgressHUD.show()
//EZLoadingActivity.show("أرجو الإنتظار", disableUI: true)
self.automaticallyAdjustsScrollViewInsets = false
self.navigationController!.navigationBar.tintColor = UIColor.whiteColor()
self.navigationController!.navigationBar.barStyle = UIBarStyle.Black
self.navigationController!.navigationBar.tintColor = UIColor.whiteColor()
let logo = UIImage(named: "toolbar_icon3")
let imageView = UIImageView(image:logo)
self.navigationItem.titleView = imageView
myweb.loadHTMLString(webviewurl, baseURL: nil)
}
Android allows to do it with:
public boolean shouldOverrideUrlLoading(WebView view, String url)
But on iOS how can we do this?

You could try creating a url request for you UIWebView.
yourWebView.loadRequest(NSURLRequest(URL: NSURL(string: "google.ca")!))
If you would like to do something while the web view is opening, you could use the UIWebViewDelegate statement.
In your class:
class ViewController: UIViewController, UIWebViewDelegate {
Then,
yourWebView.delegate = self
And finally, you can use:
func webViewDidStartLoad(webView: UIWebView) {
//do something while the web view is loading!
}
For more information on UIWebViewDelegate, visit Apple's Documentation.

Related

Swift White Screen upon returning from SafariWebController

When I open a safari view controller and then return to my app (when "Done" is pressed), my app renders a blank/white screen instead of the content for that view.
The code below is the code I have tried using in an empty view - the issue happens no matter where I try in my app.
import UIKit
import SafariServices
class SavedViewController: UIViewController, SFSafariViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if let link = URL(string: "https://google.com"){
let myrequest = SFSafariViewController(url: link)
myrequest.delegate = self
present(myrequest, animated:true)
}
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
dismiss(animated:true, completion: nil)
}
}
The website loads fine, its when I return to my app that the blank screen appears. Am I doing something wrong?
It works fine.
You just created new UIViewController this way, UIViewController by default have black background. So when you press Done you just come back from SafariViewController to you SavedViewController (UIViewController).
Probably You are looking for UIWebView solution https://developer.apple.com/documentation/uikit/uiwebview.
If u want only display SafariViewController do it as function from your ViewController, You don't need to create new File with UIViewController class to do it.
import UIKit
import SafariServices
class SavedViewController: UIViewController, SFSafariViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .gray
setupViews()
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
dismiss(animated:true, completion: nil)
}
private func setupViews(){
view.addSubview(openSafariButton)
openSafariButton.addTarget(self, action: #selector(handleOpenSafariButtonTap), for: .touchUpInside)
openSafariButton.frame = CGRect(x: 0, y: 100, width: view.frame.width, height: 60)
}
#objc func handleOpenSafariButtonTap(){
if let link = URL(string: "https://google.com"){
let myrequest = SFSafariViewController(url: link)
myrequest.delegate = self
present(myrequest, animated:true)
}
}
let openSafariButton: UIButton = {
let button = UIButton()
button.setTitle("openSafari", for: .normal)
button.setTitleColor(.black, for: .normal)
button.backgroundColor = .red
return button
}()
}
That is what i mean.
You can add function:
private func openSafariLink(link: String){
if let link = URL(string: link){
let myrequest = SFSafariViewController(url: link)
present(myrequest, animated:true)
}
}
And call it from any place like that:
openSafariLink(link: "https://google.com")
This way fits more for Your solution.

How can I refresh or reload a WKwebview when selecting tabs

I have a tabbed app which loads separate internal file WKwebviews. I now need to have the WKwebview refresh when a tab is selected.
I think I need to add the required code in the viewWillAppear, but on trying to have some code on this method nothing works.
Does anyone have any suggestions as to how I can achieve this
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
webView.configuration.userContentController.add(self, name: "jsHandler")
let bundleURL = Bundle.main.resourceURL!.absoluteURL
let html = bundleURL.appendingPathComponent("main/index.html") //Loads internal HTML files
webView.loadFileURL(html, allowingReadAccessTo:bundleURL)
webView!.uiDelegate = self
webView.allowsBackForwardNavigationGestures = true //Allows 'safari' style gestures swipe back etc
}
override func viewWillAppear(_ animated: Bool) {
//Nothing
}
Update:
To resolve this, I added the above code into the viewDidAppear method rather than the viewDidLoad. This has resolved the problem.
The JS message handler still needs to be in the viewDidLoad.
Example:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
webView.configuration.userContentController.add(self, name: "jsHandler")
}
override func viewDidAppear(_ animated: Bool) {
//webView.configuration.userContentController.add(self, name: "jsHandler")
let bundleURL = Bundle.main.resourceURL!.absoluteURL
let html = bundleURL.appendingPathComponent("index.html") //Loads internal HTML files
webView.loadFileURL(html, allowingReadAccessTo:bundleURL)
webView!.uiDelegate = self
webView.allowsBackForwardNavigationGestures = true //Allows 'safari' style gestures swipe back etc
}
Try something like this on each tab action:
func reloadTabAction() {
if let url = webView.url {
webView.reload()
} else {
webView.load(URLRequest(url: originalURL))
}
}
We have reload property for WKWebView. So you can directly call the method.
You can call the method while tapped the tabView
Try the below code,
webView.reload()

ios PDFKit displaymode = singlepage only shows the first page of the pdf

I'm trying to display a pdf on ios via apples PDFKit library, and rather than use PDFDisplayMode.singlePageContinuous mode, I want to stop at page breaks so I'm trying to use PDFDisplayMode.singlePage.
https://developer.apple.com/documentation/pdfkit/pdfdisplaymode
However, this mode seems to only display one page of the pdf which is quite useless. I've tried adding swipe handlers to the page but they aren't working either.
I've found sample applications and altered their code to test the pdfdisplaymode but get the same problem e.g.
https://github.com/vipulshah2010/PDFKitDemo
How can I implement a one page at a time pdfviewer with pdfkit, that allows swiping between pages?!
A another simple way to do this is setting
pdfView.usePageViewController(true)
This adds the swiping between pages for you and no need to set up your own gestures. See example below:
override func viewDidLoad() {
super.viewDidLoad()
// Add PDFView to view controller.
let pdfView = PDFView(frame: self.view.bounds)
self.view.addSubview(pdfView)
// Configure PDFView to be one page at a time swiping horizontally
pdfView.autoScales = true
pdfView.displayMode = .singlePage
pdfView.displayDirection = .horizontal
pdfView.usePageViewController(true)
// load PDF
let webUrl: URL! = URL(string: url)
pdfView.document = PDFDocument(url: webUrl!)
}
Use the swipe gesture recognizer (UISwipeGestureRecognizer) to let the user swipe the PDF view screen (PDFView) to the left and right.
import UIKit
import PDFKit
class ViewController: UIViewController, PDFViewDelegate {
// MARK: - Variables
// MARK: - IBOutlet
#IBOutlet weak var pdfView: PDFView!
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
let filePath = "/Users/george/Library/Developer/CoreSimulator/Devices/B5C5791C-3916-4BCB-8EB6-5D3D61C08DC0/data/Containers/Data/Application/4B644584-0025-45A7-9D71-C8F8478E4620/Documents/my PDF.pdf"
pdfView.document = getDocument(path: filePath)
pdfView.backgroundColor = .lightGray
pdfView.autoScales = true
pdfView.displayMode = .singlePageContinuous
pdfView.usePageViewController(true, withViewOptions: nil)
createMenu()
thumbnail()
/* swipe gesture */
let leftSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(respondLeftSwipeGesture(_:)))
leftSwipeGesture.direction = [UISwipeGestureRecognizer.Direction.left]
self.view.addGestureRecognizer(leftSwipeGesture)
let rightSwipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(respondRightSwipeGesture(_:)))
rightSwipeGesture.direction = [UISwipeGestureRecognizer.Direction.right]
pdfView.addGestureRecognizer(rightSwipeGesture)
}
#objc func respondLeftSwipeGesture(_ sender: UISwipeGestureRecognizer) {
if pdfView.document == nil { return }
pdfView.goToPreviousPage(self)
}
#objc func respondRightSwipeGesture(_ sender: UISwipeGestureRecognizer) {
if pdfView.document == nil { return }
pdfView.goToNextPage(self)
}
func getDocument(path: String) -> PDFDocument? {
let pdfURL = URL(fileURLWithPath: path)
let document = PDFDocument(url: pdfURL)
return document
}
}
You might simply set the displayMode to continuous and it might work:
pdfView.displayMode = .singlePageContinuous

Swift onfinish load event of a UIWebView

I'm loading a pdf in WebView from my server with this code :
webView = UIWebView(frame: CGRectMake(0, y, screenSize.width, screenSize.height-y))
let url : NSURL! = NSURL(string: urlFile)
webView?.loadRequest(NSURLRequest(URL: url))
webView?.opaque = false;
webView?.backgroundColor = UIColor.clearColor()
webView?.scalesPageToFit = true;
self.view.addSubview(webView!)
This code works but how can i receive an event "onPageLoad"?
sorry for bad english, i'm italian(:
You need to implement UIWebViewDelegate like this and use webViewDidFinishLoad to know the page is loaded successfully, for that set the webView delegate with your viewController like this, and implement the webViewDidFinishLoad method inside your viewController like below example.
import UIKit
class ViewController: UIViewController, UIWebViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
webView = UIWebView(frame: CGRectMake(0, y, screenSize.width, screenSize.height-y))
let url : NSURL! = NSURL(string: urlFile)
webView?.loadRequest(NSURLRequest(URL: url))
webView?.opaque = false;
webView?.backgroundColor = UIColor.clearColor()
webView?.scalesPageToFit = true;
webView?.delegate = self// Add this line to set the delegate of webView
self.view.addSubview(webView!)
}
func webViewDidFinishLoad(webView : UIWebView) {
//Page is loaded do what you want
}
}
In case someone is looking solution for WKWebView, implement WKNavigationDelegate:
add webView.navigationDelegate = self
and then use:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
After webView?.loadRequest(NSURLRequest(URL: url)) this, set the webView to self (Write the below line).
webView.delegate = self
Implement the webview delegate methods.
You will get callback in func webViewDidFinishLoad(_ webView: UIWebView) on completing the page load.
func webViewDidFinishLoad(webView: UIWebView) {
//handle the callback here when page load completes
}
Just use effective with ;
func webViewDidFinishLoad(webView : UIWebView) {
// Here your loaded codes.
}

Activity indicator swift

I'm trying to set up an activity indicator on my TableView where is my news feed is displayed. So I want that idicator to appear whenever load starts and disappear when it ends.
I know there is a function for webView like this:
func webViewDidFinishLoad(webView: UIWebView) {
activityView.removeFromSuperview()
}
func webViewDidStartLoad(webView: UIWebView) {
self.view.addSubview(activityView)
}
But it won't work for Table View obviously. Can someone suggest a solution?
I've tried to apply an activity indicator both in the center of my screen and in my Status bar but to no succsess.
I can add full code of my TableView controller if needed.
Thank you!
EDIT
override func viewDidLoad() {
super.viewDidLoad()
// Cell height.
self.tableView.rowHeight = 70
self.tableView.dataSource = self
self.tableView.delegate = self
url = NSURL(string: "http---")!
//url = NSURL(string: "http---")!
//url = NSURL(string: "http---")!
loadRss(url);
To show the small activity indicator in the status bar
func webViewDidFinishLoad(webView: UIWebView) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
}
func webViewDidStartLoad(webView: UIWebView) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}
show the small activity
This is links you can see the answer

Resources