Reset Zoom on iOS after viewport width change - ios

we are making an HTML5 app where width is not know at design time.
So we change the viewport tag at runtime to match the desidered size.
e.g.
<meta name="viewport" id="viewport-meta" content="width=' + params.mobilePortraitWidth + ', initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
The problem on iOS is that after we change the viewport size, view is not correctly scaled until we double tap the screen.
EDIT, after double tap is all fine, so: how can we "DOUBLE TAP" programmatically?
Thank you very much

NSString *js = #"var t=document.createElement('meta'); t.name="viewport"; t.content="initial-scale=1.0, maximum-scale=3.0"; document.getElementsByTagName('head')[0].appendChild(t);";
[myWebView stringByEvaluatingJavaScriptFromString:js];
EDIT
Thanks for update.
I had very similar issue and remember that setting viewport meta tag solved it.
If you are trying to modify this meta tag just after loading html, try doing that in webViewDidFinishLoad (loadRequest is asynchronous).
Another solution would be to read your html file into NSString and replace that meta tag before loading it to webView.
Hope it helps!

Thank you very much for your replies, I would like to share the solution we found after some test on iPhone 5s with iOS 9.2 and iPad Air with iOS 8.4.
Basically, to make it work, we didn't set initial-scale=1.0, maximum-scale=1.0, user-scalable=no
Following a working example
<html>
<head>
<meta name="viewport" id="viewport-meta" content="width=device-width, user-scalable=no" />
<style>
html, body { -webkit-text-size-adjust: 100%; }
h1 { padding: 1em; background-color: #FF80BB; }
</style>
</head>
<body>
<h1>I am the page content</h1>
<button id="s320">Set 320</button><br />
<button id="s640">Set 640</button><br />
<button id="s960">Set 960</button>
<script>
function setViewportWidth(newWidth) {
var m = document.getElementById("viewport-meta");
m.setAttribute('content', 'width=' + newWidth + ', user-scalable=no');
}
document.getElementById("s320").onclick = function () { return setViewportWidth(320); };
document.getElementById("s640").onclick = function () { return setViewportWidth(640); };
document.getElementById("s960").onclick = function () { return setViewportWidth(960); };
</script>
</body>
</html>

Related

How to get Pixijs with Cocoonjs to use a WebGLRenderer with canvas+ webview engine

I can't seem to get the canvas+ webview engine within Cocoon to use a PIXI.WebGLRenderer no matter what I try. Here is a simple example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<script type="text/javascript" src="http://pixijs.download/release/pixi.js"></script>
<title>Simple Test</title>
</head>
<body style="background-color: #99ff99; margin: 0; padding: 0;" onload="runTest()">
<script>
function runTest() {
var renderer = PIXI.autoDetectRenderer( 500, 200 );
document.body.appendChild( renderer.view );
var stageContainer = new PIXI.Container();
var text = new PIXI.Text( 'renderer.type='+renderer.type, { fontFamily: "Arial", fontSize: '12px', fill: "white" } );
text.x = text.y = 50;
stageContainer.addChild( text );
renderer.render( stageContainer );
}
</script>
</body>
</html>
With the Cocoon Launcher app I've tested this on:
iPhone5 (iOS 10.2)
iPad2 (iOS 9.3.5)
HP 10 Plus (android 4.4.2)
With webview+, all display "renderer=1" (which means PIXI.WebGLRenderer)
But with canvas+, all display "renderer=2" (which means PIXI.CanvasRenderer)
Is it possible to get canvas+ mode to work with WebGL in Pixi.js?
I have also tried forcing the renderer to be WebGL by replacing the autoDetectRenderer line with:
var renderer = new PIXI.WebGLRenderer( 500, 200 );
In this case my Cocoon Launcher on iphone and ipad crashes!
On the android, it just shows a black screen.
I have also tried with Pixi.js v3.0.1 with the same results.
So, is it possible to use WebGL with Cocoon's Canvas+ mode with Pixi.js?
Any help much appreciated, thanks
I managed to get it working, but not with the latest Pixi.js (v4.2.3), only with an old version - v3.0.10.
The key was to add cordova.js and use the document.addEventListener( "deviceready", runTest, false );
Here is some updated code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<script type="text/javascript" src="cordova.js"></script>
<script src="js/pixi-3.0.10.js"></script>
<title>Simple Test</title>
</head>
<body style="background-color: #99ff99; margin: 0; padding: 0;">
<script>
function runTest() {
var renderer = new PIXI.WebGLRenderer( 300, 100 );
document.body.appendChild( renderer.view );
var stageContainer = new PIXI.Container();
var text = new PIXI.Text( 'rrr.type='+renderer.type, { fontFamily: "Arial", fontSize: '12px', fill: "white" } );
text.x = text.y = 50;
stageContainer.addChild( text );
renderer.render( stageContainer );
}
document.addEventListener( "deviceready", runTest, false );
</script>
</body>
</html>
This is only a partial answer because it only works with an outdated version of Pixi.js
As for me, I'm abandoning canvas+ for now because what I got working showed poor and erratic results compared with the webview+ mode. Also, as an aside, according to various performance tests I've made, it seems that the old Pixi.js v3.0.10 is dramatically out performing v4.2.3 as well.. so looks like I'll be sticking with that also.

Xamarin Forms webview content not showing first time

I'm working with WebView on Xamarin Forms 1.4.2
The problem I have seems to be a binding issue. But I'm not sure why this happens.
In my OnAppearing() event, I fetch data from SQLite Local Database and fill it into the WebView.
The content of webview is not been shown the first time the page loads.
I have a ListView under the WebView. On selecting any item in the listview the content of webview shows.
Has anyone experience this? Is there a work around?
i bind my webview directly to a HTML string :
webview.Source = new HtmlWebViewSource
{
Html = #"<html>
<head>
<meta name='viewport' content='width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;'/>
</head>
<body height='100%'>"
+ htmlstring
+ #"</body>
</html>"
};
This is because of your line
<meta name='viewport' content='width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;'/>
Correct it, or for now remove it and check after removing.
I've tried the following example and it works for me.
Depending on what you do in the OnAppearing you may have to wrap the update using Xamarin.Forms.Device.BeginInvokeOnMainThread(()=>{...});. I've included it, commented out, in the example below:-
XAML:-
<StackLayout>
<WebView x:Name="webView1" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
<Button x:Name="cmdLoadTestHtml1" Text="Load Test Html 1" Clicked="cmdLoadTestHtml1_Clicked"/>
</StackLayout>
Code Behind:-
protected override void OnAppearing()
{
base.OnAppearing();
//
LoadTestHtml("OnAppearing....");
//
// Alternatively try this:-
//Xamarin.Forms.Device.BeginInvokeOnMainThread(() =>
// {
// LoadTestHtml("OnAppearing.");
// });
}
void cmdLoadTestHtml1_Clicked(object sender, EventArgs e)
{
LoadTestHtml("Button clicked");
}
void LoadTestHtml(string pstrSomeInnerContentToDisplay)
{
webView1.Source = new HtmlWebViewSource
{
Html = #"<html>
<head>
<meta name='viewport' content='width=device-width; height=device-height; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;'/>
</head>
<body height='100%'>"
+ pstrSomeInnerContentToDisplay
+ #"</body>
</html>"
};
}

iOS Safari zooms into webpage from landscape to portrait

My problem is for my webpage designed for iOS. When testing on iPhone 5 (Safari) it loads fine in portrait mode then flips fine to landscape mode. But when going back to Portrait from Landscape it zooms in. I don't have this issue with iOS Chrome thought.
I've tried lots of different meta tags like :
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" >
But they seem to only cover the opposite issue of going from portrait to landscape zooming.
Some help would be greatly appreciated. I've spend many hours searching without success.
Here's a link if you wish to try it on a mobile device: http://www.blueberry-studio.co.uk/Robomoco_Websites/Device_iPhone_5/
and here's the code used:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge" />
<meta name="viewport" content="user-scalable=no, width=1280" />
<meta name="apple-mobile-web-app-capable" content="yes"/>
<style type="text/css">
#media screen and (orientation:portrait)
{
#robomocomobileportrait_hype_container {
display: block;
}
#robomocomobilelandscape_hype_container{
display: none;
}
}
#media screen and (orientation:landscape)
{
#robomocomobileportrait_hype_container {
display: none;
}
#robomocomobilelandscape_hype_container {
display: block;
}
}
</style>
<div id="robomocomobileportrait_hype_container" style="position:relative;overflow:hidden;width:1280px;height:2260px;">
<script type="text/javascript" charset="utf-8" src="Robomoco_mobile_portrait.hyperesources/robomocomobileportrait_hype_generated_script.js?71837"></script>
</div>
<div id="robomocomobilelandscape_hype_container" style="position:relative;overflow:hidden;width:1280px;height:720px;">
<script type="text/javascript" charset="utf-8" src="Robomoco_mobile_landscape.hyperesources/robomocomobilelandscape_hype_generated_script.js?17049"></script>
</div>
I've found a way that resolves my problem:
var alsoenlarge = true;
$(function(){
if(isScalePossible()){
$('body').css({overflow:'hidden'}); //geen scrollbars
$('#scalecontainer').css({position: 'absolute', margin: 0}); //centreren met de hand na resize
// Run scale function on start
scaleSite();
scaleSite();
// run scale function on browser resize
$(window).resize(scaleSite);
}
});
function scaleSite()
{
windoww = $(window).width();
sitew = $('#scalecontainer').width();
f = windoww/sitew;
if(!alsoenlarge && f>1) f = 1;
$('#scalecontainer').css({
"-moz-transform" : "scale("+f+")",
"-webkit-transform" : "scale("+f+")",
"-ms-transform" : "scale("+f+")",
"-o-transform" : "scale("+f+")",
"transform" : "scale("+f+")",
"left" : ((windoww-(sitew*f))/2)+"px"
});
}
function isScalePossible()
{
can = 'MozTransform' in document.body.style;
if(!can) can = 'webkitTransform' in document.body.style;
if(!can) can = 'msTransform' in document.body.style;
if(!can) can = 'OTransform' in document.body.style;
if(!can) can = 'transform' in document.body.style;
if(!can) can = 'Transform' in document.body.style;
return can;
}
And my content in this div:
<div id="scalecontainer"> </div>

