I'm attempting to load a preview of a website into a UIImageView. I have the following method that is called when the requested website url is received:
func loadWebsite(item:ShareItem) {
activitySpinner.startAnimating()
imageView.setImageForURL(item.asset!.absoluteString) { (image) in
self.showActionButton(true)
self.activitySpinner.stopAnimating()
self.actionButton.titleLabel?.text = "Open"
}
}
I believe there's an error in my logic in the setImageForURL website, which is what is supposed to load the website into my custom image view class:
class MyCustomImageView:UIImageView, UIWebViewDelegate {
var webview:UIWebView?
var completion:((UIImage?)->Void)?
func setImageForURL(urlString:String, completion:((image:UIImage?)->Void)?) {
self.completion = completion
guard let url = NSURL(string: urlString) else {
self.completion?(nil)
return
}
let request = NSURLRequest(URL: url)
webview = UIWebView(frame: self.bounds)
webview!.delegate = self
webview?.scalesPageToFit = true
webview!.loadRequest(request);
}
Does anyone have some insight into how I'm approaching this incorrectly? All the methods are called correctly and in the right order, but no image is shown in the UIImageView.
You need to add the Webview to the image view at some point. By this I mean, using the addSubview method on the imageView, and all this before calling the loadRequest method on the webview. Your webview needs to have a "physical" frame and exist within a parent view before you can load the content.
Related
I am downloading files from server and showing in my ios device. File type can be any thing like image, pdf etc. and all loading up fine. Now the problem is, some part of file or image is hiding behind the title of page. I want to add margin at top of file after it loads up.
Code I have written to show file:
func openFile(file:String) {
let myBlog = file
let url = NSURL(string: myBlog)
let request = NSURLRequest(url: url! as URL)
webView.load(request as URLRequest)
self.view.addSubview(webView)
let pdfVC = UIViewController()
pdfVC.view.addSubview(webView)
pdfVC.title = "File"
self.navigationController?.pushViewController(pdfVC, animated: true)
self.navigationController!.navigationBar.tintColor = colors.whiteColor
}
I have created webView property within Class like:
var webView : WKWebView!
And inside viewDidLoad(), I have written:
webView = WKWebView(frame: self.view.frame)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.isUserInteractionEnabled = true
webView.navigationDelegate = self
Result I am getting:
Here some part of image is behind the title. I have tried verious solutions given in link add margins in swift, but nothing is working.
My suggestion is to create instance of WKWebView in controller where you need to display it, in your case instance pdfVC
There is can be model, for example:
enum FileType {
case image(fileURL: URL)
case pdf(fileURL: URL)
}
Creating incase of FileViewController and assign fileType to it
func openFile(file:String) {
let pdfViewController = FileViewController()
pdfVC.fileType = FileType.pdf(fileURL: URL(string: "https://www.google.com")!) // example
pdfVC.title = "File"
navigationController?.pushViewController(pdfVC, animated: true)
}
And inside your VC where you need to display a file:
In this way, even if you do have navigationBar you won't have problem with navigationBar and topMargin
class FileViewController: UIViewController {
var fileType: FileType!
override func viewDidLoad() {
super.viewDidLoad()
var urlRequest: URLRequest!
switch fileType {
case .image(let url), .pdf(let url):
urlRequest = URLRequest(url: url)
#unknown default:
break
}
let webView = WKWebView(frame: view.frame)
webView.load(urlRequest)
self.view = webView
}
}
Hope this will help you!
use Bounds instead of Frame
webView = WKWebView(frame: self.view.Bounds)
I'm editing a record which has some text information and images. As I get images URL so I'm using SDWebImage to download images which are then displayed in a collectionView and it's vertical scrollable. So when the view is loaded I'm doing this in viewDidLoad:
for (index, _) in mediaFiles.enumerated()
{
let img = UIImageView()
if let url = NSURL(string: "\(baseURLGeneral)\(mediaFiles[index].imageFile ?? "")")
{
print(url)
img.sd_setShowActivityIndicatorView(true)
img.sd_setIndicatorStyle(.gray)
img.sd_setImage(with: url as URL, placeholderImage: nil, options: .refreshCached, completed: { (loadedImage, error, cache, url) in
self.imagesArray.append(loadedImage!)
DispatchQueue.main.async
{
self.photoCollection.reloadData()
}
})
}
}
This code as per my understanding is downloading the image from web and when the image is loaded it add the image in an imageArray which I've declared as var imagesArray: [UIImage] = [] and then reload the collection view.
As this is the edit screen so user can also add more images in imagesArray which will show with the downloaded images in the same array and can also remove images.
As per collectionView delegate and dataSource is concerned so I'm returning return imagesArray.count in numberOfItemsInSection.
In cellForItemAt after making a cell variable I've cell.imageAddedByUser.image = imagesArray[indexPath.row].
THE ISSUE which I'm having is that after downloading images in viewDidLoad() collectionView is not getting refreshed. But If I pop and then push view controller it shows the images.
Try to call it in viewDidAppear()
DispatchQueue.main.async { self.photoCollection.reloadData() }
Try to dispatch it in main Queue
DispatchQueue.main.async
{
self.photoCollection.reloadData()
}
I'm working on a native app that uses a webview for most of the functionality, and it uses tokbox video for native video communication. When I initially load the app, the webview loads fine (its created in interface builder).
When a person goes to the video page, I believe the tokbox API makes the webview nil. Once the video is over, I call session.disconnect() and try to reload my webview, but it keeps saying found nil while trying to unwrap optional.
The code that loads the webview looks like this:
func loadApp() {
let htmlFile = Bundle.main.path(forResource: "index", ofType: "html")
let html = try? String(contentsOfFile: htmlFile!, encoding: String.Encoding.utf8)
// this was added in hopes of initializing the webview again
if webView == nil {
webView = UIWebView(frame: self.view.bounds)
self.view = webView
}
webView.delegate = self
webView.frame = view.bounds
webView.loadHTMLString(html!, baseURL: nil)
}
it keeps failing at webView.delegate = self and the instance variables show that webView is still nil even after the if condition.
EDIT
the webview was hooked by clicking control and dragging to the UIViewController and it looks like this:
#IBOutlet weak var webView: UIWebView!
the loadApp() function is called in 2 places, first in viewDidLoad() where it works fine, but then after calling session.disconnect(), a tokbox callback delegate method is called:
func sessionDidDisconnect(_ session: OTSession) {
print("The client disconnected from the OpenTok session.")
loadApp()
}
this is the second time/place where loadApp() is called, and where it fails.
I don't think webView should be set to nil when you have it setup as a IBOutlet. Try just having webView be var webView: UIWebView? a variable inside of the class and then instantiate it manually and adjust the constraints and position it accordingly.
In my iphone app I've got to load a mobile website to a webview (that contain in a separate viewcontroller). All good and working fine.
I need to exit from webview when reach to specific set of URL's. The problem is some of these url's does not exis and therefore page does not finish load (Even with page not found error message to detect current url. Just hangs)
Would like to know if I have to enable any setting in the webView to allow load pages that does not really exist (With page not found error).
OR
Is this possible to know which URL going to load next in
func webViewDidStartLoad(webView: UIWebView)
override func viewDidLoad()
{
super.viewDidLoad()
myWebview.delegate = self
var returnUrlAppendedPaymmentLink = "www.existing_url.com"
let requestURL = NSURL(string: returnUrlAppendedPaymmentLink)
let request = NSURLRequest(URL: requestURL!)
myWebview.loadRequest(request)
}
func webViewDidFinishLoad(webView: UIWebView)
{
var currentUrl = webView.request?.URL?.absoluteString ?? ""
if (currentUrl == "www.special_url.com")
{
self.navigationController?.popViewControllerAnimated(true)
}
}
To intercept specific URLs, use the shouldStartLoadWithRequest delegate method of UIWebView.
You can check the URL of the request in this method to see if this is your "special" URL, do your handling for this case and return false so the web-view won't load it.
I'm trying to make a simple web browser application in Swift to learn the language. Right now, I'm stuck on allowing the user to tap a bookmark they recently added, and having the webview load the certain url.
To decide which URL to choose, I have this in my BookmarkTVC (TableViewController with bookmarks)
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
let vc = ViewController(nibName: "ViewController", bundle: nil)
vc.gotoWebsite(bookmarks[indexPath.row].url)
self.dismissViewControllerAnimated(true, completion: nil)
}
EDIT: Screenshot of BookmarksTVC: http://imgur.com/7rKcGBZ
I know 100% that the
bookmarks[indexPath.row].url
is getting the right string, because I println'd it.
Now, this is my vc.gotoWebsite function
func gotoWebsite(link: String) {
// Format Link
var formattedLink: String!
if link.hasPrefix("http://") || link.hasPrefix("https://") {
formattedLink = link
} else if link.hasPrefix("www.") {
formattedLink = "http://\(link)"
} else {
formattedLink = "http://www.\(link)"
}
// Goto formatted link
println(formattedLink)
let url = NSURL(string: formattedLink)
println(url)
let request = NSURLRequest(URL: url)
println(request)
webView.loadRequest(request)
}
On the webView.loadRequest(request) line, I get:
fatal error: unexpectedly found nil while unwrapping an Optional value
this is the breakpoint (Image): http://imgur.com/S7dMswD&4pdL4xX
even though I have println'd the request variable and got the response
<NSURLRequest: 0x7fb9c8616700> { URL: https://www.google.com/?gws_rd=ssl, headers: (null) }
Please help. Again, all I'm trying to do is get the url that is ssociated with the table view cell that the user clicked. Then, I'm using that string and calling a method from another class that goes to that URL.
I ran into this same problem. I overcame it by adding a request parameter to my UIViewController vc which displays the UIWebView:
var request: NSURLRequest? {
didSet {
if request != nil { // didSet is called even if you are setting request to nil :-(
webView?.loadRequest(request!) // do not load request if webView is nil
}
}
}
and then in the same viewController:
override func viewDidLoad() {
super.viewDidLoad()
// ...
if request != nil {
webView.loadRequest(request!)
}
}
so I can write in the calling code which instantiates the vc, instead of webView.loadRequest(),
vc.request = NSURLRequest(URL: NSURL(string: urlAsString)!)
and that will either trigger the webView to load via the didSet function if the webView has been defined by then, or, if it hasn't, will cause the webView to load in the viewDidLoad later. I don't know if that is perfect, but it works for me.