iOS Question Getting distance of Textfields from the top of screen

doodooronron

Member
Licensed User
In order to move the selected textfield up and out of the way of the keypad, I need to extract its distance from the top of the screen.

I've adapted the following code found elsewhere in the forum, but it seems to return the distance (V.top) to the top of the sub-panel containing the textfield instead of the top of the main panel (pnl_Main.Top).
Is there a way to get distances referred to the top of the screen, or at least to the top of the main "mother" panel containing all the graphic elements?

B4X:
Sub Page2_KeyboardStateChanged (Height As Float)
    If Height = 0 Then
        pnl_Main.Top = 20
    Else
        For Each V As View In pnl_Main.GetAllViewsRecursive
            If IsFirstResponder(V) Then
                Log(V.Top)               
            End If
        Next
    End If
End Sub
 

Semen Matusovskiy

Well-Known Member
Licensed User
Try following instead of v.Top:
B4X:
    Dim no As NativeObject = v    
    Dim l As List = no.ArrayFromPoint (no.RunMethod ("convertPoint:toView:", Array (no.MakePoint (0, 0), Null)))

l.Get (1) is an offset for Y, l.Get (0) - for X.
For example, you want to convert a point (10, 20) in textField coordinates. Screen coordinates will be (10 + l.Get (0), 20 + l.Get (1))
 
Upvote 0

doodooronron

Member
Licensed User
Try following instead of v.Top:
B4X:
    Dim no As NativeObject = v   
    Dim l As List = no.ArrayFromPoint (no.RunMethod ("convertPoint:toView:", Array (no.MakePoint (0, 0), Null)))

l.Get (1) is an offset for Y, l.Get (0) - for X.
For example, you want to convert a point (10, 20) in textField coordinates. Screen coordinates will be (10 + l.Get (0), 20 + l.Get (1))

Excellent solution Semen, thank you.

This is the implementation that works well for me (my main panel starts 20 pixels below the top of usable screen)
B4X:
Sub Page2_KeyboardStateChanged (Height As Float)
    If Height = 0 Then
        pnl_Main.Top = 20
    Else
        For Each V As View In pnl_Main.GetAllViewsRecursive
            If IsFirstResponder(V) Then
                Dim no As NativeObject = v
                Dim l As List = no.ArrayFromPoint (no.RunMethod ("convertPoint:toView:", Array (no.MakePoint (0, 0), Null)))
                Log(l.Get (1))
                pnl_Main.Top =Min(0,0 - (l.Get (1) - pnl_Main.Height - 20 + Height + V.Height))
            End If           
        Next
    End If
End Sub

Sub IsFirstResponder(V As NativeObject) As Boolean
    Return V.RunMethod("isFirstResponder",Null).AsBoolean
End Sub
 
Upvote 0
Top