Search code examples
iosiphonecordovaionic-frameworkios13

Ionic Cordova - iOS 12 and 13 pushing footer buttons beyond safe area


I have an app written in Ionic v1, Cordova, and AngularJS 1.5.3.

The problem that I have does not occur on Android devices at all.

iPhones tested on: iPhone SE, iPhone 8, iPhone X, and iPhone XR.

For iOS 13.6 the problem occurs on: iPhone SE, iPhone 8, iPhone X, and iPhone XR.
iPhone X, and iPhone XR ( completely pushes the buttons out of view )

For iOS 12 the problem occurs on:

iPhone XR - somewhat occurs
iPhone 8 - does not occur
iPhone SE - does not occur
iPhone X - somewhat occurs

For iOS 11:
it does not occur on iPhone 8. There are no problems.
iPhone SE - no problems
It somewhat occurs on the iPhone X.
iPhone XR does not run iOS 11.

As the version of iOS increases, it seems to have more of an effect.

What my code is doing:

My page is for the user to enter an absence and they have the option of adding photo attachments. The attachment is just going to be added as an ion-item in my ion-list.

I have an ionic view and a footer with a button in it. When I add an ionic item to my ionic list, it seems to push the footer button down out of the "safe area" and it does so permanently.

Even if I go to a different page and come back again the problem persists. It also seems to permanently affect the "safe area" on the different pages of my app.

Problem: As the attachment list grows, it pushes the footer button down out of the safe area

How can I keep my button in my footer in place on the latest versions of iOS?

enter image description here

Code snippet:

<ion-view left-buttons="leftButtons" cache-view="false" right-buttons="rightButtons">

    <ion-nav-buttons side="right">
        <button menu-toggle="right" class="button button-icon icon ion-home" ui-sref="main.home"
            automation-id="RIGHT_NAV_HOME_BUTTON">
        </button>
    </ion-nav-buttons>

    <ion-content class="has-header has-footer bg-stable" padding="false">

        <ion-list can-swipe="true">

            <div class="item title-bar">
                <h2 class="dark" ng-i18next="BOOK_ABSENCE"></h2>
            </div>

            <div class="item item-icon-left" ng-click="setDate('startDate')">
                <i class="icon ion-ios-calendar-outline"></i>
                <span ng-i18next="START_DATE"></span>
                <span class="item-note">{{ data.startDate | dateFormat }}</span>
            </div>

            <div class="item item-icon-left" ng-click="setDate('endDate')">
                <i class="icon ion-ios-calendar"></i>
                <span ng-i18next="END_DATE"></span>
                <span class="item-note">{{ data.endDate | dateFormat }}</span>
                <i class="icon ion-ios-arrow-right"></i>
            </div>

            <div class="item item-divider"></div>

            <label class="item item-input">
                <textarea placeholder="Comments" ng-model="data.comments" rows="4"></textarea>
            </label>

            <div class="item item-divider"></div>

            <ion-item class="flex-container-center" ng-repeat="attachment in attachments">
                <div class="flex-item-1">
                    <img ng-src="data:{{ attachment.mediaTypeField }};base64,{{ attachment.imageDataField }}">
                </div>
                <div class="flex-item-big">
                    <div>{{ attachment.filename }}</div>
                </div>
            </ion-item>

        </ion-list>

    </ion-content>

    <div class="bar bar-footer no-padding bg-bottom">
        <div class="button-bar">
            <button class="button button-positive" ng-click="book()">
                <span ng-i18next="SAVE"></span>
            </button>
        </div>
    </div>

</ion-view>

Environment:

ionic info

Ionic:

   ionic (Ionic CLI) : 4.10.3 (C:\Users\User\node_modules\ionic)
   Ionic Framework   : ionic1 1.3.5
   @ionic/v1-toolkit : 1.0.22

Cordova:

   cordova (Cordova CLI) : 8.1.2 ([email protected])
   Cordova Platforms     : android 8.1.0, ios 6.1.0, browser 5.0.4, windows 4.4.3
   Cordova Plugins       : cordova-plugin-ionic-webview 4.1.3, (and 17 other plugins)

System:

   Android SDK Tools : 26.1.1 (C:\Users\User\Documents\Android\sdk)
   NodeJS            : v10.21.0 (C:\Program Files\nodejs\node.exe)
   npm               : 6.14.4
   OS                : Windows 10

In the past, the new iPhone X came out and I added some code to make adjustments for the "safe area".

css

body {
    padding: constant(safe-area-inset-top) constant(safe-area-inset-right) constant(safe-area-inset-bottom) constant(safe-area-inset-left); //iOS 11.2
    padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

html

<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

As I'm using cordova-ios 6.1.0 I'm using WkWebView only.

<platform name="ios">
    <preference name="WKWebViewOnly" value="true" />

Solution

  • It turns out that the env() calculation is only reliable when the app first loads. When we open the camera widget, we are technically leaving the application and when we come back the env() is evaluated again and it's giving a value that we don't want.

    To solve this problem I set the top padding to be zero.

    body {
        padding: 0 constant(safe-area-inset-right) constant(safe-area-inset-bottom) constant(safe-area-inset-left); //iOS 11.2
        padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    }
    

    We already have viewport cover in the HTML so we are good when it comes to the safe area.