In my Ionic 2 application, I have a grid component with items, that scrolls vertically.
The problem is that in Android devices with soft navigation bar (included in the screen) The scrolling stops before the entire content has revealed (see the bottom of the screen).
Example screenshot of an Android Nexus 5 (with soft bottom navigation bar):
Example screenshot of an iPhone 7 (without soft bottom navigation bar):
My question is: How can I detect the soft navigation bar's height (if existent) so that I can add it to the grid's bottom padding?
Adding to Paul's answer in case someone else is having this issue:
You can get the height of the soft navigation bar using the original answer, and then inject that as a CSS variable and use it directly in your style:
ngOnInit(){
this.platform.ready().then(() => {
this.checkSoftButton();
});
}
private checkSoftButton(){
const softButton=(screen.height - this.platform.height());
const body:any=document.querySelectorAll('body');
body.forEach((e:any)=>{
e.classList.add('soft-button');
e.style= '--ion-soft-button:' + softButton + 'px';
});
}
You can do this once in the first component and then use it in your style like
height:calc(100% - var(--ion-soft-button));
or
height:calc(100vh - var(--ion-soft-button));
You can even use the soft-button class added to the body in case you need to perform another operation inside your app if there is a soft button.
Try to use Cordova Fullscreen Plugin or add the below settings in your config file,
<preference name="Fullscreen" value="true" />
Answer:
We can use the global screen object, in order to get the dimensions of the entire screen, and the normal platform.height() to get the dimensions if the window (without the soft navigation bar's height).
Sample method:
/**
* On some Android devices there is a soft navigation bar,
* which overlaps with the screen.
* For that reason, we need to compute an extra space for
* the drawer so that the items in the last
* row are not shown "behind" the navigation bar
* #returns {number} the difference in pixels.
*/
getMarginBottomPropertyForDrawer() {
const difference = screen.height - this.platform.height();
return difference;
}
Another solution would be the following:
document.addEventListener('deviceready', () => {
var initialHeight = document.documentElement.clientHeight;
window.addEventListener('resize', resizeFunction);
function resizeFunction() {
console.log('STATUS BAR HEIGHT', document.documentElement.clientHeight - initialHeight);
window.removeEventListener('resize', resizeFunction);
}
StatusBar.overlaysWebView(true);
});
It takes about 150ms from deviceready, which you can "hide" by showing the SplashScreen a bit longer :)
Related
I would like to use some basic Javascript to automatically set the width of a div element (class name = "tb-megamenu-submenu") to be the full width of the screen and centered. I would also like this calculation to run any time the screen is resized.
Normally I would just use CSS for this (width: 100vw), but the parent element is position:relative and the submenu is position:absolute, so any attempt to set the width fails because the submenu cannot be centered on the screen with CSS alone.
I'm using a Drupal Module called "The Better Mega Menu." There is a working example of a websites that does this exact thing that I want (https://www.hollyhunt.com/), but I can't seem to replicate their success. Here's the code they are using on their site:
// Make submenu full browser width.
const submenuFullwidthCalc = function () {
// Get the Mega menu Level 1 sub menu.
$(".tb-megamenu-nav > .level-1 > .tb-megamenu-submenu").each(function () {
// reset to zero so it can be calculated again and again
$(this).css("left", 0);
const offsettarget = $("body").offset();
// The offset of this submenu.
const offsetthis = $(this)
.parent()
.offset();
// Calculate the offset.
$(this).css("left", offsettarget.left - offsetthis.left);
// Set the submenu full width.
$(this).css("width", $("body").width());
});
};
How can I get this kind of functionality working on my site? Oh, and I'm stuck using the old BootStrap 3 Theme, so any solutions may have to be compatible with older code standards. Thanks for any help you can give!!!
Does anyone know how to modify the position of the Cordova splash screen spinner? I have checked the documentation and couldn't find any information.
For android, a similar fix is in
platforms/android/src/org/apache/cordova/splashscreen/SplashScreen.java
in spinnerStart() change the Gravity value, and RelativeLayout rule.
e.g. to put spinner at the bottom:
change
centeredLayout.setGravity(Gravity.CENTER);
to
centeredLayout.setGravity(Gravity.BOTTOM);
and change
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
to
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
List RelativeLayout options: https://developer.android.com/reference/android/widget/RelativeLayout.html
List of Gravity options:
https://developer.android.com/reference/android/view/Gravity.html
Ok I figured it out, had to manually edit the iOS plugin file "CDVSplashScreen.m" found inside "/plugins/cordova-plugin-splashscreen/src/ios".
_activityView.center = CGPointMake(parentView.bounds.size.width / 2, parentView.bounds.size.height / 2 + 75);
What that does is makes the spinner 75 pixels lower from the centre of the screen. so "+75" goes towards the bottom of the screen "-75" would do the opposite.
Hope this helps someone else out there (but wasn't to hard to figure out).
Additionally if you want to change the colour of the spinner. There are 3 options to choose from (no idea how to change the colour).
gray (default - search for this line):
UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray
white
UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite;
whiteLarge
UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge
Found in the files:
/*
* The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.
*
* whiteLarge = UIActivityIndicatorViewStyleWhiteLarge
* white = UIActivityIndicatorViewStyleWhite
* gray = UIActivityIndicatorViewStyleGray
*
*/
I could fix this for Android in a different way, unfortunately the solution from Matt did not work for me.
So what i did was to use a native Padding Method for the progressbar inside the "spinnerStart" Method.
If anyone is interested in my solution, i have 75% padding from top of the Screen for both ios&android (sputn1k´s solution is also integrated).
You can Fork and further improve it for your needs when you need a different padding
https://github.com/kaya18/cordova-plugin-splashscreen/
final WindowManager win = (WindowManager)webView.getContext().getSystemService(Context.WINDOW_SERVICE);
final Display display = win.getDefaultDisplay();
final Point size = new Point();
display.getRealSize(size);
// add padding to (top) spinner
progressBar.setPadding(0, (size.y / 2), 0, 0);
centeredLayout.addView(progressBar);
Some apps (facebook, 9gag) have this functionality. When the user scrolls up the navigation bar gradually hides itself to a point where vanishes. Then when the user scrolls down the navigationBar gradually shows itself (depending on the speed of the scroll).
We tried to implement this on Titanium by adjusting the height of the nav view on the scroll event, but it is lagged and very slow:
scrollView.addEventListener('touchstart',function(e){
boolScroll=true;
});
scrollView.addEventListener('scroll',function(e){
if(boolScroll){
auxScroll=e.y;
boolScroll=false;
}
var bh=bars.height;
var sh=scrolls.height;
if(auxScroll<e.y)//scrolling down
if(bars.height>appHeight*0.08){
bars.height=bh-appHeight*0.005; //rate for hiding
if(scrolls.height<appHeight*0.7)
scrolls.height=sh+appHeight*0.005;//same rate to increase the height of the scroll
}
if(auxScroll>e.y)//scrolling up
if(bars.height<appHeight*0.08){
bars.height=bh+appHeight*0.005;
if(scrolls.height>appHeight*0.7)
scrolls.height=sh-appHeight*0.005;
}
});
We also tried doing it with translate animation on the view, but is still slow.
There is a solution for iOS on this question. Any help would be appreciated!
Don't know if you solved this problem but I did a trick that's working well for me ( at least for the navigation bar )
Here's the snippet :
self.addEventListener('scroll',function(e){
if(e.contentOffset.y > 20) NavigationWindow.window.hideNavBar();
if(e.contentOffset.y < 20) NavigationWindow.window.showNavBar();
});
NavigationWindow is an instance of Ti.UI.iOS.createNavigationWindow, self can be a tableview,view,scrollview or a window ( in my example )
this is actually a really nice feature to have. Appcelerator just tackled it and should be available on release 6.0 according to this ticket: https://jira.appcelerator.org/browse/TIMOB-23684
I'm developing an iOS app with phonegap. The UI consists of a number of 'wrappers', laid out horizontally, each at 100% of the height of the viewport.
<html>
<body>
<div id="wrapper-one"></div>
<div id="wrapper-two"></div>
<div id="wrapper-three"</div>
</body>
</body>
The html, body and #wrapper-* elements all have height: 100% declared in the CSS, which works perfectly, and stops the app from scrolling.
The problem is, that when the 'in call' or 'Personal Hotspot' indicators are visible, they reduce the height of the viewport by around 20px. This then pushes the bottom of the page slightly off screen, and you can scroll up and down. The wrapper divs within the body are scrollable, so I don't want the window to be scrollable as well.
Is there any way that I can stop the scrolling from happening when these indicators are visible, as I have for when only the normal status bar is visible?
You should be able to detect the window resize and handle it.
window.onresize = function() {
//820 just an example height
if (window.innerHeight >= 820) {
// Do something
}
}
Put this code inside your MainViewController.m right after MainViewController #implementation and before #end.
- (void)viewDidLayoutSubviews{
if ([self respondsToSelector:#selector(topLayoutGuide)]) // iOS 7 or above
{
CGFloat top = self.topLayoutGuide.length;
if(self.webView.frame.origin.y == 0){
// We only want to do this once, or if the view has somehow been "restored" by other code.
self.webView.frame = CGRectMake(self.webView.frame.origin.x, self.webView.frame.origin.y + top, self.webView.frame.size.width, self.webView.frame.size.height - top);
}
}
}
I want to create a navigation bar similar to this site's:
http://www.mysupermarket.co.uk/#/shelves/top_offers_in_asda.html
Can anyone tell me how to create that navigation bar, which follows you as you scroll the page down, but not following you at the initial loading of page?
When you access to the given website, try to scrolling down and you will understand what I am talking about. The navigation bar that consists of MY SHOP, OFFERS, IDEAS & LIFESTYLE, BAKERY and so-on...
I have really no idea what it's called. At least tell me what it's called, so I'll be able to search.
Here is the solution I've done
window.onscroll = function(){
if(getScrollTop()>140) {
document.getElementById("menu").style.position="fixed";
} else {
document.getElementById("menu").style.position="";
}
}
function getScrollTop() {
if (window.onscroll) {
// Most browsers
return window.pageYOffset;
}
var d = document.documentElement;
if (d.clientHeight) {
// IE in standards mode
return d.scrollTop;
}
// IE in quirks mode
return document.body.scrollTop;
}
Holding an element on same position can be achieved by fixed position styling.
If you want your navigation bar to stay on exact same location, position:fixed; is enough. (At least non IE6)
You can find a working example and some details here
However, if you want your navigation bar to move from it's initial location to the top border of page as you scroll the page down, you must implement some JavaScript to catch page scroll event and move the <div> accordingly.
See this question for an example on how to do that.
Note: this won't work with the Android 2.3 browser; position:fixed will not behave as expected - it kinda of temporarily attaches its position to the scrolling element before jumping back to the top.
if you want you could just set the z-index to be a specific No. and that should work.
example
z-index:100;