namespace UIWidgets { using UnityEngine; /// /// TileView ScrollRect fitter. Resize ScrollRect to fit whole number of items. /// [RequireComponent(typeof(ListViewBase))] public class TileViewScrollRectFitter : MonoBehaviour { ListViewBase tileView; /// /// Gets the TileView. /// /// The TileView. public ListViewBase TileView { get { if (tileView == null) { tileView = GetComponent(); } return tileView; } } bool isInited; /// /// The base size delta. /// protected Vector2 BaseSizeDelta; /// /// The resize listener. /// protected ResizeListener ResizeListener; /// /// Start this instance. /// public virtual void Start() { Init(); } /// /// Init this instance. /// public virtual void Init() { if (isInited) { return; } isInited = true; var scrollRect = TileView.GetScrollRect(); if (scrollRect != null) { ResizeListener = Utilities.GetOrAddComponent(scrollRect); BaseSizeDelta = (scrollRect.transform as RectTransform).sizeDelta; ApplyFitter(); } } /// /// Add resize listener. /// protected void ResizeListenerOn() { ResizeListener.OnResizeNextFrame.AddListener(ApplyFitter); } /// /// Remove resize listener. /// protected void ResizeListenerOff() { ResizeListener.OnResizeNextFrame.RemoveListener(ApplyFitter); } /// /// Applies the fitter. /// public virtual void ApplyFitter() { ResizeListenerOff(); var spacing_x = TileView.GetItemSpacingX(); var spacing_y = TileView.GetItemSpacingY(); var scrollRect = TileView.GetScrollRect(); var scrollRectTransform = scrollRect.transform as RectTransform; var size = scrollRectTransform.rect.size; var margin = TileView.GetLayoutMargin(); size += BaseSizeDelta - scrollRectTransform.sizeDelta; size.x -= margin.x + margin.y; size.y -= margin.z + margin.w; var item_width = TileView.GetDefaultItemWidth(); var items_in_row = Mathf.Max(1, Mathf.FloorToInt((size.x + spacing_x) / (item_width + spacing_x))); var required_width = (items_in_row * (item_width + spacing_x)) - spacing_x + margin.x + margin.y; if (size.x != required_width) { scrollRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, required_width); } var item_height = TileView.GetDefaultItemHeight(); var items_in_column = Mathf.Max(1, Mathf.FloorToInt((size.y + spacing_y) / (item_height + spacing_y))); var required_height = (items_in_column * (item_height + spacing_y)) - spacing_y + margin.z; if (size.y != required_height) { scrollRectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, required_height); } ResizeListenerOn(); } /// /// This function is called when the MonoBehaviour will be destroyed. /// public virtual void OnDestroy() { if (ResizeListener != null) { ResizeListenerOff(); } } } }