Author Topic: UIScrollView  (Read 127021 times)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
UIScrollView
« on: November 23, 2013, 08:49:55 AM »
Overview

A clipped UIPanel is not complete unless it can be dragged around like a scroll view, right? Right!



Turning a panel into a Scroll View is a short 3-step process.
  • First, select the panel you want to be your scroll view and right-click anywhere in the Scene View to bring up the context menu, then choose Attach -> Scroll View.
  • Now that you have a scroll view, choose its rectangle by dragging the purple handles just like you would choose the widget's rectangle.
  • The last step is to add the UIDragScrollView script to at least one collider. Again, select the collider, right click in the scene view, Attach -> Drag Scroll View (it will be on top if you've followed the previous steps).



Note that if you have more than one collider, then you will need to add Drag Scroll View script to all of them that the user will be able to press on. So for example if you have a scroll view like in the Scroll View Example where you have a background area and a bunch of items inside it, then you will want to add the UIDragScrollView to the background as well as each of the children. The idea behind it is simple: every collider that can intercept the event should be capable of dragging the scroll view.

Note that the context menu-based approach is context-sensitive. So if you right-click on a widget that doesn't have a collider, you won't be able to see the drag scroll view option.



On the scroll view script you have several options for you to tweak. First comes the Content Origin that's used to specify where the scroll view's content will originate.

Next comes the Movement that lets you choose whether you are making a Horizontal or a Vertical draggable panel. You can also choose Unrestricted movement which will let you drag the content around freely. If you want some custom movement, you can set the field to Custom and set your own X and Y values.

The Drag Effect option controls how the scroll view behaves when you drag it around. MomentumAndSpring is the default iOS-like behaviour.

If you want the scroll view to be scrollable with the mouse scroll wheel, play with the Scroll Wheel Factor value. Note that you can specify a negative value such as -0.25 if you want the mouse wheel scrolling to be inverted.

Momentum Amount controls how the scroll view behaves when the user lets go of the drag mid-swing (swiping gesture). Tweak this value to make it more or less sensitive based on what you desire.

In most cases you will want to have Restrict Within Panel option left turned on, as this is what will prevent your scroll view's content from leaving the scroll view's region. In case you haven't guessed it already, the dimensions of the scroll view's content should already be outlined by the orange color in the scene view.

Cancel Drag If Fits option will prevent the content from leaving the bounds at all. If left off, it will be possible to drag the content outside the bounds, but there will be visible resistance in doing so.

Smooth Drag Start and IOS Drag Emulation options further tweak the behaviour of the scroll view script, and in most cases you will just leave them at default values.

If you have a Horizontal or a Vertical Scroll Bar, you can specify them in the appropriate fields. Once done, you can also choose what happens to the scroll bars when they are not needed by adjusting the Show Scroll Bars option.

Limitation

In NGUI 3.5.5 and earlier versions, a scroll view will only clip the widgets directly underneath it. If you nest scroll views, the clipping will not be nested. Only one scroll view can clip the content inside of it. NGUI 3.5.6 lifts this limitation, provided you stick to using an NGUI's shader on your atlas such as Unlit - Transparent Colored.

Pro-Tip #1

It's best to leave the Scroll Bars Show Condition at OnlyIfNeeded so that your scroll bars will get automatically hidden until they are actually needed.

Pro-Tip #2

If you want to create an Endless Scroll View, attach a UIWrapContent script underneath it like so:



Class Documentation

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

If you have a question regarding this component or would like me to clarify something, just post a reply here.
« Last Edit: February 12, 2016, 08:51:53 PM by ArenMook »

vexe

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 153
    • View Profile
Re: UIScrollView
« Reply #1 on: November 23, 2013, 12:00:59 PM »
I can't believe my eyes, you really made a nice doc following my suggestion! You are the best developer ever! Thanks.

About the scroll view - I've always found it a bit inconvenient to have it scroll by left/right clicking and dragging. What if I only wanted it to drag when I hold right click and drag? and not left click? I would have to modify the code - which is not very nice since my changes will get overwritten in the next update.

Another thing, is that if one would specify unrestricted movement and scroll with the mouse - it would scroll diagonally! which is very odd, as a user I would expect that scrolling with the mouse, will only scroll vertically - While holding the middle mouse button and moving the mouse left/right would scroll horizontally.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIScrollView
« Reply #2 on: November 23, 2013, 12:39:02 PM »
Unrestricted movement scroll with the mouse is only horizontal for me in 3.0.6. As for the mouse button other than left... you only need to create a custom UIDragScrollView script. Nothing else needs to change.

PaulGregory

  • Guest
Re: UIScrollView
« Reply #3 on: November 26, 2013, 05:39:56 AM »
As discussed elsewhere, the context menu does not work for me and at least one other person (the only common denominator currently identified being that we're both on Mac).

So "Attach > Scroll View" is thus unavailable to me. Can you please confirm if adding the component Scroll View to the panel in the inspector (click Add Component, start typing scroll, pick Scroll View) completes step 1 or if the menu option sets anything else up?

Similarly for step 3, is it sufficient to (on the collider) click Add Component, start typing scroll, pick Drag Scroll View or is there something extra that would need to be done?

Shortcuts are great, but it's good to have what they actually do documented in case the shortcut can't be used (or indeed, for checking that everything is already set up correctly).

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIScrollView
« Reply #4 on: November 26, 2013, 06:26:14 AM »
That has been fixed. Just grab the latest (f3). :)

Wumpee

  • Jr. Member
  • **
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: UIScrollView
« Reply #5 on: December 03, 2013, 08:55:06 PM »
Is UIDragScrollView supposed to be in 3.0.6f7?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIScrollView
« Reply #6 on: December 03, 2013, 09:02:19 PM »
Yes, it's there. Make sure you're following NGUI's upgrade instructions that involve deleting the NGUI folder.

Wumpee

  • Jr. Member
  • **
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 53
    • View Profile
Re: UIScrollView
« Reply #7 on: December 03, 2013, 10:35:29 PM »
Thanks. I didn't perform the NGUI update, but I'll follow up on that now.

honeal

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 6
    • View Profile
Re: UIScrollView
« Reply #8 on: January 08, 2014, 08:26:52 PM »
Maybe something wonky has occurred with my import, but it seems creating the scroll view via the toolbar does not include the UIScroll View script automatically. Creating it via the context menu does. Just an FYI.

Oakshiro

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 16
    • View Profile
Re: UIScrollView
« Reply #9 on: January 10, 2014, 07:40:41 AM »
Is there any easy way to make the UIScrollView go "page by page"?

I am trying to put a "next page" button, and everything goes ok until i reach the extens of the scroll, am I going ok doing this?


  1.         Vector3 targetPosition = scrollView.transform.localPosition;
  2.                 targetPosition.x += moveBy;
  3.  
  4.                 if (targetPosition.x < -scrollView.bounds.extents.x)
  5.                 {
  6.                         targetPosition.x = -scrollView.bounds.extents.x;
  7.                 }
  8.  
  9.                 SpringPanel.Begin (scrollView.gameObject, targetPosition, 13f);

THANKS!


It is NGUI 3, btw

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIScrollView
« Reply #10 on: January 10, 2014, 09:18:59 AM »
UICenterOnChild can be used to center on pages, and has an option to flick to go to the next page (the threshold, in pixels).

Oakshiro

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 16
    • View Profile
Re: UIScrollView
« Reply #11 on: January 10, 2014, 10:42:16 AM »
Hmmm, I can't see how UICenterOnChild could work for that... It just centers my first grid element on the center of the screen, and I only can change its spring strength...

What I intend to do is to have one button on each side of the scrollview and move one page left or right when I click on them, but keeping the content inside the bounds.


EDIT:
Ok, i see there is a CenterOn(Transform t) to center it on an object. The problem is my pages have 6 elements, so I should center it between two elements...
« Last Edit: January 10, 2014, 10:58:34 AM by Oakshiro »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: UIScrollView
« Reply #12 on: January 10, 2014, 06:20:10 PM »
Have a look at how it works in the Scroll View (Panel) example. UICenterOnChild centers on the child object whos transform's position is the closest to the center of the scroll view.

If you wanted to center in-between of elements, you would structure your content like so:

Center On Child
- Child 1
-- Element 1
-- Element 2
-- Element 3
-- Element 4
-- Element 5
-- Element 6
- Child 2
-- Element 1
-- Element 2
-- Element 3
-- Element 4
-- Element 5
-- Element 6
...etc

Center On Child will center on your "Child 1", "Child 2", etc, rather than "Element X"

Oakshiro

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 16
    • View Profile
Re: UIScrollView
« Reply #13 on: January 10, 2014, 06:45:35 PM »
That could have worked indeed, but in the end I created my own PageScrollView class, based on UICenterOnChild. It might not be the best code in the world, but hey, it works!
Thanks for your help :)

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// Attach this script to the container that has the objects to allow paging
  6. /// </summary>
  7.  
  8. public class PageScrollView : MonoBehaviour {
  9.  
  10.         public float springStrength = 8.0f;
  11.  
  12.         private UIScrollView scrollView;
  13.         private int elementsPerPage;
  14.         private int currentScrolledElements;
  15.         private Vector3 startingScrollPosition;
  16.  
  17.         private UIGrid grid;
  18.  
  19.         // Use this for initialization
  20.         void Start ()
  21.         {
  22.                 if (scrollView == null)
  23.                 {
  24.                         scrollView = NGUITools.FindInParents<UIScrollView>(gameObject);
  25.                         if (scrollView == null)
  26.                         {
  27.                                 Debug.LogWarning(GetType() + " requires " + typeof(UIScrollView) + " object in order to work", this);
  28.                                 enabled = false;
  29.                                 return;
  30.                         }
  31.  
  32.                         grid = this.GetComponent<UIGrid>();
  33.                         elementsPerPage = (int) (scrollView.panel.clipRange.z / grid.cellWidth);
  34.                         currentScrolledElements = 0;
  35.                         startingScrollPosition = scrollView.panel.cachedTransform.localPosition;
  36.                 }      
  37.         }
  38.        
  39.         // Update is called once per frame
  40.         void Update () {
  41.        
  42.         }
  43.        
  44.  
  45.         /// <summary>
  46.         /// Scrolls until target position matches target panelAnchorPosition (may be the center of the panel, one of its sides, etc)
  47.         /// </summary> 
  48.         void MoveBy (Vector3 target)
  49.         {
  50.                 if (scrollView != null && scrollView.panel != null)
  51.                 {
  52.                         // Spring the panel to this calculated position
  53.                         SpringPanel.Begin(scrollView.panel.cachedGameObject, startingScrollPosition - target, springStrength);
  54.                 }
  55.         }
  56.  
  57.  
  58.         public void NextPage()
  59.         {
  60.                 if (scrollView != null && scrollView.panel != null)
  61.                 {
  62.                         currentScrolledElements += elementsPerPage;
  63.                         if (currentScrolledElements > (this.transform.childCount - elementsPerPage))
  64.                         {
  65.                                 currentScrolledElements = (this.transform.childCount - elementsPerPage);
  66.                         }
  67.                         float nextScroll = grid.cellWidth * currentScrolledElements;
  68.                         Vector3 target = new Vector3(nextScroll, 0.0f, 0.0f);                          
  69.                         MoveBy(target);
  70.                 }
  71.         }
  72.  
  73.         public void PreviousPage()
  74.         {
  75.                 if (scrollView != null && scrollView.panel != null)
  76.                 {
  77.                         currentScrolledElements -= elementsPerPage;
  78.                         if (currentScrolledElements < 0)
  79.                         {
  80.                                 currentScrolledElements = 0;
  81.                         }
  82.                         float nextScroll = grid.cellWidth * currentScrolledElements;
  83.                         Vector3 target = new Vector3(nextScroll, 0.0f, 0.0f);                          
  84.                         MoveBy(target);
  85.                 }
  86.         }
  87.  
  88. }
  89.  

nerophon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: UIScrollView
« Reply #14 on: January 16, 2014, 12:46:39 PM »
Hi,

We love the CenterOnChild behavior and are using it to tween our scrollView. Sadly, however, if a user taps / clicks during the tween, the tween is canceled (or overridden?) and the scrollView stops where it is. It does not even snap back to the nearest child.

How can we prevent this behavior? We want the scrollView to NOT stop tweening due to a user press, but a user swipe should still override it with a new tween in the new swipe direction.

Many thanks!

Nick