iOS Question [B4XPages] KeyboardStateChanged Event for the wrong page

Alexander Stolte

Expert
Licensed User
If i have 2 Pages and on the second page is the keyboard open and i go to the first page back, then the KeyboardStateChanged event is firing, but on the first page, not on the second page where the keyboard is open.

I dont think this is the right behavior.

On "b4xp_notes" the keyboard is open on the "mainpage" not.
B4X:
Application_Start
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
Application_Active
Writing analzed variants.
*** mainpage: B4XPage_Disappear [mainpage, b4xp_notes]
*** b4xp_notes: B4XPage_Appear [mainpage, b4xp_notes]
*** b4xp_notes: B4XPage_Resize [mainpage, b4xp_notes]
Writing analzed variants.
*** b4xp_notes: B4XPage_KeyboardStateChanged [mainpage, b4xp_notes]
*** b4xp_notes: B4XPage_KeyboardStateChanged [mainpage, b4xp_notes]
*** b4xp_notes: B4XPage_Disappear [mainpage, b4xp_notes]
*** mainpage: B4XPage_Appear [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_Disappear [mainpage]
*** b4xp_notes: B4XPage_Appear [b4xp_notes]
*** b4xp_notes: B4XPage_Disappear [b4xp_notes]
*** mainpage: B4XPage_Appear [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_Disappear [mainpage]
*** b4xp_notes: B4XPage_Appear [b4xp_notes]
Application_Inactive
Application_Background
*** b4xp_notes: B4XPage_Disappear [b4xp_notes]
Can't end BackgroundTask: no background task exists with identifier 1027 (0x403), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.

I have a bug because of this, my list on the 1st page is calculated with the keyboard height, although no keyboard is open on the page.
 

Alexander Stolte

Expert
Licensed User
This only happens when I cancel the swipe gesture to get to the previous page and then swipe again to go to the previous page. Then the "B4XPage_KeyboardStateChanged" is triggered on the "mainpage" with the height of the keyboard, although no keyboard is open.
 
Upvote 0

Johan Hormaza

Well-Known Member
Licensed User
Maybe there is a TextField that I am focusing it on
You put this in Main
Objective-C:
#if OBJC
@end
@interface B4IViewController (KeyboardWillHide)
@end
@implementation B4IViewController (KeyboardWillHide)
- (void) addWillHide {
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardWillHideNotification object:nil];
}
#end if
 
Upvote 0

Alexander Stolte

Expert
Licensed User
Please upload a small project that demonstrates the issue.
Project is in the attachment.
  1. Start the App
  2. Press the top button to go to the second page
  3. On the bottom is a TextField -> open the keyboard
  4. swipe to the half of the screen to go back, swipe back
  5. repeat it and you see the listview on the first page has an keyboard gap
Video:
ezgif.com-gif-maker.gif


In my real project I have to look at the keyboard on the 1st page, because there are situations where I show the user a textfield.
 

Attachments

  • KeyboardStatechanged.zip
    7 KB · Views: 25
Upvote 0

Erel

B4X founder
Staff member
Licensed User
I see what you are talking about, however overall the behavior is reasonable. The event will be raised again with height = 0 after the second page has completely disappeared.

It happens during the transition because the main page becomes the "top page" immediately after you start sliding.

A possible solution is to disable the sliding gesture while the keyboard is visible:
1. Main module:
B4X:
Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Private recognizer As NativeObject
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Dim PagesManager As B4XPagesManager
    PagesManager.Initialize(NavControl)
    
    NavControl.NavigationBarVisible = False
    
    recognizer = recognizer.Initialize("NavGestureRecognizer").RunMethod("new", Null)
    NavControl.As(NativeObject).GetField("interactivePopGestureRecognizer").SetField("delegate", recognizer)
    SetSlideGestureState(True)
    
End Sub

Public Sub SetSlideGestureState (Enabled As Boolean)
    recognizer.SetField("enabled", Enabled)
End Sub

#if OBJC
@end
@interface NavGestureRecognizer : NSObject<UIGestureRecognizerDelegate>
@end
@implementation NavGestureRecognizer {
    BOOL enabled;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return enabled;
}
#End If

2. Add to B4XPage_KeyboardStateChanged:
B4X:
Main.SetSlideGestureState(Height = 0)
 
Upvote 0

Alexander Stolte

Expert
Licensed User
A possible solution is to disable the sliding gesture while the keyboard is visible:
1. Main module:
B4X:
Sub Process_Globals
Public App As Application
Public NavControl As NavigationController
Private recognizer As NativeObject
End Sub

Private Sub Application_Start (Nav As NavigationController)
NavControl = Nav
Dim PagesManager As B4XPagesManager
PagesManager.Initialize(NavControl)

NavControl.NavigationBarVisible = False

recognizer = recognizer.Initialize("NavGestureRecognizer").RunMethod("new", Null)
NavControl.As(NativeObject).GetField("interactivePopGestureRecognizer").SetField("delegate", recognizer)
SetSlideGestureState(True)

End Sub

Public Sub SetSlideGestureState (Enabled As Boolean)
recognizer.SetField("enabled", Enabled)
End Sub

#if OBJC
@end
@interface NavGestureRecognizer : NSObject<UIGestureRecognizerDelegate>
@end
@implementation NavGestureRecognizer {
BOOL enabled;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return enabled;
}
#End If
2. Add to B4XPage_KeyboardStateChanged:
B4X:
Main.SetSlideGestureState(Height = 0)
Thanks for the solution, but that disables with me, the 2nd time the swipe gesture and I no longer come back
 

Attachments

  • KeyboardStatechanged.zip
    7.1 KB · Views: 21
Upvote 0

Alexander Stolte

Expert
Licensed User
You need to put it in the second page. This way the gesture will be disabled until the keyboard is hidden.
Thank ypu very mutch, but unfortunately this is not a workaround for me, because I don't know how to tell the user to close the keyboard first, before he can leave the page.

This is the following log as soon as I release the finger:
B4X:
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_KeyboardStateChanged [mainpage]
*** mainpage: B4XPage_Disappear [mainpage]
*** b4xp_notes: B4XPage_Appear [b4xp_notes]
The KeyBoardStateChanged event should be triggered after the "Appear" event or i tell the B4XPage that it is not on the mainpage anymore so it can be triggered on the right page...

the main page becomes the "top page" immediately after you start sliding.
and why doesn't my current page "immediately" become the "top page" again as soon as I release the finger?
 
Upvote 0

Alexander Stolte

Expert
Licensed User
I wanted to look at Instagram now, they close the keyboard as soon as the "Disappear" event is triggered, that I wanted to do now, but does not work.
B4X:
Private Sub B4XPage_Disappear
    B4XPages.GetNativeParent(Me).ResignFocus
End Sub
I made a new thread about this:
 
Upvote 0
Top