iOS Question Button click does not trigger click event in B4i

jai

Active Member
Licensed User
Longtime User
Hi,

I am in the process of porting a large B4A app over to B4i. All was going well and functioning until I converted a code module that adds a panel with buttons on the lower half of the screen. This panel and the buttons are created programmatically based on options the user picked earlier. A click on any of the buttons on this panel is captured and processed in the Main module.

The code module creates the panel and buttons just fine. But a click on buttons does not fire the button click event.

As a glimpse for this problem, this code module is called from main module by-
TempAlpha=MenuPanel.Show(mp,Page1,Hint,"OK","Cancel")

The Sub called starts in the code module with-
Sub Show(mp As cMenuPanel, Page1 As Page, Hint As String, Positive As String, Cancel As String) As String

Buttons in this sub are initialized individually after each has been defined in Dim statements such as-
mp.Initialize
mp.btn0.Initialize("cMenuPanelBtn",btn0.STYLE_SYSTEM)
mp.btn1.Initialize("cMenuPanelBtn",btn1.STYLE_SYSTEM)
mp.btn2.Initialize("cMenuPanelBtn",btn2.STYLE_SYSTEM)


The button event should be captured in the main module by sub-
Sub cMenuPanelBtn_click

End Sub

But no event is fired upon clicking any button. I have used debugging points and log statements and don’t see any even happening at the button click.

What could be missing? Appreciate any help in resolving it.

Please note that I don’t have the liberty of posting the project on the forum. Thank you.
 

ilan

Expert
Licensed User
Longtime User
this works for me:

B4X:
'Code module
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #PlistExtra:<key>NSLocationWhenInUseUsageDescription</key>
    #PlistExtra:<key>NSLocationUsageDescription</key>
#End Region

#CertificateFile: ios_development.cer
#ProvisionFile: Ilan_Development.mobileprovision

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
  
    Dim btn1,btn2,btn3 As Button

End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
  
    btn1.Initialize("btn",btn1.STYLE_SYSTEM)
    btn2.Initialize("btn",btn2.STYLE_SYSTEM)
    btn3.Initialize("btn",btn3.STYLE_SYSTEM)
  
    btn1.Tag = "Button1"
    btn2.Tag = "Button2"
    btn3.Tag = "Button3"
  
    btn1.Text = btn1.Tag
    btn2.Text = btn2.Tag
    btn3.Text = btn3.Tag
  
End Sub

Sub btn_Click

    Dim b As Button = Sender
    Log(b.Tag)

End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)

    Page1.RootPanel.AddView(btn1,0,0,50,50)
    Page1.RootPanel.AddView(btn2,0,75,50,50)
    Page1.RootPanel.AddView(btn3,0,150,50,50)
   
End Sub

Private Sub Application_Background
   
End Sub
 
Upvote 0

jai

Active Member
Licensed User
Longtime User
this works for me:

B4X:
'Code module
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #PlistExtra:<key>NSLocationWhenInUseUsageDescription</key>
    #PlistExtra:<key>NSLocationUsageDescription</key>
#End Region

#CertificateFile: ios_development.cer
#ProvisionFile: Ilan_Development.mobileprovision

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
 
    Dim btn1,btn2,btn3 As Button

End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
 
    btn1.Initialize("btn",btn1.STYLE_SYSTEM)
    btn2.Initialize("btn",btn2.STYLE_SYSTEM)
    btn3.Initialize("btn",btn3.STYLE_SYSTEM)
 
    btn1.Tag = "Button1"
    btn2.Tag = "Button2"
    btn3.Tag = "Button3"
 
    btn1.Text = btn1.Tag
    btn2.Text = btn2.Tag
    btn3.Text = btn3.Tag
 
End Sub

Sub btn_Click

    Dim b As Button = Sender
    Log(b.Tag)

End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)

    Page1.RootPanel.AddView(btn1,0,0,50,50)
    Page1.RootPanel.AddView(btn2,0,75,50,50)
    Page1.RootPanel.AddView(btn3,0,150,50,50)
  
End Sub

Private Sub Application_Background
  
End Sub

I am trying to use an array of buttons on a panel, such as-
MenuButtons = Array As Button(mp.btn0, mp.btn1, mp.btn2, mp.btn3....)

Buttons are initialized as-
mp.btn0.Initialize("cMenuPanelBtn",mp.btn0.STYLE_SYSTEM)
mp.btn1.Initialize("cMenuPanelBtn",mp.btn1.STYLE_SYSTEM)
mp.btn2.Initialize("cMenuPanelBtn",mp.btn2.STYLE_SYSTEM)
mp.btn3.Initialize("cMenuPanelBtn",mp.btn3.STYLE_SYSTEM)

In this case click on MenuButtons does not fire a button click event. It seems to work ok when using labels but not with buttons.
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
is this what u r looking for?

B4X:
'Code module
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #PlistExtra:<key>NSLocationWhenInUseUsageDescription</key>
    #PlistExtra:<key>NSLocationUsageDescription</key>
#End Region

