iOS Question iCustomDialog position behaviour

Mike1970

Well-Known Member
Licensed User
Longtime User
Erel, first of all thank you so much for the beautiness of your tools. A really impressive work. By the way, I'm facing a problem with the iCustomDialog's library.
In one of your posts, using the following code, it do the job:
B4X:
    Public Sub MoveCustomDialog(cd As CustomLayoutDialog, Top As Int)
        Dim no As NativeObject = cd
        Dim v As View = no.GetField("alertView").GetField("view")
        Do While v.Top = 0
            Sleep(5)
        Loop
        v.Top = Top
    End Sub

This run fine over a iPhone 5/5S with iOS version 10.3.2
Using the above code on iPhone 6 iOS version 11.4 the dialog still remain in the center of the screen.
Stepping throught using the debbuger, I've seen that a breackpoint to the "Sleep(5)" line is never reached.
Using instead this version of the code:
B4X:
    Public Sub MoveCustomDialog(cd As CustomLayoutDialog, Top As Int)
        Dim no As NativeObject = cd
        Dim v As View = no.GetField("alertView").GetField("view")
        'Do While v.Top = 0
        '    Sleep(5)
        'Loop
        v.Top = 0 'Top
    End Sub

The Dialog moves to the ZERO position on the screen.
Setting any value different from zero, to v.Top causes the iCustomDialog to set the position again in the center of the screen (202.0) in the iPhone 6 case.
Is there a bug into the iCustomDialog library or I'm missing something?
Libraries used: iCustomDialog (V1.00), iUI8 (V.1.70). Compiler set to 64 bit, otherwise no way to run it in debug mode.

Thank you for your support.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Erel, first of all thank you so much for the beautiness of your tools. A really impressive work. By the way, I'm facing a problem with the iCustomDialog's library.
Thank you. However you shouldn't limit your questions to a single member. This is a community forum.

Compiler set to 64 bit, otherwise no way to run it in debug mode.
This is expected if you are using a 64 bit device.

Can you upload a small project that demonstrates this issue?
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
Thank you. However you shouldn't limit your questions to a single member. This is a community forum.


This is expected if you are using a 64 bit device.

Can you upload a small project that demonstrates this issue?

Sure.
Please find attached a simple example.
Thank you all again.
 

Attachments

  • iCustomDialog_Test.zip
    4.2 KB · Views: 455
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You must learn about resumable subs. Your current code is incorrect. Watch the resumable subs video: https://www.b4x.com/etp.html

There is indeed a change in the way the dialog behaves. This code works on iOS 11.4. I haven't tested it on other versions:
B4X:
Public Sub MoveCustomDialog(cd As CustomLayoutDialog, Top As Int) As ResumableSub
   Dim no As NativeObject = cd
   Dim MainView As View = no.GetField("alertView").GetField("view")
   Do While MainView.Top = 0
       Sleep(5)
   Loop
   Dim ContentView As View = no.GetField("alertView").GetField("contentView")
   ContentView.Top = -MainView.Top + Top
   Return True
End Sub

Sub btnOpen_Click
   Dim p As Panel
   PrepareDialogPanel(p, Page1, "DetailsDialog1", DetailsDialog.STYLE_CUSTOM)
   Field1Description.Text = "Type something here"
   Field1.KeyboardType = Field1.TYPE_DEFAULT
   Dim sf As Object = DetailsDialog.ShowAsync("Hello", "OK", "ABORT", "", False)
   Wait For (MoveCustomDialog(DetailsDialog, 50dip)) Complete (Success As Boolean)
   Field1.RequestFocus
   Wait For (sf) Dialog_Result (Result As Int)
   If Result = DetailsDialog.RESULT_POSITIVE Then
       Label1.Text = Field1.Text
   End If
End Sub
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
You must learn about resumable subs. Your current code is incorrect. Watch the resumable subs video: https://www.b4x.com/etp.html

There is indeed a change in the way the dialog behaves. This code works on iOS 11.4. I haven't tested it on other versions:
B4X:
Public Sub MoveCustomDialog(cd As CustomLayoutDialog, Top As Int) As ResumableSub
   Dim no As NativeObject = cd
   Dim MainView As View = no.GetField("alertView").GetField("view")
   Do While MainView.Top = 0
       Sleep(5)
   Loop  
   ContentView.Top = -MainView.Top + Top
   Return True
End Sub

Sub btnOpen_Click
   Dim p As Panel
   PrepareDialogPanel(p, Page1, "DetailsDialog1", DetailsDialog.STYLE_CUSTOM)
   Field1Description.Text = "Type something here"
   Field1.KeyboardType = Field1.TYPE_DEFAULT
   Dim sf As Object = DetailsDialog.ShowAsync("Hello", "OK", "ABORT", "", False)
   Wait For (MoveCustomDialog(DetailsDialog, 50dip)) Complete (Success As Boolean)
   Field1.RequestFocus
   Wait For (sf) Dialog_Result (Result As Int)
   If Result = DetailsDialog.RESULT_POSITIVE Then
       Label1.Text = Field1.Text
   End If
End Sub

