Currently i got a small problem with WebViews that dont release there memory usage in time, i m calling some webviews (the user can open them switch back to a map (via Tabbar) and open a new one),
Everytime a WebView is called it use up to 30MB RAM, so after 10 WebViews the App runs into a memory warning, so i m looking for a way (as i found in other Posts there is no way caus it handled automatic) to release the memory after switching back to the map from the webview.
This is how i call my WebView
import UIKit
class ViewController_webView: UIViewController {
/* ################################################## IBOutlets ################################################## */
#IBOutlet weak var webView: UIWebView!
#IBOutlet weak var TBB_shop: UITabBarItem!
#IBOutlet weak var activity: UIActivityIndicatorView!
/* ################################################## Home Button ################################################## */
#IBAction func BThome(sender: AnyObject) {
var shopurl = "http://google.com"
let webviewURL = NSURL(string: shopurl)
let request = NSURLRequest(URL: webviewURL)
webView.loadRequest(request)
}
/* ################################################## ViewDidLoad ################################################## */
override func viewDidLoad() {
super.viewDidLoad()
var TBB_shop_img = UIImage(named: "TabbarShopping.png") as UIImage
TBB_shop.selectedImage = TBB_shop_img
}
/* ################################################## MemoryWarning ################################################## */
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
println("Memory Warning")
}
/* ################################################## viewWillAppear ################################################## */
override func viewWillAppear(animated: Bool) {
var shopurl = "http://google.com"
let webviewURL = NSURL(string: shopurl)
let request = NSURLRequest(URL: webviewURL)
webView.loadRequest(request)
}
/* ################################################## Activity Indicator ################################################## */
func webViewDidStartLoad(_ : UIWebView){activity.startAnimating()}
func webViewDidFinishLoad(_ : UIWebView){activity.stopAnimating()}
}
Is there anyway to use the
override func viewDidDisappear(animated: Bool) {
<#code#>
}
to release the memory usage of a webview? Or anyway to reduce the usage of memory?
From your code I deduce that the webView is in a nib.
To reduce the memory footprint, you might want to try creating and removing the webView in viewWillAppear and viewWillDisappear, respectively.
This would mean that you might have to re-load the content if the user were to go back to it. Annoying from the user perspective.
Releasing memory can depend on how you are bringing up the view - here is a modal presentation of a view controller - this will not release memory of a previously loaded view controller:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("WebViewController") as WebViewController
let navigationController = UINavigationController(rootViewController: vc)!
self.presentViewController( navigationController, animated: true, completion: nil)
Below is a case where the rootViewController is replaced with the new controller - in this case the rootViewController value is changed - so the original view controller (if one was loaded before) reference count goes down to 0 and should be removed from memory, in theory:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("WebViewController") as WebViewController
let navigationController = UINavigationController(rootViewController: vc)!
let window = UIApplication.sharedApplication().windows[0] as UIWindow
window.rootViewController = navigationController
I tried the latter case in a code situation like what is described in the question. I saw an improvement in memory releasing, however I have to admit that the memory did not go back where I started from - don't know why. I hope somebody has a better solution.
Related
I am new to iOS development, I have created android app where app gets sets of images (sometimes over 100 images) from urls and loads into imageView with zoomEnabled Inside ViewPager.
Now I want to create same app for iOS, I have found this lib ImageSliderShow. Problem with this is it shows fullscreen ONLY when user did tap on selected image. I have been struggling to presentFullScreenController on viewDidLoad with no lock.
I only want image to be shown in fullScreen, example:
Select Category A From CategoryVC -> Loads ImageSlideVC, gets set of images from server, show in FullScreenView.
How can i achieve this? Adding this:
slideshow.presentFullScreenController(from: self)
on viewDidLoad didn't work:
#IBOutlet var slideshow: ImageSlideshow!
let kingfisherSource = [KingfisherSource(urlString: "https://images.unsplash.com/photo-1447746249824-4be4e1b76d66?w=1080")!,
KingfisherSource(urlString: "https://images.unsplash.com/photo-1447746249824-4be4e1b76d66?w=1080")!,
KingfisherSource(urlString: "https://images.unsplash.com/photo-1463595373836-6e0b0a8ee322?w=1080")!]
override func viewDidLoad() {
super.viewDidLoad()
slideshow.setImageInputs(kingfisherSource)
slideshow.presentFullScreenController(from: self)
}
I dont get any error, output is same as before (shows slideshow in smallview with no zoom)
Please help
EDIT
by doing in viewDidAppear, after split second view is loaded its loads into fullscreen. First its smallview then shows in fullscreen. I think i have to do something inside setImageInputs
this is what its looks like :
open func setImageInputs(_ inputs: [InputSource]) {
self.images = inputs
self.pageControl.numberOfPages = inputs.count
// in circular mode we add dummy first and last image to enable smooth scrolling
if circular && images.count > 1 {
var scImages = [InputSource]()
if let last = images.last {
scImages.append(last)
}
scImages += images
if let first = images.first {
scImages.append(first)
}
self.scrollViewImages = scImages
} else {
self.scrollViewImages = images
}
reloadScrollView()
layoutScrollView()
layoutPageControl()
setTimerIfNeeded()
}
try to do it in viewDidAppear
#IBOutlet var slideshow: ImageSlideshow!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
slideshow.setImageInputs(kingfisherSource)
slideshow.presentFullScreenController(from: self)
}
Presenting viewController in ViewDidLoad is a bad practice.
I have made a baseViewController which is derived from UIViewController, SlideMenuDelegate and UIWebViewDelegate
Then I have created subclass which are derived from baseviewcontroller
LoginVC - displays login screen
PlayVC - shows a webview if login is successful.
Everything is fine except that webview is not scrolling at all.
I have tried everything suggested in all posts so far regarding scrolling
Below is my code written in PlayVC.swift
#IBOutlet weak var web1: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
addSlideMenuButton()
let webUrl : URL = URL(string: "http://brainyknights.com")!
let webRequest : URLRequest = URLRequest(url: webUrl)
web1.scalesPageToFit = true
web1.isUserInteractionEnabled = true
web1.scrollView.isScrollEnabled = true
web1.loadRequest(webRequest)
// Do any additional setup after loading the view.
}
remove this line web1.scalesPageToFit = true
#IBOutlet weak var web1: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
addSlideMenuButton()
let webUrl : URL = URL(string: "http://brainyknights.com")!
let webRequest : URLRequest = URLRequest(url: webUrl)
//web1.scalesPageToFit = true
web1.isUserInteractionEnabled = true
web1.scrollView.isScrollEnabled = true
web1.loadRequest(webRequest)
// Do any additional setup after loading the view.
}
According Apple Documentation
scalesPageToFit
A Boolean value determining whether the webpage scales to fit the view
and the user can change the scale.
if web1.scalesPageToFit is true then the web content will fit in your UIWebView frame and the contentSize will have the same height and width as your UIWebViewframe making imposible to be scrollable
so remove this line and must work
web1.scalesPageToFit = true
I hope this helps you
I have the following code for a view which is one of the options attached to a tab on a Tab Bar Controller (swift 3):
import UIKit
class SecondViewController: UIViewController {
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let str8REDURL = URL(string: "https://str8red.com/leaderboard/")
let str8REDURLRequest = URLRequest(url: str8REDURL!)
webView.loadRequest(str8REDURLRequest)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is working perfectly. However, the user can currently have a browse of the site and then select another tab. When they select this tab I would like the webView to reload the URL as above, so basically resetting that view as if it had just loaded. I am assuming there is some "reload" option but can't seem to work it out and would appreciate any guidance.
UPDATE
After a few suggestions I even tried the following with no joy:
func viewWillAppear() {
let str8REDURL = URL(string: "https://str8red.com/leaderboard/")
let str8REDURLRequest = URLRequest(url: str8REDURL!)
webView.loadRequest(str8REDURLRequest)
}
Many thanks, Alan.
Just put the load request in viewWillAppear(), it will be called everytime you change the tab back to that screen
webview.loadRequest() will load the webview content. webview.reload() reloads the last request which has finished loading. Therefore for your case, you can use webview.reload()
I wonder if you can help as I am getting this error.
2016-07-17 20:13:01.312 ShortGameGolfAcademy[17843:6735678] This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release.
Stack:(
Now I think this has something to do with an embed YouTubeVideo code.
import UIKit
class ControlBackSwingViewController: UIViewController {
#IBOutlet weak var videoView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let youTubeUrl = "https://www.youtube.com/embed/TNY9xpW0idk"
videoView.allowsInlineMediaPlayback = true
videoView.loadHTMLString("<iframe width=\"\(videoView.frame.width)\" height=\"\(videoView.frame.height)\" src=\"\(youTubeUrl)\" frameborder=\"0\" allowfullscreen></iframe>", baseURL: nil)
// Do any additional setup after loading the view.
}
Now I am going from a Static UITableView to a WebView in a Storyboard.
Try putting the code in question in this code block:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("This is run on the main queue, after the previous code in outer block")
})
I am having trouble resolving an odd issue with my webView. I am attempting to load a web page (any web page) in a webView which is the sole object within a UIViewController. When I create an instance of the view controller and push it onto the stack, the screen is blank and white. For now I am attempting to load www.apple.com. Here is the relevant code:
UIViewController:
import UIKit
class GoodReadsVC: UIViewController {
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL (string: "http://www.apple.com")
let requestObj = NSURLRequest(URL: url!)
webView?.loadRequest(requestObj);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
For what it is worth, I know that the webView is indeed connected to the xib, due to the little dot being filled in the left margin.
Pushing the controller onto the nav stack:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let bookWebView = GoodReadsVC(nibName: "GoodReadsVC", bundle: NSBundle.mainBundle())
self.navigationController!.pushViewController(bookWebView, animated: true)
tableView.reloadData()
}
What am I doing wrong?
This was a case of the loading being blocked by this error:
Transport security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
The solution to this problem may be found here:
Transport security has blocked a cleartext HTTP