iOS: How to stop screen layout distortion because of Keyboard? - javascript

I want to stop the Keyboard from distorting/resizing my layout in my phonegap application. I have used the following native android code to disable and enable resize in the application using a Cordova Plugin:
this.cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
context.getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
});
However I have no idea how to do the same in iOS(6 & 7). Can anyone provide a snippet that I can use? Or point me in the right direction?

This functionality is available in the Cordova Keyboard plugin. You can then either add a preference to the main Cordova config.xml...
<preference name="KeyboardShrinksView" value="false" />
...or call the corresponding method on the created global Keyboard object:
window.Keyboard.shrinkView(false);

Related

How to detect cordova iOS WebView navigation events

As per cordova iOS WebView Guide you can embed web views in iOS.
According to that you can do
<content src="http://apache.org" />
with the definition of
CDVViewController* viewController = [CDVViewController new];
I am wondering if there is a way to detect if that content source navigated to another site by clicking the link and if there is way how to get the new URL ?
CDVViewController is the one referenced but I can't tell by inspecting as to how one would accomplish that.
A slight parallel to that is Microsoft's x-ms-webview which at DOM level allows me to do this:-
var webView = document.getElementByTag("x-ms-webview");
webView.addEventListener("MSWebViewNavigationCompleted", function (arg) {
if (arg.uri.match(/something)) {
doSomething();
}
});
Another example in iOS but just for loading initial page.
How do detect navigations inside WebView in Cordova iOS ?
Cordova post CDVPageDidLoadNotification when the page is loaded.
You can listen for it with
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(pageDidLoad:) name:CDVPageDidLoadNotification object:self.webView];

Resizing the Cordova WebView in iOS

I'm having problems resizing the Cordova (4.0.1) webview frame while trying to build a Native Hybrid application. I am relatively new to iOS development and really new to Cordova/PhoneGap.
I have followed all instructions on this page, http://docs.phonegap.com/develop/1-embed-webview/ios/, using the CocoaPods approach with the sample phone gap project. I have searched and tried other methods that are syntactically different, but essentially the same.
I've created a custom view controller class "GolfViewController" that extends the CDVViewController class provided by Cordova. This code for GolfViewController.swift is below:
import UIKit
class GolfViewController: CDVViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
self.view.backgroundColor = UIColor.blueColor()
self.webView.frame = CGRectMake(self.view.bounds.origin.x,
self.view.bounds.origin.y + 50,
self.view.bounds.size.width,
self.view.bounds.size.height - 100)
super.viewWillAppear(animated);
}
}
The content in the webview should load with some space at the top and bottom of the screen. Which it actually does, for a split second, then something in the cordova javascript forces the webview to full screen. If I comment out the wkwebview cordova plugin in cordova-plugins.js, the webview renders properly with the space at the top and bottom, but then of course none of the controls work.
Any help would be greatly appreciated as all documented approaches I've tried, have failed.
************* SOLVED *************
There is a cordova plugin called "cordova-plugin-statusbar", that when initialized resizes the webview frame to take full screen. This only happens when you have
<preference name="StatusBarOverlaysWebView" value="true" />
defined in the config.xml for the webview.
It does not simply "overlay the status bar" as you might expect from the documentation. Setting this parameter to true actually completely resizes the webview to go full screen and will override any other custom sizes you may have defined before this event fires.
If you either remove the plugin (not really needed for native hybrid apps anyway) or you disable the "StatusBarOverlaysWebView" preference, then the status bar plugin will not resize your webview and the size you define in "viewWillAppear" will be respected and not overridden. This should be updated within the official phone gap documentation on embedding the web view.

PhoneGap Build: how to open external url in device browser on Android?

