UIToolkit 기본 UI 개발 중

This commit is contained in:
logonkhi
2026-01-08 20:15:57 +09:00
parent ef4e86820c
commit 71831dd4c3
319 changed files with 28283 additions and 761 deletions

View File

@@ -0,0 +1,225 @@
# NHN 모듈 가이드
NHN은 uGUI 기반 **무한 스크롤(InfiniteScroll)** 컴포넌트 라이브러리입니다. 대량 데이터 목록을 효율적으로 렌더링하기 위해 아이템을 재활용(recycling)합니다.
> **참고**: 새 UI는 UI Toolkit의 `ListView`/`TreeView` 가상화 기능을 권장합니다. 이 모듈은 uGUI 기반 레거시 프로젝트용입니다.
---
## 파일 구조
```
NHN/
├── InfiniteScroll.cs # 메인 클래스 (partial)
├── InfiniteScroll.ItemContainer.cs # 아이템 컨테이너 관리
├── InfiniteScroll.ItemData.cs # 데이터 컨텍스트
├── InfiniteScroll.Layout.cs # 레이아웃 계산
├── InfiniteScroll.Scroll.cs # 스크롤 처리
├── InfiniteScrollItem.cs # 아이템 베이스 클래스
├── InfiniteScrollData.cs # 데이터 베이스 클래스
├── ScrollLayout.cs # 레이아웃 설정
├── ScrollMoveTo.cs # 스크롤 이동 유틸리티
├── LayoutUpdater.cs # 레이아웃 업데이트
├── DraggableRect.cs # 드래그 가능한 영역
├── DragEventHandler.cs # 드래그 이벤트 처리
└── ContentSizeSetter.cs # 콘텐츠 크기 설정
```
---
## 핵심 클래스
### InfiniteScroll
uGUI `ScrollRect` 기반의 무한 스크롤 컴포넌트입니다.
```csharp
namespace Gpm.Ui
{
public partial class InfiniteScroll : MonoBehaviour
{
// 이벤트
public ChangeValueEvent onChangeValue; // 스크롤 값 변경
public ItemActiveEvent onChangeActiveItem; // 아이템 활성화 변경
public StateChangeEvent onStartLine; // 시작점 도달
public StateChangeEvent onEndLine; // 끝점 도달
}
}
```
---
## 기본 사용법
### 1. 데이터 삽입
```csharp
// 단일 데이터 삽입
InfiniteScrollData myData = new MyScrollData();
infiniteScroll.InsertData(myData, immediately: true);
// 다중 데이터 삽입
InfiniteScrollData[] dataArray = new InfiniteScrollData[100];
infiniteScroll.InsertData(dataArray, immediately: true);
// 특정 인덱스에 삽입
infiniteScroll.InsertData(myData, insertIndex: 0, immediately: true);
```
### 2. 데이터 제거
```csharp
// 데이터 객체로 제거
infiniteScroll.RemoveData(dataToRemove, immediately: true);
// 인덱스로 제거
infiniteScroll.RemoveData(dataIndex: 0, immediately: true);
```
### 3. 데이터 초기화
```csharp
// 데이터만 초기화 (아이템 객체 유지)
infiniteScroll.ClearData(immediately: true);
// 완전 초기화 (아이템 객체도 제거)
infiniteScroll.Clear();
```
### 4. 데이터 업데이트
```csharp
// 단일 데이터 업데이트
InfiniteScrollData existingData = infiniteScroll.GetData(0);
// ... 데이터 수정 ...
infiniteScroll.UpdateData(existingData);
// 전체 새로고침
infiniteScroll.UpdateAllData(immediately: true);
```
---
## 이벤트 처리
```csharp
// 스크롤 값 변경 (첫 번째/마지막 보이는 인덱스)
infiniteScroll.onChangeValue.AddListener((first, last, isStart, isEnd) => {
Debug.Log($"Visible: {first}~{last}, Start: {isStart}, End: {isEnd}");
});
// 아이템 활성화 상태 변경
infiniteScroll.onChangeActiveItem.AddListener((dataIndex, isActive) => {
Debug.Log($"Item {dataIndex} is {(isActive ? "active" : "inactive")}");
});
// 시작/끝 도달
infiniteScroll.onStartLine.AddListener((isAtStart) => {
if (isAtStart) LoadPreviousPage();
});
infiniteScroll.onEndLine.AddListener((isAtEnd) => {
if (isAtEnd) LoadNextPage();
});
```
---
## 필터링
```csharp
// 필터 설정
infiniteScroll.SetFilter(data => {
MyCustomData myData = data as MyCustomData;
return myData.score > 50; // 점수 50 이상만 표시
});
// 필터 적용 후 업데이트
infiniteScroll.UpdateAllData(immediately: true);
```
---
## 스크롤 제어
```csharp
// 특정 아이템 위치로 이동
float position = infiniteScroll.GetItemPosition(itemIndex: 10);
// 뷰포트/콘텐츠 크기
float viewportSize = infiniteScroll.GetViewportSize();
float contentSize = infiniteScroll.GetContentSize();
float contentPos = infiniteScroll.GetContentPosition();
// 수동 새로고침
infiniteScroll.RefreshScroll();
infiniteScroll.ResizeScrollView();
```
---
## 커스텀 데이터/아이템 구현
### 데이터 클래스
```csharp
public class MyScrollData : InfiniteScrollData
{
public string title;
public int score;
public Sprite icon;
}
```
### 아이템 클래스
```csharp
public class MyScrollItem : InfiniteScrollItem
{
[SerializeField] private Text titleText;
[SerializeField] private Image iconImage;
public override void UpdateData(InfiniteScrollData scrollData)
{
base.UpdateData(scrollData);
if (scrollData is MyScrollData myData)
{
titleText.text = myData.title;
iconImage.sprite = myData.icon;
}
}
}
```
---
## 성능 최적화
| 항목 | 설명 |
|------|------|
| **아이템 재활용** | 화면에 보이는 아이템만 생성, 나머지는 풀에서 재활용 |
| **즉시 업데이트** | `immediately: true`로 즉시 레이아웃 갱신 |
| **필터링** | 서버 필터링 권장, 클라이언트 필터는 대량 데이터 시 주의 |
| **아이템 프리팹** | 가볍게 유지, 복잡한 UI는 지연 로딩 고려 |
---
## UI Toolkit 마이그레이션
새 프로젝트에서는 UI Toolkit의 `ListView` 사용을 권장합니다:
```csharp
// UI Toolkit ListView (권장)
var listView = new ListView();
listView.makeItem = () => new Label();
listView.bindItem = (element, index) => {
(element as Label).text = items[index].title;
};
listView.itemsSource = items;
```
InfiniteScroll → ListView 마이그레이션 시:
- `InfiniteScrollData` → 일반 데이터 클래스
- `InfiniteScrollItem``makeItem`/`bindItem` 콜백
- 이벤트 → ListView 이벤트 (`selectionChanged` 등)

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 50d860adeb4661b43bb0cf83be4c7f10
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: