Start a new topic

Problem with iPhone 9:16 ratio

Hi,

i'm developing an app with Xamarin and Wikitude. I had already opened a thread for a similar problem (https://support.wikitude.com/support/discussions/topics/5000092655) but after the last update (Wikitude 8.9.1) a strange thing happens on iPhone with 9:16 ratio:

when I open first time the app, the bottom part is moved up like this:

image



image


but I don't want this, I need to cover the bottom part. I realized that when i close and reopen the app, the bottom part was fixed:


image


image


and this happens every time I open the app for the first time (when i close the app from background). I also made a video that reproduces the problem, you can find it attached on this topic.


These are the files:


 index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <!--  basic meta information -->
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Type" content="application/json; charset=utf-8">
    <meta content="width=device-width,initial-scale=1,maximum-scale=5,user-scalable=yes,viewport-fit=cover" name="viewport">

    <title>Adeon</title>

    <script src="https://www.wikitude.com/libs/architect.js"></script>
    <script src="../ade.js"></script>

    <!-- important for static POI loading - include the static data  -->
    <script type="text/javascript" src="js/myjsondata.js"></script>

    <!-- jquery mobile CSS -->
    <link rel="stylesheet" href="jquery/jquery.mobile-1.4.5.min.css" />
    <!-- required to set background transparent & enable "click through" -->
    <link rel="stylesheet" href="css/stylesheet.css" />

    <!-- jquery JS files -->
    <script type="text/javascript" src="jquery/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="jquery/jquery.mobile-1.4.5.min.js"></script>

    <!-- marker representation-->
    <script src="js/marker.js"></script>

    <!-- World logic-->
    <script type="text/javascript" src="js/WorldLogic.js"></script>
</head>
<body>
    <div data-role="page" style="background: none;">
        <!-- MAIN PAGE CONTENT -->
        <!-- header of UI holding settings and range buttons -->
        <div role="main" class="ui-content">
            <a href="javascript: World.showRange();" class="ui-btn-left ui-btn ui-btn-inline ui-corner-all" id="trasparent-btn">
                <img src="assets/icon/range.png" alt="Range" id="range">
            </a>

            <a href="javascript: World.showSettings();" class="ui-btn-right ui-btn ui-btn-inline ui-corner-all" id="trasparent-btn">
                <img src="assets/icon/gear.png" alt="Impostazioni" id="settings">
            </a>
            <a href="javascript: World.showSettings();" class="ui-btn-right ui-btn ui-btn-inline ui-corner-all" id="trasparent-btn">
                <img src="assets/icon/help.png" alt="Aiuto" id="help">
            </a>
        </div>

        <div data-role="footer" id="footer" class="ui-bar" data-position="fixed" style="text-align:center;">
            <a href="javascript: World.showSettings();" class="ui-btn-center ui-btn ui-btn-inline ui-corner-all" id="trasparent-btn">
                <img src="assets/icon/swipe.png" alt="Swipe" id="swipe">
            </a>
        </div>

        <div class="box" id="box">
            <div class="box-inner">
                
            </div>
        </div>

        <script type="text/javascript" src="js/swipeup.js"></script>
        <script type="text/javascript">
            $('#footer').on('swipeup',function(){
                $('#box').animate({'bottom':'0'},300);
                $("#swipe").hide();} );

            $('#box').on('swipedown',function(){
                $('#box').animate({'bottom':'-200'},300);
                $("#swipe").show();} );
        </script>
    </div>
</body>
</html>

 

stylesheet.css

body{
    border: none;
    color: #333 /*{c-body-color}*/;
    text-shadow: 0 /*{c-body-shadow-x}*/ 1px /*{c-body-shadow-y}*/ 0 /*{c-body-shadow-radius}*/ #fff /*{c-body-shadow-color}*/ !important;
    background-color: none;
    background-image: none;
    background: none !important;
}

#range{
    width:40px;
    height:40px;
    border:none;
    background: none;
    margin-top: 20px;
}

#settings{
    width:40px;
    height:40px;
    margin-top: 20px;
}

#help{
    width:40px;
    height:40px;
    margin-top: 100px;
}

#swipe{
    width:50px;
    height:50px;
}

#trasparent-btn{
    box-shadow:none;
    background:none;
    background-color:none;
    border:none;
}


#header-status, #footer {
    background-color: none !important;
    background-image: none !important;
    background: none !important;
    border: 0px solid #aaa !important;
}

#footer{
    padding-bottom: 30px;
}

.box{
    position:fixed;
    bottom:-100%;
    height: 200px; 
    background-color: #190004;
    opacity: 0.85;
    width: 100%;
    display: block;
    z-index:999999;
}

.box-inner {
    position: absolute;
    width:100%;
    top: 0px;
    bottom: 0px;
    overflow: scroll;
    -webkit-overflow-scrolling: touch;
}