Trigger.io topbar jQuery Mobile iOS bug

I have a problem that the text inside the content-div is scrollable. Happens on iOS 6 with iPhone 4 and only if native title is set.
Video: http://www.youtube.com/watch?v=8ARaDQzBqOM
Demo:
<!DOCTYPE html>
<html>
<head>
<script>
forge.topbar.setTitle('Test App', function() {
forge.logging.log("Topbar image set");
}, function(e) {
forge.logging.log("Topbar image error: " + e);
});
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Single page template</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="content">
<p>this text is scrollable</p>
</div>
</div>
</body>
</html>
You might want to try to reset all the margins, paddings and border for all elements using CSS. Add this right before the closing </head>:
<style type="text/css">
* { /* reset */
margin: 0;
padding: 0;
border: 0;
}
</style>

Hide Safari address bar and footer

On my jQuery Mobile project I'm using the following code:
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1">
I'm getting the Safari browser address bar and nav footer. How can I hide those so I can just have my app showing?
You can setup a few meta tags to tell iOS that your site can be added to the Home Screen as a web app. Once launched from there, all of the Safari elements are hidden.
Check out the section titled "Hiding Safari User Interface Components" here.
You can specify start up splash screen images and custom icons for the app as it appears on the home screen.
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-icon" href="apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="72x72" href="apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="apple-touch-icon-114x114.png" />
<link rel="apple-touch-startup-image" href="apple-touch-startup-image-320x460.png" />
<link rel="apple-touch-startup-image" sizes="768x1004" href="apple-touch-startup-image-768x1004.png" />
You should not need a <meta> tag. jQuery mobile should take care of hiding the address bar on iOS. Never been able to get the nav footer disappear myself.
Rob,
try adding below script. This should do the trick of opening new request in the same window
<script type="text/javascript">
window.onload = function () {
var a = document.getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
if (a[i].className.match("noeffect")) {
// Does nothing
}
else {
a[i].onclick = function () {
window.location = this.getAttribute("href");
return false;
};
}
}
};
</script>

Resources