Author Topic: UIToggle  (Read 88179 times)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
UIToggle
« on: November 20, 2013, 11:19:04 PM »
Overview

A toggle is a generic component that has two states: on, and off. Toggle can be used to create checkboxes, tabs, radio button groups, and other similar widgets.



Toggle is a perfect example of a small to-the-point component that can be used to do a lot of things. Like most NGUI controls, the look of it is not hard-coded for you like it is in other systems. Instead, it's used in combination with other scripts to achieve the desired behaviour.

By itself, the toggle is simply capable of fading in and fading out the targeted object. Generally this "object" is a checkmark, a highlighted sprite, or some other indicator of an active state.

To create a basic checkbox, create a pair of sprites -- a background, and a foreground (make it a child of the background to make it simple). For the background choose something that looks like a button. For the foreground choose something that looks like a checkmark.

Attach the UIToggle script to the parent (the background), and reference the foreground in the UIToggle's Sprite parameter. That's it, you now have a checkbox.

You can turn it into a Radio Button by specifying a Group ID other than zero. Just set up your checkbox how you want it to be, give it a group ID, and duplicate your checkbox game object a couple of times (CTRL+D with it selected).

You can create an Animation to make your checkmark transition smoother, or just attach an Animation component to your Checkmark and reference the provided "Checkmark" animation clip. Reference this clip in the Animation field on your Toggle, and you will have an even better looking transition.

If you want your toggle to start active, check the Starting State checkbox.

Pro-Tip

You can create a tab using a Toggle by creating two sprites, one on top of the other. First create a dark sprite, then add a child to it and make it brighter. Attach a Toggle component to the dark sprite's object and reference the lighter sprite as the Toggle's Sprite. Give this tab a Group then duplicate it a few times to create a group of tabs.

Use together with the UIToggledObjects script to set up easy enabling and disabling of child panels, thus creating a multi-tabbed window.

Class Documentation

http://tasharen.com/ngui/docs/class_u_i_toggle.html

If you have a question regarding this component or would like me to clarify something, just post a reply here.

stacktrace

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: UIToggle
« Reply #1 on: December 22, 2013, 08:03:33 PM »
I have a popup window with a set of 6 Grouped UIToggle controls.  I want the currently selected UIToggle to be the first on the list everytime the window is opened, rather than the last control that was selected when the window was last closed.

I am currently using the following code snippet when the window is opened:

  1. _selectToggles[0].value = true;
  2.  
  3. for (_indx = 1; _indx < _selectToggles.Count; _indx++)
  4. {
  5.        _selectToggles[_indx].value = false;
  6. }
  7.  

Where _selectToggles is a List<UIToggle> of all the controls in the group. 

However, when the window is reopened, it shows the Sprite specified as the State Transition sprite (of the UIToggle script) visible for both the first item and the last item that was selected when the window was last closed.  (I do not have an Animation attached)

Is there a way to reset the UIToggle state to its start state, or somehow force it to hide its attached "on" sprite?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIToggle
« Reply #2 on: December 23, 2013, 01:57:07 PM »
Unfortunately I don't understand your explanation. What list? Some custom list? Why do you need the currently selected toggle to be first? What does selection have to do with it? Do you mean currently active toggle (value == true)?

Selection is not given to some specific component unless you do it yourself. In the controller menu example it's done via the UIButtonKeys script (UIButtonKeys.selectOnClick) and has nothing to do with toggles.

stacktrace

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: UIToggle
« Reply #3 on: December 23, 2013, 02:34:20 PM »
Sorry that I was not clear, looks like I interchanged "list" for "toggle group".  Let me try again.

I have a group of UIToggle components each attached to a separate UIWidget.  There is also a separate UISprite which is set as the "State Transition Sprite" property of a UIToggle.  These are arranged from top to bottom on a window with a UILabel with a description that overlaps the UIWidget areas, but is not parented to them.  The UISprite mentioned above is just a little bullet, so that whichever UIWidge the player clicks on, the bullet sprite appears next to the label, showing which item is currently selected.

I believe this is a relatively simple and standard setup, and it works just fine (just to be totally clear, all of the UIToggle components have the same Group ID set).

Here is the issue.

What happens by default, is that each time the window is shown, the bullet appears next to the last item clicked on.  The window is not recreated each time, just being hidden and made visible.  I understand this behavior and totally expect it.  But I want to change it.

The behavior I want, is that each time the window is shown, I want the bullet to appear next to the top label.  As I understand it, because the bullet sprite is set as the "State Transition Sprite" of a UIToggle component, its visibility is controlled by that UIToggle's value property.