Thank you Erel.
Actually it now moves... but the Circle with the Question Mark inside the dialog have a different position now, as you can see in the included picture.
I would try to discover by myself how to get to the circle, but how one can discover what are and what name have the "views" inside an object?
What I mean is:
B4X:
Dim ContentView As View = no.GetField("alertView").GetField("contentView")
From where I can discover that exist a view named "contentView"?
Exist some Object's inspector that help in such cases?

Thank you.
 

Attachments

  • iCustomDialog_Moving.png
    iCustomDialog_Moving.png
    134.4 KB · Views: 456
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I would try to discover by myself how to get to the circle
It is difficult to do it without the library source code, which is quite complicated by itself.

Moving the circle as well:
B4X:
Public Sub MoveCustomDialog(cd As CustomLayoutDialog, Top As Int) As ResumableSub
   Dim no As NativeObject = cd
   Dim MainView As View = no.GetField("alertView").GetField("view")
   Do While MainView.Top = 0
       Sleep(5)
   Loop
   Dim ContentView As View = no.GetField("alertView").GetField("contentView")
   Dim CircleView As View = no.GetField("alertView").GetField("circleView")
   ContentView.Top = -MainView.Top + Top
   CircleView.Parent.Top = -MainView.Top + Top + CircleView.Parent.Top
   Return True
End Sub
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
What to say.... wonderful and almost perfect.
I'm saying "almost" because if I add a panel with 2 fields, then inside the first field you can still type something in it, since it is explicitly executed a RequestFocus on it.
But as soon you you tap on the second field and then loose the focus on the first field, then there is no way to put the focus back on the first field, like if there is something "transparent in front" of the first field that prevent the click on the text area.
Of course, if I don't move the dialog at all, both fields can receive focus.

The above DOES NOT happen on iOS 10.3.2, where everythings works as expected. On iPhone6 (iOS 11.4), the strange behaviour happen!

By the way, in attachment is the code to reproduce the behaviour.

I'm really sorry to bother the community with this, but probably it can help anybody that need to create a simple dialog with 2 (or more) fields, that need to be moved somewhere on the screen.

Actually, it would be perfect if the library could handle automatically the presence of the keyboard and if so, move accordingly the whole dialog to the best visible area.
Ok, I know, this last sentence if for the "WISH" section...

Thank you all.
 

Attachments

  • iCustomDialog_Test2_Fields.zip
    5.7 KB · Views: 440
Last edited:
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
There is a very simple solution to this. Use a simple panel and change its layout however you like. There is nothing special with the custom dialog.
It is exactly what I did in the second example I've posted and named "iCustomDialog_Test2_Fields.zip". I've added a panel with 2 labels and two Textbox.
In that example there is a panel with 2 fields instead of one as per the previous example.
Behaviour 1:
Not move the dialog, leaving it in the center of the screen = focus can be given tapping to the screen to both text fields.

Behaviour 2:
Let move the dialog by the code gently provided by Erel (MoveDialog function in the example), then the dialog move correctly to the top (I've choosed 40dip) BUT then while the second field can get focus tapping over it, the first field can't receive focus anymore and does not matter how many time you tap over it with your fingers.
The capability to get the focus by some elements inside the iCustomDialog seems related to the moving of the dialog in position different from the original "center screen" position...

It is confirmed that the Behaviour 1 & 2 happen on real devices iPhone 6 AND iPhone 8, iOS 11.4. (Maybe a 64bit platform make the difference? I don't know...).
It is confirmed that on iPhone 5 & 5S iOS 10+, everythings works fine as expected even moving the dialog at 40dip to the top

Hope someone have an answer for this strangeness.
Thank you all.
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
What I meant is that if iCustomDialog doesn't work as you like then don't use it. Just show a Panel over your layout.
Ah.. now I got it..
iCustomDialog are really cool and it is a real pit not to use them because of that strangess...
BTW, I'm new to B4i, and I'm guessing how to implement what Erel is saying, considering that this panel is called many times all around the application.
Avoiding to use the iCustomDialog, means design a Panel to use as Dialog. This is clear. What I'm guessing is that I would design that panel just once and then "overimpose" it on the page when needed, and capture the events etc.
That said, how to overimpose the Dialog's panel over the current page, loading it when needed?
Should I add an empty panel in each layout and then load into it the dialog content when needed?
Is there another way to do it in more efficient way?

Thanks.
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
It is better to start a new thread for new questions. The best way to do it is by implementing it in a class. This will make it simple to reuse it. You can pass the parent to the class and when done remove the added panel from the parent.
Logically speacking, I agree 100%, but I've no idea where to start from with B4X.
Where to learn how to write classes and designer-binded objects with B4X?

Thank you.
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
Sorry to "insist" in using the iCustomDialog, I've used a lot of it in my program and now trying to change it is a long job and even not sure if it will behave correctly on all iPhones...
BTW, using the example I've posted, I've discovered that if you set the dialog to open with the following settings, then there is no way to put the focus on field1 and even field2.
Moving the dialog, let the inner panel not to receive the focus on the inside objects (like if something else need to be moved togheter with the other elements in order to fully discover the panel area)...

B4X:
DetailsDialog.Style = DetailsDialog.STYLE_CUSTOM
Dim sf As Object = DetailsDialog.ShowAsync("", "OK", "CANCEL", "", False)
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
Additional info:
If I move the dialog closest to the center of the screen , then the possibilities to give the focus to both fields increase a lot.
 
Upvote 0
Top