#CertificateFile: ios_development.cer
#ProvisionFile: Ilan_Development.mobileprovision

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
   
    Dim mp As Panel
    Dim MenuButtons(4) As Button

End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
  
    mp.Initialize("mp")

End Sub

Sub btn_Click

    Dim b As Button = Sender
    Log(b.Tag)

End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)

    Page1.RootPanel.AddView(mp,0,0,Width,Height)
    mp.Color = Colors.Yellow
  
    For i = 0 To 3
        MenuButtons(i).Initialize("btn",MenuButtons(i).STYLE_SYSTEM)
        MenuButtons(i).Tag = "Button" & i
        MenuButtons(i).Text = "Button" & i
        mp.AddView(MenuButtons(i),0,i*50,100,50)
    Next
  
End Sub

Private Sub Application_Background
  
End Sub
 
Last edited:
Upvote 0

jai

Active Member
Licensed User
Longtime User
mp is a panel??

Yes,

It is defined in Main as-
Dim mp As cMenuPanel

It is called from Main as-
TempAlpha=MenuPanel.Show(mp,Page1,Hint,"OK","Cancel")

and, used in the code module as-
Sub Show(mp As cMenuPanel, Page1 As Page, Hint As String, Positive As String, Cancel As String) As String

Draws it ok but does not register click event.
 
Upvote 0

jai

Active Member
Licensed User
Longtime User
Using B4i v1.8.

The cMenuPanel name is from the B4A version.

cMenuPanel is defined in the code module in Process_Globals as-

Type cMenuPanel (cMenuPanelHeader As Label, FrontPnl As Panel, _
Title1 As Label, btn0 As Button, btn1 As Button, btn2 As Button, btn3 As Button, _
btn4 As Button, btn5 As Button, btn6 As Button, btn7 As Button, btn8 As Button, _
btn9 As Button, btn10 As Button, btn11 As Button, btn12 As Button, btn13 As Button, _
btn14 As Button, btn15 As Button, btn16 As Button, btn17 As Button, _
btn18 As Button, btn19 As Button, btn20 As Button, btn21 As Button, btn22 As Button, _
btn23 As Button, Response As Int, Result As String, _
HolderPnl As Panel, Visible As Boolean)
 
Upvote 0

jai

Active Member
Licensed User
Longtime User
The issue seems to be a combination of buttons being created programmatically AND this being done in a different code module. I verified it by moving my menu panel functionality from the code module to the main module and used Designer to create buttons that get modified and become part of an array of buttons. This worked fine.

One more thing to note, if a button InitializeCustom is used-
MenuButtons(i).InitializeCustom("MenuButtons(i)",Colors.White, Colors.White)

AFTER Initializing the button the button-
MenuButtons(i).Initialize("MenuPanelButton",MenuButtons(i).STYLE_SYSTEM)

the click event stops being triggered.

Still looking for a solution for my initial problem.
 
Upvote 0

jai

Active Member
Licensed User
Longtime User
Erel, I figured out the main problem. Button click can only be captured in the code module it is programmatically created in. This is unlike in B4A where all events are captured in the Main module. That is what I was trying to do - capture button click of a code module in the main module. Once I moved the click event capture to the corresponding code module it worked fine.

Though, please look into the InitializeCustom for buttons that are created programmatically. I was trying to use it to change the button text color but it negates the button Initialization to the point the click events stops firing. An example from my case-

mp.btn0.Initialize("cMenuPanelBtn",btn0.STYLE_SYSTEM)
mp.btn1.Initialize("cMenuPanelBtn",btn1.STYLE_SYSTEM) <---works fine; cMenuPanelBtn_click is fired
....
MenuButtons = Array As Button(mp.btn0, mp.btn1, mp.btn2, mp.btn3, mp.btn4)

works fine - all button click events are generated. But if I add the next statements-

for i=0 to 4
MenuButtons(i).InitializeCustom("MenuButtons(i)",Colors.White, Colors.White) <---changes color but stops cMenuPanelBtn_click firing
next

the button text color changes to white but they no longer generate the click event.
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
for i=0 to 4
MenuButtons(i).InitializeCustom("MenuButtons(i)",Colors.White, Colors.White) <---changes color but stops cMenuPanelBtn_click firing
next


if you want to change only the button text color why you intialize it again??
just change the color like this

B4X:
for i=0 to 4
    MenuButtons(i).TintColor = Colors.White
next
 
  • Like
Reactions: jai
Upvote 0

jai

Active Member
Licensed User
Longtime User
if you want to change only the button text color why you intialize it again??
just change the color like this

B4X:
for i=0 to 4
    MenuButtons(i).TintColor = Colors.White
next

Perfect!
Thanks ilan.
 
Upvote 0

Brian Robinson

Active Member
Licensed User
Longtime User
Hi,

I had a similar problem just now and tracked it down to the instance being released.

My views were created in a class module, and added to a panel created in main

Because I was creating these objects dynamically in a function, as soon as I left that function, they were released.

I created a list to hold the objects in Main and that stopped the problem. I was the same as you in that this was ported from B4A.

Not sure if this helps others

Cheers
Brian
 
Upvote 0
Top