iOS Question B4i Control Substitutes for B4A

swabygw

Active Member
Licensed User
Longtime User
I've ported my application from B4A to B4i, which has gone pretty smoothly. However, I have a few questions about the differences in appearance of certain controls in iPhone. The questions are all related to appearance (not functionality), so I figured that I would ask in one thread, instead of numerous threads (let me know if separate threads are preferred and I'm happy to do so):

TabBarController (as a substitute for a TabHost)
- Can the tabs be on the top of the screen, instead of at the bottom?
- Is it possible to obtain the height (or other dimensions, such as width, top, left, etc.) of the tabs, or to change any of the dimensions?

Switch (as a substitute for a Checkbox)
- The Switch works fine as a substitute for a B4A-style CheckBox, but looks a bit awkward when there are many Switches (the CheckBox provided nicer aesthetics). Is there a better substitute for the CheckBox, that look more like a CheckBox (the solution of using 'images' of a CheckBox won't suffice)?

RadioButtons
- I saw the posting about using Switches or Pickers as a substitute. Before I go down that path, is there another recommended substitute?
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Can the tabs be on the top of the screen, instead of at the bottom?
No.
Is it possible to obtain the height (or other dimensions, such as width, top, left, etc.) of the tabs, or to change any of the dimensions?
You cannot set the height. However the page will be resized automatically based on the available size.

The Switch works fine as a substitute for a B4A-style CheckBox, but looks a bit awkward when there are many Switches (the CheckBox provided nicer aesthetics)
There is no native CheckBox in iOS.
Check this implementation: https://www.b4x.com/android/forum/threads/class-checkbox.61183/#content

RadioButtons: https://www.b4x.com/android/forum/threads/class-b4i-customviews.48877/
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Thanks for the answers and example implementations. I think I'll stick with using Switches (and using code to mimic RadioButton behavior). However, those examples helped me to solve another issue I was wrangling with.

That's also a good point about the look/feel of iOS versus Android - I might be somewhat biased since I use Android routinely.
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
I have a further question on how to use one of the custom implementation's above: I've created a CustomView and pasted in the text from the .bas file (of the custom checkbox - clsCheckBox) and I'm able to use it. This also works if I paste it into a Standard Class (I'm a bit confused about the difference, actually).

Anyhow, the custom clsCheckBox is a great example. In fact, I've added additional custom properties to it. However, when I iterate through the controls in a Page containing the custom control, for example with myPage.RootPanel.GetAllViewsRecursive, the GetType(myControl) will not equal the name of the CustomView (or Standard Class). It will, actually, find all the views within the class, such as the Panel, the Switch, and the Label. But, I want to identify the class so I can retrieve a property of the Class/View, not the internal views. Here's an example of this attempt:

B4X:
For Each v As View In myPage.RootPanel.GetAllViewsRecursive
  If v Is clsCheckBox Then 'This will never be true
    Dim c As clsCheckBox = v
    Msgbox(c.Tag,"Tag")
  End If
  If GetType(v) = "clsCheckBox" Then 'This is never true, either
    Dim c As clsCheckBox = v
    Msgbox(c.Tag,"Tag")
  End If
Next
Is there a way to do this?
 
Last edited:
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
I found a solution. Got a clue from here: https://www.b4x.com/android/forum/t...was-released-event-handling-in-classes.48790/

Essentially, within the Initialize sub in the custom class, I put "Me" in the tag of the panel, like this:
B4X:
'Initializes the object.
Public Sub Initialize(EventName As String, ParentPage As Page)
  mEventName = EventName
  CallBack = Main
  pnl.Initialize("pnl")
  ...
  pnl.Tag = Me
  ...
End Sub

Then, I can reference it by:
B4X:
Dim myCustomCheckBox As clsCheckBox = Page1a.RootPanelPanel.GetView(x).Tag
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
However, when I iterate through the controls in a Page containing the custom control...
... But, I want to identify the class so I can retrieve a property of the Class/View, not the internal views.
Why do you need to go through the controls in the Page ?

I wouldn't use the CheckBox class as it is.
I would change it into a CustomView class.
The B4i CheckBox class, you are refering to, was written before Erel added the CustomView class.
You might have a look at chapter 12.4 Custom views in the B4A User's Guide, the principle is the same for B4i.
 
Last edited:
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
Good idea - I'm reviewing it now - I think section 12.4 should clear up my confusion about when to use the Standard Class versus CustomView. The reason for the looping is that I wanted to customize the clsCheckBox to create a custom radiobutton which will belong to a group and act like a group of radiobutton's. I accomplished it (or pretty close) with the attached script. Maybe it will be useful for someone else to update and improve upon.

P.S., I should have mentioned that the crucial parts are a new property called GroupName, the Tag property of the containing Panel holds a copy of the instance, and the very last Sub, which looks like this (there are some other, minor mods throughout):

B4X:
Private Sub ApplyRadioButtonFunctionality
Dim currRadioButton As customRadioButton = Me

'Unnecessary for parent containers of few elements
'This would involve keeping a List on Main called RadioButtonGroups
' For a = 0 To Main.RadioButtonGroups.Size - 1
'   Dim crg As RadioButtonGroup = Main.RadioButtonGroups.Get(a)
'   If crg.GroupName = currRadioButton.GroupName And crg.CustomRadioButton <> currRadioButton Then
'   crg.CustomRadioButton.Checked = False
'  End If
' Next

Dim pnlPar As Panel = currRadioButton.View.Parent
For Each v As View In pnlPar.GetAllViewsRecursive
  If v.Tag Is customRadioButton Then
    Dim rb As customRadioButton = v.Tag
    If rb.GroupName = currRadioButton.GroupName And rb <> currRadioButton Then
      rb.Checked = False
    End If
  End If
Next
End Sub
 

Attachments

  • customRadioButton.txt
    10.3 KB · Views: 320
Last edited:
Upvote 0
Top