External URL's don't open in the system's browser in my PhoneGap Android application. I'm using PhoneGap Build 2.3.0.
According to the Cordova documentation I used target '_system':
window.open('http://www.myurl.nl', '_system');
In my config.xml I have:
<plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />
<access origin="*" browserOnly="true" />
But still the links open in my apps webview.
How to solve this?
It's not the answer when you want to keep using PhoneGap Build, but I solved the problem by setting up a development environment for Cordova (PhoneGap) on my machine and compiling the app locally. In Cordova 2.5.0 window.open('http://www.myurl.nl', '_system'); works perfect, it will open the link in the system's browser.
So my advice is to stop using PhoneGap Build and start compiling your app locally. Here's how to set up your development environment for Cordova >>
Late answer,but may be it can help someone.
navigator.app.loadUrl('https://google.com/', { openExternal:true });
Cordova 3.3.1
This question is now a little old, but I felt it was worth updating. This now works fine with PhoneGap Build when used with 2.9.0.
I have compiled and tested it on Android 4.3 and iOS 6.1.3. I do not have the InAppBrowser plugin in my app as that's to open pages in the app, rather than cause the native browser to open them, and I only have the following for the access tags:
<access origin="http://127.0.0.1*"/>
<access origin="http://phonegap.com" subdomains="true" />
This worked for me. Phonegap 3.1.0.
html code:
<a id="ext-link" href="#">Google it</a>
or
<button id="ext-link" href="#">Google it</button>
Javascript (with jQuery+cordova):
$("#ext-link").on("click"), function() {
if (typeof navigator !== "undefined" && navigator.app) {
// Mobile device.
navigator.app.loadUrl('http://www.google.com/', {openExternal: true});
} else {
// Possible web browser
window.open("http://www.google.com/", "_blank");
}
});
Hope that helps.
#George Siggouroglou: It's not a good idea to use an id for elements that eventually will appear more than one time in a document. Instead, its good practice to make the code more modular.
if expecting touch devices its also a good choice to use "tap" before "click" because it fires much faster and earlier than a click. to check touch capable stuff I prefer to use modernizr because it makes feature detection a breeze.
The jQuery Mobile tap event triggers after a quick, complete touch event that occurs on a single target object. It is the gesture equivalent of a standard click event that is triggered by the release state of the touch gesture.
https://api.jquerymobile.com/tap/
hope that helps someone
**html code:**
<a class="ext-link" href="#">Google it</a>
or
<button class="ext-link" href="#">Google it</button>
Javascript (with jQuery):
//define tap or click event type on root level (can be combined with modernizr)
iaEvent = "click";
if (typeof navigator !== "undefined" && navigator.app) {
iaEvent = "tap";
}
$('.ext-link').each.bind(iaEvent, function() {
if (typeof navigator !== "undefined" && navigator.app) {
// Mobile device.
var linktarget = this.attr("href");
navigator.app.loadUrl(linktarget, {openExternal: true});
} else {
// Possible web browser
window.open(linktarget, "_blank");
}
});
Use this
window.open('http://www.myurl.nl', '_blank', 'location=yes');

Prevent scrolling on keyboard display iOS 6

I am running into a strange issue. I am currently producing a mobile web app using HTML5 and CSS3 for iOS 6 only.
However, when an input element receives focus and the soft keyboard is displayed, the window is scrolled so that the input is not obscured by the keyboard (even though it won't be in any instance).
I have read on SO and via Google that one can add the following to prevent this behaviour (when viewing this inside a UIWebView):
input.onfocus = function () {
window.scrollTo(0, 0);
document.body.scrollTop = 0;
}
However, it seems that in iOS 6, even though the window is initially scrolled to 0,0, it is then once again scrolled to centre the focused element. Has anyone else come across this and do they know of a fix for iOS 6?
I hit this issue too. The following works on iOS 6:
<input onfocus="this.style.webkitTransform = 'translate3d(0px,-10000px,0)'; webkitRequestAnimationFrame(function() { this.style.webkitTransform = ''; }.bind(this))"/>
Basically, since Safari decides whether or not to scroll the page based on the textbox's vertical position, you can trick it by momentarily moving the element above the top of the screen then back again after the focus event has completed.
The drawback is that the element vanishes for a fraction of a second. If you want to work around that, you could dynamically insert a clone of the original element at the original location and then remove it in the webkitRequestAnimationFrame callback.
Could it be a timing issue?
Try wrapping it up in a timeout to ensure that it's firing after the native events are firing.
input.onfocus = function () {
setTimeout(function() {
window.scrollTo(0, 0);
document.body.scrollTop = 0;
}, 50)
}
Update:
While the accepted solution worked with UIWebView, the newer faster WKWebView has since arrived. And if you are using the latest version of Cordova for iOS you can enable WKWebView for iOS 9 devices, but by default the view will still scroll up. To fix this just add the Keyboard plugin (no CSS hacks needed anymore):
Add Cordova plugins within Terminal:
cordova platform add ios#4
cordova plugin add cordova-plugin-wkwebview-engine --save
cordova plugin add cordova-plugin-keyboard --save
Set iOS preference to use WKWebView in Cordova's config.xml
<platform name="ios">
<feature name="CDVWKWebViewEngine">
<param name="ios-package" value="CDVWKWebViewEngine" />
</feature>
<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
</platform>
Then insert iOS keyboard preferences in Cordova's config.xml
<preference name="KeyboardShrinksView" value="true" />
<preference name="DisallowOverscroll" value="true" />
More detail on iOS preferences are listed on Cordova docs:
https://cordova.apache.org/docs/en/5.4.0/guide/platforms/ios/config.html
Set the input's font-size style to be 1em or higher.
<input type=text style="font-size:1.2em">

Phonegap Android "navigator.notification.activitystart()" in tablets

In my Android application, I am using Phonegap's navigator.notification.activitystart() event to show the Activity indicator. It is working fine in Android phones and tablets, but the problem is when I touch the screen of the tablet, the loader disappears even if the loading is not finished.
How can I prevent the disappearance of loading indicator when I touch on the screen using javascript/jquery?
Not sure you could change that implementation using javascript alone. The way PhoneGap works is that it will create an object ProgressDialog in the native Android code. I think the issue is that it is setting the ProgressDialog to cancelable in its constructor. If you go into the cordova source code you could change that and it should create a fix for your specific issue.
Source code from Notification.java lines 250-255 change the second true to false
Notification.this.spinnerDialog = ProgressDialog.show(cordova.getActivity(), title, message, true, true/*change this to false*/,
new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
Notification.this.spinnerDialog = null;
}
});
}

Categories

Resources