国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

NGUI:關于ScrollView的ResetPosition 不能用于UIWrapContent

2019-11-09 14:35:24
字體:
來源:轉載
供稿:網友

之前用ScrollView的resetPosition方法來給ScrollView復位,發現復位后的坐標不是預料中的(0,0,0),并且這個值還會變化,有時候是偏差-12,有時候又偏差-7,這真是很令我困惑啊。今天打開NGUI的源碼看了下ResetPosition這塊的源碼。

public void ResetPosition() { if (NGUITools.GetActive(this)) { // Invalidate the bounds mCalculatedBounds = false; Vector2 pv = NGUIMath.GetPivotOffset(contentPivot); // First move the position back to where it would be if the scroll bars got reset to zero SetDragAmount(pv.x, 1f - pv.y, false); // Next move the clipping area back and update the scroll bars SetDragAmount(pv.x, 1f - pv.y, true); } } 看到NGUITools.GetActive(this)這句過濾了active為false的狀態,所以ResetPosition必須在activeInHierarchy為true的情況下才能生效。 然后最重要的用來計算復位坐標的主要就是 SetDragAmount(pv.x, 1f - pv.y, false);這句了。繼續跟進去看看: 代碼有點長,而且都是一些計算,著實有點難看啊。不過沒關系,不能看得明明白白,看個大概也就可以了。public virtual void SetDragAmount (float x, float y, bool updateScrollbars) { if (mPanel == null) mPanel = GetComponent<UIPanel>(); DisableSPRing(); //先取消了SpringPanel的active,防止復位后又被SpringPanel拉回來。 Bounds b = bounds; //計算了當前ScrollView的一個相對邊框尺寸,包括所有子級。 if (b.min.x == b.max.x || b.min.y == b.max.y) return;//min和max是邊框的兩個邊界坐標。 Vector4 clip = mPanel.finalClipRegion;//獲取了ScrollView最后被渲染出來的中心坐標和裁剪區域尺寸ViewSize float hx = clip.z * 0.5f; float hy = clip.w * 0.5f;//得到裁剪區域尺寸的一半 ViewSize/2 float left = b.min.x + hx; float right = b.max.x - hx; float bottom = b.min.y + hy; float top = b.max.y - hy;//各邊界坐標分別向中心點偏移了半個ViewSize if (mPanel.clipping == UIDrawCall.Clipping.SoftClip) { left -= mPanel.clipSoftness.x; right += mPanel.clipSoftness.x;//當選擇的裁剪方式為SoftClip時會有一個Softness值,這個就是軟裁剪的意思吧。 bottom -= mPanel.clipSoftness.y;//上面計算得到的各邊界再減去這個軟裁剪的值 top += mPanel.clipSoftness.y;//到此得到的坐標其實就是SV的中心坐標了,只是這個中心坐標偏移了最初的位置 } // Calculate the offset based on the scroll value float ox = Mathf.Lerp(left, right, x); float oy = Mathf.Lerp(top, bottom, y);//根據設置的pivot選取SV的中心應該是在左邊還是右邊,是在頭還是尾。 // Update the position //因為SV的可以從top開始滑,也可以從bottom開始滑。 if (!updateScrollbars) { Vector3 pos = mTrans.localPosition;//ScrollView的當前坐標 if (canMoveHorizontally) pos.x += clip.x - ox;//寫成pos.x-=ox-clip.x可能更好看點。 if (canMoveVertically) pos.y += clip.y - oy;//clip.xy是SV最后被渲染在屏幕上的中心點,而oxy則是偏移后的中心 mTrans.localPosition = pos; //兩者做差正好就是偏移量了。 這步把SV的坐標拉回起始點了。 } if (canMoveHorizontally) clip.x = ox; if (canMoveVertically) clip.y = oy; // Update the clipping offset Vector4 cr = mPanel.baseClipRegion;//這個是最初設置的SV的中心點,其實這里和finalClipRegion的值是一樣的。 mPanel.clipOffset = new Vector2(clip.x - cr.x, clip.y - cr.y);//偏移后的中心點跟最初的中心點做差,得到偏移量, // Update the scrollbars, reflecting this change //賦值還給clipOffset,把SV拉回起始點。 if (updateScrollbars) UpdateScrollbars(mDragID == -10); } 大概看明白了SV的復位過程,就知道了所謂的復位其實是把SV所包含的內容拉回到SV裁剪區域,并讓渲染的裁剪邊界與內容的邊界恰好貼合的過程。所以復位得到坐標取決于最初內容邊界與裁剪邊界的一個差值。放到這里其實就是Grid的坐標值了。當Grid的坐標值剛好為內容邊界與裁剪邊界的差值時,復位得到的坐標就是0了。(就是把這個差值從SV轉移到了Grid) 對于UIGrid,使用ResetPosition確實是可以給ScrollView復位,但是對于UIWrapContent,因為其下的Item是循環利用的,所以內容邊界總是固定的,但在邊界的那個Item并不一定是第一個Item(就是realIndex為0的那個),每次復位也只是把當前的內容給復位了,而真正的起始Item還在更前面。所以對于UIWrapContent不能使用這個ResetPosition,那就只能直接給SV賦一個起始坐標了。而這個起始坐標則要根據起始的內容邊界和裁剪邊界的差值計算。但是這里如果我們把這個差值事先賦給了Grid(WrapContent,我習慣也給命名為Grid),那么SV的復位坐標就總是0了。 貼一個給UIWrapContent賦偏移量的方法。可以放在Start或Awake里執行一遍。public void adjustWrapPos() { if (mScroll == null) CacheScrollView(); Bounds b = NGUIMath.CalculateRelativeWidgetBounds(mScroll.transform,MChildren[0],true); Vector2 pos = transform.localPosition; if(mHorizontal) { pos.x = -(mPanel.GetViewSize().x / 2f -mPanel.baseClipRegion.x - b.extents.x-mPanel.clipSoftness.x); }else { pos.y = mPanel.GetViewSize().y / 2f +mPanel.baseClipRegion.y - b.extents.y-mPanel.clipSoftness.y; } transform.localPosition = pos; } 關于UIWrapContent,我還加了一些其他的工具方法,像是計算一個realIndex的Item對應的相對坐標,或是判定當前SV是否在底部等。放到了github上,以后用的時候可以隨時下載。

https://github.com/mutou1994/NGUI_UIWrapContent


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 榕江县| 华坪县| 洞口县| 巴东县| 三河市| 武邑县| 兴义市| 乳山市| 彰化县| 本溪| 鲜城| 永春县| 富源县| 毕节市| 岐山县| 邯郸县| 阿拉善盟| 洛隆县| 蓬安县| 民权县| 泰顺县| 望奎县| 民丰县| 河南省| 景东| 偃师市| 宿迁市| 凭祥市| 汉沽区| 格尔木市| 新巴尔虎左旗| 乌兰浩特市| 陆川县| 昌都县| 确山县| 吉木萨尔县| 宁城县| 溆浦县| 巴青县| 兴仁县| 平果县|