Can't get the right value for height of uiwebview - html

I am trying to get the value of uiwebview this way:
var webview = self.articleContent
println(webview.frame.size.height)
// prints 300
// rendering the webview
webview.loadHTMLString(articleHtmlContent, baseURL: nil)
// getting the height of the webview
var output = webview.stringByEvaluatingJavaScriptFromString("document.body.scrollHeight;")!
println(output)
// prints 300 - again
So it looks like the output I get is the height of the uiwebview instead of the height of the HTML content.
How can I get the height of the HTML contents?

Use its scroll view's content size which will be available after the web view responds to webViewDidFinishLoad on its UIWebViewDelegate like this:
func webViewDidFinishLoad(webView: UIWebView!) {
CGFloat totalHeight = webview.scrollView.contentSize.height
}

Related

Adjusting the height of a wkwebview programmatically

This is my first question on Stack Overflow. I just started learning swift programming and got sucked into something.
I followed IAP tutorials on YouTube and successfully implemented AdMob banners and interstitial ads in my app. I was also able to turn off ads using the IAP. My question is:
I have a view in which I have two UI elements (WKWebViewand a GADBannerView). The WKWebView element covers 90% of the screen starting from x:0,y:0, whereas the GADBannerView element covers 10%. I turned off ads and hid the GADBannerView element using IAP.
Now I want to dynamically/programmatically adjust the WKWebView size to fill the entire screen, i.e 100%. In other words, I want the WKWebView element to extend over the hidden GADBannerView element.
This is because hiding the GADBannerView leaves a blank field which is not cool to the view and the WKWebView looks truncated.
Please note that neither of the views are subviews. Both are independent views added separately. I understand that I can initially make the web view fill entire screen, add the GADBannerView on top of it, and when I remove ads and hid the GADBannerView, the web view will fill screen. That is not what I want because some content of the web view can not be seen using this approach. If I have a button at the end of HTML page that loads on the web view, this button can not be clicked because it will always be behind the gad banner view even when scrolling reached the bottom. Yes, you can scroll and hold to see the button, but once you release it, it will go back down.
So as a recap, I have two separate views and want to hid one and extend the length of the other to cover the entire screen.
Please tell me how to achieve that.
thirdBannerView.isHidden = true //Hide the banner view
//then code below to increase the size of the web view to equal device //screen width and height i.e full screen.
func webViewDidFinishLoad(webView: WKWebView) {
//let screenBounds = UIScreen.main.bounds
// let heightq = screenBounds.height
//let widthq = screenBounds.width
//webView.frame.size.height = heightq
//webView.frame.size = webView.sizeThatFits(CGSize.zero)
//webView.frame = CGRectMake(0, 0, widthq, heightq);
webView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
}
This code is not effective at all as nothing changes. Please let me know how to achieve this.
This particular scenario looks promising for applying UIStackview. Add your two view ( WKWebview and GADBannerView). apply fixed height for the GADBannerview. Whenever necessary just hide the GADBannerview.
Sample code
class StackviewController : UIViewController {
let stackview: UIStackView = {
let view = UIStackView()
view.axis = .vertical
view.distribution = .fill
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// Your WKWebview here
let sampleWKWebView: UIView = {
let view = UIView()
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// Your GADBannerView here
let sampleGADBannerView: UIView = {
let view = UIView()
view.backgroundColor = .green
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
func setupViews() {
view.addSubview(stackview)
stackview.addArrangedSubview(sampleWKWebView)
stackview.addArrangedSubview(sampleGADBannerView)
NSLayoutConstraint.activate([
stackview.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
stackview.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
stackview.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0),
stackview.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0),
sampleGADBannerView.heightAnchor.constraint(equalToConstant: 100.0)
])
// Enable this line to hide the GADBannerView
// sampleGADBannerView.isHidden = true
}
}
Here is the output
I use two UIView to represent the WKWebView & GADBannerView. In the sample code uncomment the following to hide the bottom banner like green view.
sampleGADBannerView.isHidden = true

Can't measure Clientwidth of Html-Image in Firefox

I am trying to place markers on points of interest (poi) on an Image.
These poi have been set in a different software and were stored in a database. The position is determined by their pixel position relative to the original Image. In my webapp the Images are scaled down thanks to panzoom.js (a plugin irrelevant to my question I think). I got the right formula to scale the markerposition, the only Problem is:
In firefox I'm unable to read the Images size in time (In Chrome that's not an Issue).
This is the Code
$(document).ready(function ()
{
var imagectrl = document.getElementById('<%= img.ClientID %>');
var hiddenfield = document.getElementById('<%= hf.ClientID %>');
if (hiddenfield.value == "")
{
var myWidth;
var myHeight;
myWidth = imagectrl.clientWidth;
myHeight = imagectrl.clientHeight;
hiddenfield.value = myWidth + ';' + myHeight;
__doPostBack();
}
});
If I do a postback manually (clicking a button that shows the Image in higher quality) the size gets written correctly.
I've also tried calling an identical function from Code behind when my X or Y are 0, but nothing worked.
What can i do to get the Images size when first loading the page?
Firefox has a different implementation on asynchronous operations like image loading than Chrome. I guess this could be the reason why in Chrome you can access the image right away with $(document).ready, but in Firefox the image source gets loaded after the document is ready - thus clientWidth and clientHeight will be undefined.
Solution: Define an onload event handler on your image and put your logic into that method:
$(document).ready(function ()
{
var imagectrl = document.getElementById('<%= img.ClientID %>');
var hiddenfield = document.getElementById('<%= hf.ClientID %>');
imagectrl.onload = function() {
if (hiddenfield.value == "")
{
var myWidth;
var myHeight;
myWidth = imagectrl.clientWidth;
myHeight = imagectrl.clientHeight;
hiddenfield.value = myWidth + ';' + myHeight;
__doPostBack();
}
}
});
I found a Solution:
No matter what I did, the Image itself can't be measured in time.
So i gave the Image the height of it's surrounding control via CSS and used
AddHandler dvGalerieFill.Load, AddressOf Me.measure_height
in the Page_Load method to react to the loading of the surrounding control.
In "measure_height" I called my Javascript function.
Through the height of the control (wich is the height of my image)
I can calculate the width of my image as height and width rescale with the same factor.

How to set UIWebView initial position?

How to set the initial focus in a HTML page using UIWebView. For example, below is the HTML page. If i load this in UIWebView, it shows from (0,0) coordinates of a HTML view. But i want to change the starting position as described in the below image. I tried to change the offset, but no use.
webView.scrollView.contentOffset = CGPointMake(100, 100).
You probably shouldn't hard code this because for one reason, it's hard-coded. If google, or whatever website you want to display alters their layout your positions will be obsolete. And you will have to resubmit your entire app just to off-set this.
My recommendation is use auto layout and 'scales page to fit' for the UIWebView.
But your code is accurate. Make sure you put it in webViewDidFinishLoad: or viewDidLoad and your UIWebViewDelegate & UIScrollViewDelegate are added to your header file and called in your implementation file :
self.webView.delegate = self;
self.webView.scrollView.delegate = self;
Place the UIWebView into a subview. A generic UIView will work.
When instantiating the UIWebView, give it screen bounds with a slightly lower width than the containing UIView. Weird, I know.
Set the UIWebView's contentOffset in the webViewDidFinishLoad method of your UIWebViewDelegate
The following code works for me, in Xcode 6.1.1. To test, just make this ViewController class the root view controller for your app:
import UIKit
class ViewController: UIViewController, UIWebViewDelegate {
override func loadView () {
let screenBounds : CGRect = UIScreen.mainScreen().bounds
var slimmerBounds : CGRect = UIScreen.mainScreen().bounds
slimmerBounds.size.width = slimmerBounds.size.width - 1
let webView = UIWebView(frame: slimmerBounds)
let url = NSURL (string: "http://google.com/")
let req = NSURLRequest(URL: url!)
webView.loadRequest(req)
webView.delegate = self;
let contentView = UIView(frame: screenBounds)
contentView.addSubview(webView)
self.view = contentView
}
func webViewDidFinishLoad(webView: UIWebView) {
webView.scrollView.contentOffset = CGPointMake(0, 100)
webView.bounds = UIScreen.mainScreen().bounds
}
}
By the way ... this will set the initial position of all URLs loaded into this Web view. If you only want to position the first page, you'll need to add some additional logic to webViewDidFinishLoad

