I am trying to use the segment control and somethings are working fine. However a few comments and posssible bugs.
I have set the id=99, but in the event the id ==nil. {code follows from modified corona sample}
I would also like to be able to access the segmentcontrol table of segments, but this is returned as nil. Likewise I would like to be able to change the segment labels at run time as well as treat the segment table as a normal table determining total number of entries using #target.segments.Maybe also change the number of segments.
Ideally new and additional methods to access the table and make the required changes.
id bug follows
local function segmentedControlListener( event )
local target = event.target
print (target.id)—print nil here
statusText.text = "Segmented Control\nself.segmentNumber = " … target.segmentNumber
end
– Create a default segmented control (using widget.setTheme)
local segmentedControl = widget.newSegmentedControl {
left = 10,
top = 0,
segments = { “Corona”, “Widget”, “Demo” },
defaultSegment = 1,
id=99, – added a new id value [string I assume]
segmentWidth = 88,
onPress = segmentedControlListener
}
I did a quick test. In your listener event.id is a type “userdata” but this isn’t your segement’s id. event.target.id is not being set. But here is the quandary that I’m not willing to call a bug. event.target is about the segment that was pressed, not the whole controller. There is no .id per segment. I don’t know an easy way to get to the parent object from the listener.
As for new API’s to get / set the label. They would need to be added. This would require a feature request to be filed at http://feedback.coronalabs.com or you can get the Open Source Lua code for them and implement your own, which would be the quicker option.
String. An optional identification to assign to the segmented control. Default is widget_segmentedControl.
I have just discovered there are no setEnabled( ) methods either. I need to disable the whole segmentcontrol while showing an overlay.
Thinking more on this I have put in code to react as if disabled by checking states of the userscreen…
I will add these to feedback however if you agree ? I still feel access to the internal segment table would be really powerfull. At the moment I am re-creating the control each timeI need a label change, with no real hits in performance.
Thanks Rob for your usual fast responses , even at weekends .
As for disabling the segmented controller, if you’re using a composer.showOverlay() just set .isModal = true on it. We will create an invisible rectangle as the background of the overlay that will consume all touch and tap events which keeps things under the overlay from being interacted with.
The 2nd post about image sheets, this is if you wanted to create your own custom skin for it. We use image sheets internally for the default theme looks. You can position the widget using it’s .x and .y properties, but trying to do: segController.width = 50 is not supported. You pass those in when you create the widget as parameters. Afterwords, there is no guarantee that the techniques used to resize display objects will work on the widgets. The widgets use display objects to construct the widget, but the widget itself is not a display object.
Interesting. If you just create the segmented controller, and not go through all of this re-create when you’re processing the touch of the segment, it works just fine. This seems to be an artifact of removing the controller in the middle of handling it’s event. Again I’m not sure the use case of what you’re doing, but if you must do it this way, perhaps put the function that is recreating the segmented controller inside a timer so that the listener has a chance to complete before you remove it’s parent object.
The app is a storyboard app going from scene to scene.
To keep the same layout of the toolbar for the user on different scenes the whole screen layout is removed and recreated at each scene. So from a user’s view the toolbar is the same one, but, now I started using the segment control [re-coding from newbutton] the user will notice the scene toolbar changing now because the segments border disappears evey other click.
The scene to scene at the moment has no delay and just looks like card flipping.If I put it in a timer for the segmentControl delaying for the segmentControl the card flipping effect slows down.
A better design[now knowing this hic-up] would have had the toolbar stay and just change internal list. I dont want to recode all that at this point. It willl be quicker to fall back to a set of newbuttons. Unfortunaly I was trying to keep up with Apple’s modernisations at each release of IOS.
What are my chances of getting this accepted as a bug,or, can you give me a clue where in the https://github.com/coronalabs/framework-widget the artifact but be addressed. Is it due to pixels of the image sheet [where is that?]? Or calculation in the dividerFrame or…
Thinking more on this I cannot do anything different with my app as the segmentComponent is ‘supplied’. SoI have to fix the artifact problem, some how, or fall back.
Reasons [unless you educate me otherwise…]
Unable to change the number of segments once the control is created.
Unable to change the labels once the control is created.
To have different segments per scene with different labels I would need to create as many controls as scenes ahead of the scenes and ‘hide’ them off the display and move them in as required to avoid recreating each time [all/each controls are created in one main routine called when a scene is created]
------
I have done a mock up test case for your interest [and bug fix ;) ].
I can send it to you if you let me know how, or where and when.
The test case shows three scenes across the app, white [main.lua], yellow and blue.
White has 4 segments/tabs - 3 tabs run within the white scene, a fourth starts a new scens Yellow.
Yellow scene has only 3 tabs. 2 run within the yellow scene, a third tab starts a new scene Blue.
Blue scene has 6 tabs. 4 run within blue scene, another tab recreates scene Yellow, while another tab recreates Blue scene.
So this allows us to test the borders missing [under several sequences-not scene dependant] by using different tabs the borders disappear on blue or yellow etc depending on the sequence of the tabs clicked. Basically the tab borders dissapear every other new scene creation … very odd and unrelated I would think!
Each scene requests a new and its own control.
Each scene calls a common global scope routine in main.lua to create a new control for that scene
In the app you’re trying to build (not a test app), does the labels and number of segments change from scene to scene? Is there a reason to not use a tabBar for this?
I guess the only reason is that the tabbar looked like an overkill, with icons and, specing each tab etc, compared to the simple segmentControl. Examples I have tried make the tabbar look a bit oold IOS 5/6 with black fill.
But you are probably right in asking the question, I’ll go look and try that and see if I can customise to look like the segmentControl.
I do have my latest demo, more realistic, within storyboard as well. if you need it …shout.
I found if you recreated the segmentControl in one scene [Blue scene] at the createscene event it is ok for that scene, but if done later the same odd divider missing actions. The other scene [yellow] missed dividers if recreated in any startup event, so this may be an indication there is some cause/ link between number of segements and a timing issue.
I have sent you another test by email that shows the same as above, unless you do another change in the newly sent test Blue Scene. Recreating in CreateScene in blue blue works ok. Do the same in Yellow , it doesnt.
I recreate the segmentControl each scene to change labels and number of segments by have a global segment lis
e.g. #_G.ui.segmentedControlsegments={“label1”,“label2”, …}
This is then used at create time of segement control. After that I run the following code
–=== mock up set of dividers to over come the bug
local dloop
local lines={}
local linesGroup = display.newGroup()
for dloop =1,#_G.ui.segmentedControlsegments-1 do --get label list size from global list
–_G.ui.segmentedControlsegments is assigned to segmentcontrols segments option at segmentControl creation
local x=segmentedControl.x -
(math.floor(#_G.ui.segmentedControlsegments*0.5)*segmentWidth) +
segmentWidth*dloop --ok for my case only?
local y1=segmentedControl.y-segmentedControl.height*0.5
local y2=segmentedControl.y+segmentedControl.height*0.5
local divider=display.newLine( x,y1 ,x,y2)
divider:setStrokeColor(R,G,B,255)-- R,G,B set to color required
linesGroup:insert(divider)
lines[#lines]= divider --not sure this does what I think --i.e. addresablity to each line if required
end
group:insert(linesGroup)
--=======================
I did a quick test. In your listener event.id is a type “userdata” but this isn’t your segement’s id. event.target.id is not being set. But here is the quandary that I’m not willing to call a bug. event.target is about the segment that was pressed, not the whole controller. There is no .id per segment. I don’t know an easy way to get to the parent object from the listener.
As for new API’s to get / set the label. They would need to be added. This would require a feature request to be filed at http://feedback.coronalabs.com or you can get the Open Source Lua code for them and implement your own, which would be the quicker option.