Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: Prodigga on June 26, 2014, 02:08:47 AM

Title: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: Prodigga on June 26, 2014, 02:08:47 AM
Hey guys. I am trying to make my scroll view 'spring' back to the top of the grid of items it contains (Back to the default resting position) when the scroll view is not full. When the scroll view is not full, you can scroll the objects in the scroll view around freely and they will just hover around wherever you stop dragging them. I want it so that if the player pulls the content down/away from the top, they spring back up there (You can observe this behaviour in the ScrollView if the scroll view is full).

I am trying to create a 'pull to refresh' type feature with my scrollview so for this reason I need the content to 'spring' back up to the top even if the scrollview is not full.

Any ideas?
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: ArenMook on June 26, 2014, 11:10:09 AM
Call ResetPosition() on the scroll view, assuming you set its content origin.
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: Prodigga on June 26, 2014, 11:26:59 AM
ResetPosition just snaps it back to the top. I don't want that.

(http://i.imgur.com/0046IKF.png)
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: ArenMook on June 26, 2014, 11:37:32 AM
Have a look inside the RestrictWithinBounds function. It calculates the offset then uses SpringPanel.Begin to move the scroll view into place smoothly. In your case you'd do something similar, based on the distance from the content's top to the scroll view's top instead of CalculateConstrainOffset.
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: Prodigga on June 26, 2014, 11:57:51 AM
thanks ill have a look tomorrow at work and get back to you!
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: Prodigga on June 26, 2014, 08:56:01 PM
I got it working. For anyone with the same problem, here is what I did:

In UIPanel, replace CalculateConstrainOffset with

  1. public virtual Vector3 CalculateConstrainOffset (Vector2 min, Vector2 max, bool SnapToTopOfGrid = false)
  2.         {
  3.                 Vector4 cr = finalClipRegion;
  4.  
  5.                 float offsetX = cr.z * 0.5f;
  6.                 float offsetY = cr.w * 0.5f;
  7.  
  8.                 Vector2 minRect = new Vector2(min.x, min.y);
  9.                 Vector2 maxRect = new Vector2(max.x, max.y);
  10.  
  11.                 Vector2 minArea = new Vector2(cr.x - offsetX, cr.y - offsetY);
  12.                 Vector2 maxArea = new Vector2(cr.x + offsetX, cr.y + offsetY);
  13.                
  14.  
  15.                 if(SnapToTopOfGrid)
  16.                 {
  17.                         UIGrid ChildGrid = GetComponentInChildren<UIGrid>();
  18.                         if(ChildGrid != null)
  19.                         {
  20.                                 BetterList<Transform> childs = ChildGrid.GetChildList();
  21.                                 UIWidget lastChildWidget = childs[childs.size-1].GetComponent<UIWidget>();
  22.                                 float childHeight = lastChildWidget.CalculateBounds().extents.y;
  23.                                 float newExtentY = -cr.w;
  24.                                 newExtentY+=childHeight;
  25.                                 if(newExtentY < minRect.y)
  26.                                 {
  27.                                         minRect.y = newExtentY;
  28.                                 }
  29.                                
  30.                         }
  31.                 }
  32.  
  33.                 if (clipping == UIDrawCall.Clipping.SoftClip)
  34.                 {
  35.                         minArea.x += clipSoftness.x;
  36.                         minArea.y += clipSoftness.y;
  37.                         maxArea.x -= clipSoftness.x;
  38.                         maxArea.y -= clipSoftness.y;
  39.                 }
  40.  
  41.  
  42.                 return NGUIMath.ConstrainRect(minRect, maxRect, minArea, maxArea);
  43.         }
  44.  

then in UIScrollView, add "true" as a paramater to both the "CalculateConstrainOffset" method calls, ie:

  1. Vector3 constraint = mPanel.CalculateConstrainOffset(bounds.min, bounds.max);
  2. //becomes
  3. Vector3 constraint = mPanel.CalculateConstrainOffset(bounds.min, bounds.max, true);

Things to be aware of:

Only tested to on UIScrollView that scroll vertically and snap to the top.
Expects a UIGrid child which contains a vertical grid of items of the same height.
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: e-tip on May 06, 2015, 05:33:18 AM
Wow, that's should be part of official NGUI sources thanks
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: ArenMook on May 07, 2015, 06:20:58 PM
I would recommend you make this function a part of your own class rather than modifying NGUI. This way when you update your changes won't be lost.
Title: Re: Forcing a UIScrollView contents to "spring" to the top when not full
Post by: mucylulu on January 27, 2016, 01:02:39 AM
I got the same problem too,my solution is below:
  1. private UIScrollView scrollView;
  2.     private Vector3 startPos = Vector3.zero;
  3.     private void dragFinished()
  4.     {
  5.         if (scrollView != null)
  6.         {
  7.             if (!scrollView.shouldMoveVertically)
  8.             {
  9.  
  10.                 if (scrollView.dragEffect == UIScrollView.DragEffect.MomentumAndSpring)
  11.                 {
  12.                     // Spring back into place
  13.                     SpringPanel.Begin(scrollView.GetComponent<UIPanel>().gameObject, startPos, 13f).strength = 8f;
  14.                 }
  15.  
  16.             }
  17.         }
  18.         else
  19.         {
  20.             Debug.Log("grid or scroll view is null FUNC:dragFinished POS:PackageTypeClick.cs");
  21.         }
  22.     }
  23.  
  24.     private void dragStart()
  25.     {
  26.         scrollView = CurrentScrollView.GetComponent<UIScrollView>();
  27.         startPos = scrollView.gameObject.transform.localPosition;
  28.        
  29.     }
  30.  

 ;D ;D ;Dit's works well