需求
在每次打開界面滑動列表都是復位狀態(未滑動)。
分析
在制作滑動列表時常常會結合UIPanel和UIScrollView
要讓滑動列表回到未滑動時的位置,那么就需要改變Panel的Clipping和transform的position
演示
以前做法
以前是保存Panel的初始信息,每時打開面板時再還原
public class CUIShopVIP : CUIController { private UIPanel GridPanel; private UIScrollView GridPanel_ScrollView; private float BakGridPanel_Y; private Vector4 BakGridPanel_ClipRegion; public override void OnInit() { base.OnInit(); //...... 初始化代碼 GridPanel = GetControl<UIPanel>("GridPanel"); GridPanel_ScrollView = GridPanel.GetComponent<UIScrollView>(); BakGridPanel_Y = GridPanel.transform.GetLocalPositionY(); BakGridPanel_ClipRegion = GridPanel.baseClipRegion; } public override void OnOpen(params object[] args) { base.OnOpen(args); //打開前 重設Scrollview的屬性到初始 GridPanel.baseClipRegion = BakGridPanel_ClipRegion;//NOTE 不建議直接修改此值 GridPanel_ScrollView.UpdatePosition(); GridPanel_ScrollView.ResetPosition(); GridPanel.transform.SetLocalPositionY(BakGridPanel_Y); } }
之前的做法是 修改 Panel的 localPosition 和 Panel的 baseClipRegion,但官方不建議直接修改baseClipRegion。然后更新ScrollView的信息
/// <summary>
/// Clipping position (XY) and size (ZW).
/// Note that you should not be modifying this property at run-time to reposition the clipping. Adjust clipOffset instead.
/// </summary>
public Vector4 baseClipRegion
編寫組件
現在做了一個PanelResetHelper,修改Panel的 clipOffset和 localPosition 而不直接修改baseClipRegion
/// <summary>
/// Clipping area offset used to make it possible to move clipped panels (scroll views) efficiently.
/// Scroll views move by adjusting the clip offset by one value, and the transform position by the inverse.
/// This makes it possible to not have to rebuild the geometry, greatly improving performance.
/// </summary>
public Vector2 clipOffset
原理
和之前做法一樣,初始化時保存Panel的屬性,界面打開時,再還原值。
組件源碼
Helper代碼如下
/// <summary> /// 可以對UIPanel進行滾動復位 /// </summary> public class CUIPanelResetHelper { private UIPanel _panel; private Vector2 _initPanelClipOffset; private Vector3 _initPanelLocalPos; public CUIPanelResetHelper(UIPanel uiPanel) { _panel = uiPanel; _initPanelClipOffset = _panel.clipOffset; _initPanelLocalPos = _panel.cachedTransform.localPosition; } public void ResetScroll() { _panel.clipOffset = _initPanelClipOffset; _panel.cachedTransform.localPosition = _initPanelLocalPos; } }
組件用法
public class CUIShopVIP : CUIController { private UIPanel GridPanel; private CUIPanelResetHelper GridPanelResetHelper; public override void OnInit() { base.OnInit(); //...... 初始化代碼 GridPanel = GetControl<UIPanel>("GridPanel"); GridPanelResetHelper = new CUIPanelResetHelper(GridPanel); } public override void OnOpen(params object[] args) { base.OnOpen(args); //打開前 重設Scrollview的屬性到初始 GridPanelResetHelper.ResetScroll(); } }
UIScrollView
uiscrollview中的屬性
/// <summary> /// Whether the dragging will be restricted to be within the scroll view's bounds. /// </summary> public bool restrictWithinPanel = true; /// <summary> /// Whether dragging will be disabled if the contents fit. /// </summary> public bool disableDragIfFits = false;