.ui-slider-input {
    background: lightgrey !important;
    background-color: lightgrey !important;
    background-image: none !important;
}

.ui-slider-popup {
    background: lightgrey !important;
    background-color: lightgrey !important;
    background-image: none !important;
}

/* fixes focus scrolling*/
html .ui-page-active {
    overflow: hidden !important;
}

/* fixes info button not centered */
.ui-footer-fixed {
    padding-left: 0;
}

 

ViewController.cs

 

using System;
using Foundation;
using UIKit;
using CoreGraphics;
using AVFoundation;
using WikitudeComponent.iOS;
using Adeon.iOS.CoreServices;



namespace Adeon.iOS
{
    public partial class ViewController : UIViewController
    {
        protected class ArchitectDelegate : WTArchitectViewDelegate
        {
            [Weak]
            protected ViewController arExperienceViewController;
            public ArchitectDelegate(ViewController arExperienceViewController)
            {
                this.arExperienceViewController = arExperienceViewController;
            }

            public override void DidFinishLoadNavigation(WTArchitectView architectView, WTNavigation navigation)
            {
                Console.WriteLine("Finished loading Architect World");
                arExperienceViewController.ArchitectWorldFinishedLoading(navigation);
            }

            public override void DidFailToLoadNavigation(WTArchitectView architectView, WTNavigation navigation, NSError error)
            {
                string errorMessage = error.LocalizedDescription + " ('" + navigation.OriginalURL + "')";
                UIAlertController failedToLoadArchitectWorldAlertController = UIAlertController.Create("Failed to load Architect World", errorMessage, UIAlertControllerStyle.Alert);
                failedToLoadArchitectWorldAlertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));

                arExperienceViewController.PresentViewController(failedToLoadArchitectWorldAlertController, true, null);
            }

