Author Topic: how to know when UILabel/UIPanel size/position is updated?  (Read 3796 times)

tr4np

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 17
    • View Profile
I have a panel inside a scroll view.  I have a method that changes the panel size based on the panel's children (variable-length text fields), then changes the scroll view size to match (+2 pixels, to account for the border), and then positions the panel at the top of the scroll view.

The problem is that the scroll view's size isn't updated as soon as I change the panel's size.  However, if I set a timer (e.g. half a second), then the same code works the second time it is run.  I'm guessing that the panel's children's sizes aren't updated immediately after setting their text contents.

Here's some sample code:
  1. label.text="something";
  2. Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(label.transform);
  3. panel.width = (int)(label.transform.localPosition.x + bounds.max.x) + 15;
  4.  
  5. // debug output shows the label bounds is still the old value
  6.  
  7. Vector3 calPos = panel.transform.position;
  8. calPos.x = calibrationScrollView.finalClipRegion.x - calibrationScrollView.finalClipRegion.z / 2 + 1;
  9. calPos.y = calibrationScrollView.finalClipRegion.y + calibrationScrollView.finalClipRegion.w / 2 - 1;
  10.  
  11. panel.transform.localPosition = calPos;
  12. calibrationScrollView.rightAnchor.Set(0, panel.width + 2);
  13.  

So my question is whether I can force the label to update its size before getting its new bounds.  Again, if I run this same code again about half a second later, then it moves the panel in the expected location.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: how to know when UILabel/UIPanel size/position is updated?
« Reply #1 on: May 27, 2014, 12:03:37 AM »
You can force it by calling UpdateAnchors() if it's anchored. If nothing else, you can always just wait until the end of the frame (start a coroutine, yield WaitForEndOfFrame), then do your clip reposition logic.

tr4np

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 17
    • View Profile
Re: how to know when UILabel/UIPanel size/position is updated?
« Reply #2 on: May 27, 2014, 12:23:21 AM »
Thanks for the quick reply!  Unfortunately, using UpdateAnchors() didn't work.  Using a co-routine to wait until the end of the frame gives me the correct size for the labels, but the scroll view clip region still isn't updated by that time.

I have more info now, though.  I was enabling the scroll view before running this code.  I found that if the scroll view is already enabled before that re-positioning code runs, then it works fine (I don't even need to wait until end of frame).  If the scroll view is disabled (and enabled via the code on the same frame), I get that positioning error.

I use this to enable to scroll view:
  1. NGUITools.SetActive(calibrationScrollView.gameObject, true);

So there's something that delays the size/position update when the scroll view is enabled.  Any ideas?

tr4np

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 17
    • View Profile
Re: how to know when UILabel/UIPanel size/position is updated?
« Reply #3 on: May 27, 2014, 10:29:30 AM »
One more piece of info...

Even when the panel is already enabled, the panel size is still sometimes calculated incorrectly due to the label.  I was able to get it working 100% with this:

  1. label.text="something";
  2. label.MarkAsChanged();
  3. label.UpdateAnchors();
  4.  
  5. Bounds bounds = NGUIMath.CalculateRelativeWidgetBounds(label.transform);
  6. // bounds is now always correct
  7.  

If either MarkAsChanged() or UpdateAnchors() is missing, the label size is not updated immediately.  Is this a bug, or just something we need to be aware of (I don't see any mention of this in the docs)?

Despite this fix, the label is still not positioned correctly if the panel is disabled initially (and re-enabled just before the positioning code).  The size is correct, but the position is not (the label is anchored to another label, and I called MarkAsChanged() and UpdateAnchors() on that label first).

[edit] Oops, I used the wrong term.  Everywhere I wrote "panel", I meant "UI Widget".  Sorry about that.  I named each of my widgets with "panel", since I use them as floating windows on my UI.
« Last Edit: May 27, 2014, 01:43:02 PM by tr4np »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: how to know when UILabel/UIPanel size/position is updated?
« Reply #4 on: May 28, 2014, 07:46:42 AM »
You can remove the need for MarkAsChanged() if you just modify the UILabel's 'text' property to this:
  1.         public string text
  2.         {
  3.                 get
  4.                 {
  5.                         return mText;
  6.                 }
  7.                 set
  8.                 {
  9.                         if (mText == value) return;
  10.  
  11.                         if (string.IsNullOrEmpty(value))
  12.                         {
  13.                                 if (!string.IsNullOrEmpty(mText))
  14.                                 {
  15.                                         mText = "";
  16.                                         MarkAsChanged();
  17.                                         ProcessAndRequest();
  18.                                 }
  19.                         }
  20.                         else if (mText != value)
  21.                         {
  22.                                 mText = value;
  23.                                 MarkAsChanged();
  24.                                 ProcessAndRequest();
  25.                         }
  26.  
  27.                         if (autoResizeBoxCollider) ResizeCollider();
  28.                 }
  29.         }

tr4np

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 17
    • View Profile
Re: how to know when UILabel/UIPanel size/position is updated?
« Reply #5 on: May 28, 2014, 10:40:45 AM »
You can remove the need for MarkAsChanged() if you just modify the UILabel's 'text' property to this:

Thanks for the info.  Is this going into a future version of NGUI?  I'd rather not make changes to the NGUI source, since I tend to copy & paste code among different projects.  I just know I would forget to make the change to the NGUI source in another project and run into the issue again.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: how to know when UILabel/UIPanel size/position is updated?
« Reply #6 on: May 29, 2014, 06:01:30 AM »
Yup, I almost always make the changes locally when I post the code.