iOS Question iPhone X layouts

justabill

Member
Licensed User
Longtime User
I have version 4.40 which said it included support for iPhone X layouts, but my apps are still letterboxed. What do I need to update to address this so they fill the iPhone X screen?

In another app I had written in Apple’s Xcode I needed to update the target to iOS 9.3 or later and make sure the safe mode was on for the layout, but changing the #MinVersion line in my Project Attributes to #MinVersion: 9.3 wasn’t enough by itself.

I would prefer to not target iOS 11 so users with older devices can still use my app.

Any tips or tricks that anyone can suggest would be great.
 

justabill

Member
Licensed User
Longtime User
I'm using an actual iPhone X not a simulator. It doesn't look any different than any other apps that haven't been updated for iPhone X yet as it seems to be a standard letterbox by Apple for backward compatibility with non-updated apps but here's a screen shot of one of my apps installed by the b4i bridge:

Image-132.jpg

My project attributes have
#Target: iPhone, iPad
#MinVersion: 9.3

It was set to #MinVersion: 9.0 before but I tried changing it to 9.3 to see if it would make a difference (it didn't).
 
Upvote 0

justabill

Member
Licensed User
Longtime User
OK, I setup a local builder on a mac on my network where Xcode 9.1 is installed and it now runs the app without letterboxing it. I also didn't need to make any other changes to my project to make that part happen so the key (as expected I guess) is that the builder must be running a newer version of Xcode to avoid the letterbox.

However, I do think I see a problem with the Anchor constraints on an iPhone X. Anything anchored to the top or left seem fine but things anchored to the bottom when in portrait mode or to the right when in landscape mode seem to go too far and don't respect the safe boundaries the way the navigation bar and button bars do.

This picture is a screenshot of a label that is vertically anchored to the bottom on a portrait mode view and is covered by the home indicator since it didn't stop within the constraints of the so-called safe area:
Image-12343.jpg

This picture is a screenshot of a label that is horizontally anchored to the right on a landscape mode view. You can see the alignment of the buttons on the nav bar and button bar to see where I think this label should have been anchored to:

Image-4324.jpg

I could be doing something wrong or I might be misunderstanding what the bottom and right anchors are supposed to do in the designer, but right anchor works fine on portrait mode on the iPhone X when it doesn't have the unsafe area to contend with.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1. Add a global panel variable named Root.
2. Add Root to Page.RootLayout and load the layout to Root.
3. Find the safe insets in Page_Resize.

B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'Public variables can be accessed from all modules.
   Public App As Application
   Public NavControl As NavigationController
   Private Page1 As Page
   Private PieChart1 As PieChart
   Private Root As Panel
End Sub

Private Sub Application_Start (Nav As NavigationController)
   NavControl = Nav
   Page1.Initialize("Page1")
   Root.Initialize("Root")
   Page1.RootPanel.AddView(Root, 0, 0, Page1.RootPanel.Width, Page1.RootPanel.Height)
   Page1.RootPanel.Color = Colors.White
   Root.LoadLayout("1")
   NavControl.ShowPage(Page1)
End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)
   'Log($"Input: ${Width} x ${Height}"$)
   Dim top = 0, left = 0 As Int
   If App.OSVersion >= 11 Then
     Dim no As NativeObject = Page1.RootPanel
     no = no.GetField("safeAreaInsets")
     Dim matcher As Matcher = Regex.Matcher("\{(.*)\}", no.AsString.Replace(" ", ""))
     If matcher.Find Then
       Dim values() As String = Regex.Split(",", matcher.Group(1))
       Log(matcher.Group(1))
       top = top + values(0)
       left = left + values(1)
       Height = Height - values(2) - top
       Width = Width - values(3) - left
     End If
   End If
   'Log($"top: ${top}, left: ${left}, height: ${Height}, width: ${Width}"$)
   Root.SetLayoutAnimated(0, 1, left, top, Width, Height)
End Sub
 
Upvote 0

justabill

Member
Licensed User
Longtime User
The sample code you gave me shows a box that looks like the correct safe dimensions for portrait and landscape so that must mean I've done something wrong with my bottom anchored and right anchored items in the designer since they aren't in the same boundaries. I'll dig in and see if I can figure it out.

Image-1231345.jpg Image-176476.jpg
 
Upvote 0
Top