            public override UIViewController PresentingViewControllerForViewControllerPresentationInArchitectView(WTArchitectView architectView)
            {
                return arExperienceViewController;
            }
        }

        public ViewController(IntPtr handle) : base(handle)
        {

        }

        protected class NavigationControllerDelegate : UINavigationControllerDelegate
        {
            [Weak]
            protected WTArchitectView architectView = null;

            public NavigationControllerDelegate(WTArchitectView architectView)
            {
                this.architectView = architectView;
            }

        }


        protected WTArchitectView architectView;
        protected ArchitectDelegate delegateObject;

        [Weak]
        protected ArExperience currentArExperience;
        protected WTNavigation loadedArExperienceNavigation = null;
        protected WTNavigation loadingArExperienceNavigation = null;


        protected NSObject applicationWillResignActiveObserver;
        protected NSObject applicationDidBecomeActiveObserver;

        protected bool isRunning;

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            // Perform any additional setup after loading the view, typically from a nib.

            architectView = new WTArchitectView();
            architectView.SetLicenseKey("rXxGPSn4WA2Bkg6vd1j176qXR6Y9iKULHtta8L2EFDvj8NZymFAkUWOlC8fgj6oUE59u7DLgXTAqU1we2tmkQ2drwhcaxx/FxxJacaM0462FMqDElT7a6klWFLSaf/7B20kiUmiHcriRWTS4lX3l+xN6+X/rwV+DIL+OXZsEf9hTYWx0ZWRfX0/WkNROVvDYiF7eGx0lP/XutcXlZX2otUyKY1s/Q1AxtFtrHRvEeUw11Ti+2O/qij12LF/cOdPMEL2/bKe0bbFHCVJR/lpQEvxG7o25We3l58t1ZPsDzOziNvxD4g8e5HHCILFwFXzesbOMLhc+LrdulPh6sUsrmGiJOmln7dPyHMgxWRa8rYuUR19hRihOftJ1593Pkz1j324PDUoNKYWeHt2gYzc4z3Prdy/oCO3g5hBdrFLnsRdWzfdjyVNR34b+iaCcnUckSMCQ2k7RohreNh5JEDK5DMHCD7dbUc//SS7qFbjmd8V/rworMeA4X/VuZPaJrufYUzXHZJV2xp3zjrF0qj/dO+E2mBA1kJwnZ0LE4XmDwAElabT0U3K4E2lM4UR+I3r3SNj3/6K4SVKs+wtbk5ie8TkYbfXhkWQKeug8Bn1lOsPVKGUuAxRtCni4L2HQpQ2vtbDZgdVaEAMRjPRoEmx0txT3W1FNJhkJCTUL05jM/sEn3VcCEzUxKA+snBjk9ys+D497kw/FL/qW81bHWPi6gNev8LNLxzgdvrcoCBepMko5HrGq0UyJNOg8Xz+Zyl0VtC2X/qIu+iVfd54/E2vr5A==");
            delegateObject = new ArchitectDelegate(this);
            architectView.Delegate = delegateObject;
            architectView.TranslatesAutoresizingMaskIntoConstraints = false;
            Add(architectView);

            architectView.CenterXAnchor.ConstraintEqualTo(View.CenterXAnchor).Active = true;
            architectView.CenterYAnchor.ConstraintEqualTo(View.CenterYAnchor).Active = true;
            architectView.WidthAnchor.ConstraintEqualTo(View.WidthAnchor).Active = true;
            architectView.HeightAnchor.ConstraintEqualTo(View.HeightAnchor).Active = true;

            EdgesForExtendedLayout = UIRectEdge.None;
        }

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            LoadArExperience();
            StartArchitectViewRendering();


            //UIInterfaceOrientation currentOrientation = UIApplication.SharedApplication.StatusBarOrientation;
            //architectView.SetShouldRotateToInterfaceOrientation(true, currentOrientation);

            applicationWillResignActiveObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.WillResignActiveNotification, ApplicationWillResignActive);
            applicationDidBecomeActiveObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidBecomeActiveNotification, ApplicationDidBecomeActive);
        }

        public override void ViewDidDisappear(bool animated)
        {
            base.ViewDidDisappear(animated);

            StopArchitectViewRendering();

            NSNotificationCenter.DefaultCenter.RemoveObserver(applicationWillResignActiveObserver);
            NSNotificationCenter.DefaultCenter.RemoveObserver(applicationDidBecomeActiveObserver);
        }

        public override void DidReceiveMemoryWarning()
        {
            base.DidReceiveMemoryWarning();
            // Release any cached data, images, etc that aren't in use.		
        }

        public override void ViewWillTransitionToSize(CGSize toSize, IUIViewControllerTransitionCoordinator coordinator)
        {
            if (coordinator != null)
            {
                coordinator.AnimateAlongsideTransition((IUIViewControllerTransitionCoordinatorContext context) =>
                {
                    UIInterfaceOrientation newInterfaceOrientation = UIApplication.SharedApplication.StatusBarOrientation;
                    architectView.SetShouldRotateToInterfaceOrientation(true, newInterfaceOrientation);
                }, null);
            }
            else
            {
                UIInterfaceOrientation newInterfaceOrientation = UIApplication.SharedApplication.StatusBarOrientation;
                architectView.SetShouldRotateToInterfaceOrientation(true, newInterfaceOrientation);
            }

            base.ViewWillTransitionToSize(toSize, coordinator);
        }

        public void ArchitectWorldFinishedLoading(WTNavigation navigation)
        {
            if (loadingArExperienceNavigation.Equals(navigation))
            {
                loadedArExperienceNavigation = navigation;
            }
        }

        #region Notifications
        private void ApplicationWillResignActive(NSNotification notification)
        {
            StopArchitectViewRendering();
        }

        private void ApplicationDidBecomeActive(NSNotification notification)
        {
            StartArchitectViewRendering();
        }
        #endregion

        #region Private Methods
        private void LoadArExperience()
        {
            NSUrl fullArExperienceURL = NSBundle.MainBundle.GetUrlForResource("index", "html", "Milan/");
            loadingArExperienceNavigation = architectView.LoadArchitectWorldFromURL(fullArExperienceURL);

        }

        private void StartArchitectViewRendering()
        {
            if (!architectView.IsRunning)
            {
                architectView.Start((WTArchitectStartupConfiguration architectStartupConfiguration) =>
                {
                    architectStartupConfiguration.CaptureDevicePosition = AVCaptureDevicePosition.Back;
                    architectStartupConfiguration.CaptureDeviceResolution = WTCaptureDeviceResolution.WTCaptureDeviceResolution_AUTO;
                    architectStartupConfiguration.CaptureDeviceFocusMode = AVCaptureFocusMode.ContinuousAutoFocus;
                }, (bool success, NSError error) =>
                {
                    isRunning = success;
                });
            }
        }


        private void StopArchitectViewRendering()
        {
            if (isRunning)
            {
                architectView.Stop();
            }
        }
        #endregion


    }
}


Can you help me to solve?

Thank you,

Vincenzo

mp4

Hi Vincenzo,


This seems to be an issue with the `UIScrollView` in the `WKWebView` that we use to render our content. Its default behaviour is to adjust the size of its content insets to the safe area, which is taking priority over the CSS instructions. We will change this.


I am not entirely sure why it "fixes" itself after rotating the device or sending the app to background and opening it again. Maybe the `WKWebView` has not fully processed the `viewport-fit=cover` attribute properly the first time, somehow. The size of its bounds seems fine, and just reloading the same URL doesn't make a difference. It may be a quirk in `WKWebView` itself.


Thanks for letting us know, we will address this problem in a future release. In the meantime, setting the size of the HTML elements in `vh` units instead of percentages is also working for me.



- Damian

Ok, thanks I'll wait for it to be fixed in the next release

Login or Signup to post a comment