My code logic was to call a custom function each time the window was opened that looped through all the UIToggle components in the toggle group, and set their value property to "false" except for the top most UIToggle, which would be set to "true".  I thought that this would give the desired result of only showing the Bullet sprite associated with the top most UIToggle only.

What is happening however is that when the window is opened for a second time, two bullet sprites are visible, the one associated with the top UIToggle (as desired) and the one which was visible when the window was closed the last time (unexpected).  (Note: by "top" I mean Y position on the screen as the UIWidgets the UIToggles are attached to are arranged vertically).


What I hope to find out:

- Should my logic work (and I have a problem elsewhere, perhaps with the notify handler used by the UIToggles in the group)?
- And if not, can you suggest an alternate solution/workaround?


Hopefully this is clearer, and not muddled up worse. 

I thank you for your time and help.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIToggle
« Reply #4 on: December 23, 2013, 03:27:29 PM »
Depending on when you perform this action, the toggles may not be in the UIToggle.list yet. They get added in UIToggle.OnEnable, and removed in UIToggle.OnDisable. If you change the value of one, and other toggles are not yet in the list, then it won't be able to turn off the values of others properly.

Since you're setting the value of a group of toggles, you don't need to loop through them and set them to 'false'. Setting one of them to 'true' automatically sets others to 'false', provided the toggles have executed their OnEnable function already.

So long story short -- modify the script execution order to have your script run after the UIToggle.

stacktrace

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: UIToggle
« Reply #5 on: December 23, 2013, 03:40:15 PM »
Excellent, thank you for the quick reply!

shuihuyunyun

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: UIToggle
« Reply #6 on: January 07, 2014, 09:49:08 PM »
How can I use "UIToggledComponents" to receive the second C# script component in a GameObject?
So far, I can only drag the gameobject to the activate's or deactivate's Elements, only the first script of the gameobject could be loaded.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIToggle
« Reply #7 on: January 08, 2014, 01:58:57 PM »
You can have more than one Inspector window open. You can also lock one inspector (use the lock icon on the top right), so that selecting objects won't clear it. Using this, you can drag & drop a component from one inspector window into a field of another inspector window. Not exactly an NGUI question. :)

shuihuyunyun

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: UIToggle
« Reply #8 on: January 08, 2014, 07:23:09 PM »
oh,sorry. It is not my question exactly.
I mean, how can I drag the "WindowAutoYaw" script(in the first picture) to Element1 of the "UIToggledComponents" component(picture 2)?

You see, only drag & drop do not work correctly, because I want Element1 to be "Lagposition(WindowAutoYaw)", not "Lagpositon(Lagposition)".

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIToggle
« Reply #9 on: January 08, 2014, 10:12:22 PM »
Yup, and my reply explains exactly that. Instead of drag & dropping the game object from the hierarchy window, you will be drag & dropping the actual script from one inspector window to another.

shuihuyunyun

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: UIToggle
« Reply #10 on: January 08, 2014, 10:18:13 PM »
aha, Thanks a lot.

PanCotzky

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: UIToggle
« Reply #11 on: January 10, 2014, 09:24:18 PM »
I'm trying to set my UIToggle a OnValueChanged receiver:



But I can't see a way to specify an event receiver method. When I check my UIToggle nothing happens. Trying to debug the reason for this, I've discovered that UIToggle just treats my receiver object as invalid EventDelegate and doesn't run it. Does this function even work? Or I should set all my callback up in the code? Could you please give me some hints on how to use this function (I mean, how to assign the callback receivers in the inspector)?
« Last Edit: January 11, 2014, 11:56:35 AM by PanCotzky »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIToggle
« Reply #12 on: January 11, 2014, 06:38:36 PM »
Without seeing your function declaration, how can I answer that question? ;)

It needs to be of public void FuncName () type. No parameters, void return, and must be 'public'.

UIToggle.current tells you which toggle triggered this delegate while inside the delegate callback.

lilyac

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: UIToggle
« Reply #13 on: January 17, 2014, 10:41:08 AM »
Hi Aren,

I seem to be having some issues with an unexpected behaviour with the UI Toggle's notify behaviour. It seems that the function specified in notify is called not only on change, but it is in fact also called once on start up/initialization, before any changes are made. Is there anyway to disable this behaviour or fix this issue ?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: UIToggle
« Reply #14 on: January 18, 2014, 10:31:58 PM »
It's intentional for it to be called on start. It's done for consistency, to ensure that callbacks are in the proper state and match the toggle.