Get a Google Chart image to fill the width of a DIV

I'm fetching some line charts using Google's Chart API and placing it in a DIV like this:
<div class="chart" style="display:block">
<img src="http://chart.apis.google.com/chart?chs=620x40&cht=lfi&chco=0077CC&&chm=B,E6F2FA,0,0,0&chls=1,0,0&chd=t:27,25,25,25,25,27,100,31,25,36,25,25,39,25,31,25,25,25,26,26,25,25,28,25,25,100,28,27,31,25,27,27,29,25,27,26,26,25,26,26,35,33,34,25,26,25,36,25,26,37,33,33,37,37,39,25,25,25,25">
</div>
I have to pass the height and width of the chart image required and the Google Chart API renders it e.g. chs=620x40. I'd like the chart image to be the with of my parent div. I need to calculate the width and dynamically construct this chart URL so that I get a chart image of the right size. How can I do this?
(I'm not too bright with jQuery and I'm trying to avoid using some bloated libraries)
Thanks
You can use the following JavaScript (with jQuery):
function sizeCharts(){
$(".chart").each(function(){
var w = $(this).width();
var h = $(this).height(); // or just change this to var h = 40
$("<img>").attr("src","http://chart.apis.google.com/chart?chs=" + \
escape(w) + "x" + escape(h) + "&[etc]").appendTo(this);
});
}
$(function(){
sizeCharts();
var shouldResize = true;
$(window).bind("resize",function(){
if(!shouldResize){
return;
}
shouldResize = false;
setTimeout(function(){
sizeCharts();
shouldResize = true;
},1000);
});
});
Replace [etc] with the rest of the url you wish to use. What happens in the above code is it will iterate through everything with the chart class in your page and puts the chart into it with the appropriate size.
If you use a liquid layout (i.e. your site resizes to fill a certain percentage of the screen), then you will also want to include the $(function(){ ... }) bit, which runs the same code when the page is resized. Note the use of timers here, otherwise the same chart will be reloaded for every pixel that the window is resized.

Showing a large amount of HTML alternative content with swfobject & swffit flash site

I have a full flash site which uses swfobject to embed it 100% height and width. I'm using swffit to force a browser scroll bar for pages with a large amount of content. This is all fine and works perfectly. I also have the content in HTML format, as alternative content and this also works apart from in order to get the flash swfobject to work I need to add the overflow = hidden in the CSS, like:
html{
height: 100%;
overflow:hidden;
}
#content{
height: 100%;
}
This then stops the scroll bar showing when the alternative content is shown.
Does anyone know how to fix this?
I don't know SWFFit but why do you need the overflow: hidden in the first place? Won't it work without?
The only workaround that comes to mind is to define two classes, one with, one without overflow: hidden, and change the class of the html element programmatically from within Flash by triggering some Javascript.
If you need to change a page's CSS or content based on the success of a SWFObject embed, use the callback function feature in SWFObject 2.2.
For dynamic publishing, it looks like this:
var flashvars = {};
var params = {};
var attributes = {};
var embedHandler = function (e){
};
swfobject.embedSWF("mymovie.swf", "targetID", "550", "400", "9.0.0", "expressInstall.swf", flashvars, params, attributes, embedHandler);
In your situation, if you needed to remove overflow:hidden from the HTML element, you could do this:
var flashvars = {};
var params = {};
var attributes = {};
var embedHandler = function (e){
//If embed fails
if(!e.success){
document.getElementsByTagName("html")[0].style.overflow = "auto";
}
};
swfobject.embedSWF("mymovie.swf", "targetID", "550", "400", "9.0.0", "expressInstall.swf", flashvars, params, attributes, embedHandler);
This callback function feature is only available in SWFObject 2.2.