<p>Xamarin.Forms.CollectionView ์‚ฌ์–‘</p>

์— ๋งŒ๋“  2018๋…„ 06์›” 27์ผ  ยท  178์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: xamarin/Xamarin.Forms

์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ

ํ˜„์žฌ Forms ListView ๋””์ž์ธ ๋ฐ ๊ตฌํ˜„์€ ๋งค์šฐ ๋ณต์žกํ•˜๊ณ  ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๊นŒ๋‹ค๋กญ์ง€๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„์˜ ๋ณต์žก์„ฑ๊ณผ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ ์š”๊ตฌ ์‚ฌํ•ญ์œผ๋กœ ์ธํ•ด ListView ๋ฒ„๊ทธ๋ฅผ ์ฐพ๊ณ  ์ˆ˜์ •ํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CollectionView ๋…ธ๋ ฅ์˜ ๋ชฉํ‘œ๋Š” API๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ณ  ๊ธฐ๋ณธ ํ”Œ๋žซํผ์˜ ๋ชฉ๋ก ์ž‘์„ฑ ์ œ์–ด ๊ธฐ๋Šฅ์„ ์ˆ˜์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰๊นŒ์ง€:

  • CollectionView๋Š” Cell์˜ ๊ฐœ๋…์„ ์™„์ „ํžˆ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ํŽธ๋ฆฌํ•˜์ง€๋งŒ Cell ๊ฐœ๋…์€ ListView์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์— ์ƒ๋‹นํ•œ ๋ณต์žก์„ฑ์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. Cells๋กœ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒƒ์€ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ DataTemplates๋กœ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • CollectionView๋Š” API ํ‘œ๋ฉด์„ ์ค„์ž…๋‹ˆ๋‹ค. ListView์˜ ์—ฌ๋Ÿฌ ์†์„ฑ๊ณผ ์ด๋ฒคํŠธ๋Š” CollectionView์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋“ค ์ค‘ ๋ช‡ ๊ฐ€์ง€๋Š” DataTemplates ๋‚ด์—์„œ ์‰ฝ๊ฒŒ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ๋“ค์€ ํŠน์ • ํ”Œ๋žซํผ์— ๋งค์šฐ ๊ตฌ์ฒด์ ์ด์—ˆ๊ณ  ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹ค์ œ๋กœ ์†ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์˜ ๋ชฉ๋ก์€ ์•„๋ž˜์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • CollectionView๋Š” ๋ ˆ์ด์•„์›ƒ์— ๋Œ€ํ•œ ๊ฐ€์ •์„ ๊ตฝํžˆ์ง€ ์•Š์Œ์œผ๋กœ์จ ๋ณด๋‹ค ์œ ์—ฐํ•œ ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์˜ค๋žซ๋™์•ˆ ์š”์ฒญํ•œ ๋ ˆ์ด์•„์›ƒ(์˜ˆ: HorizontalListView)๊ณผ ๊ธฐ๋ณธ ๊ตฌํ˜„์ด ์ด๋ฏธ ์ œ๊ณตํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

_์ฐธ๊ณ : ์ด ๋ฌธ์„œ์˜ ์–ด๋–ค ๋‚ด์šฉ๋„ ํ˜„์žฌ ListView๊ฐ€ ์ œ๊ฑฐ๋˜๊ฑฐ๋‚˜ ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ์ค‘๋‹จ๋  ๊ฒƒ์ด๋ผ๋Š” ํ‘œ์‹œ๋กœ ๊ฐ„์ฃผ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋…ธ๋ ฅ์€ ๋‹จ์ˆœํžˆ ๋งŽ์€ Forms ์‚ฌ์šฉ์ž์˜ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋ณด๋‹ค ์‰ฝ๊ฒŒ โ€‹โ€‹์ถฉ์กฑํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€์ฒด ์ปจํŠธ๋กค์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค._

_์ฐธ๊ณ : ์ด ์‚ฌ์–‘์˜ ์–ด๋–ค ๊ฒƒ๋„ ์ตœ์ข…์ ์ž„์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ธฐ๋Šฅ, ๊ตฌํ˜„ ๋ฐ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค._

์•„๋ž˜์— ์ง€์ •๋œ ๊ธฐ๋Šฅ์˜ ํ˜„์žฌ ์™„๋ฃŒ ์ƒํƒœ

์ง€์› API

์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด๋‹ค ํ˜„๋Œ€์ ์ธ ๋ชฉ๋ก์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด CollectionView ์ž‘์—…์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์ง€์› API๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • FontIconSource - ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ธ€๋ฆฌํ”„๋ฅผ ์•„์ด์ฝ˜์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์˜๋„๋Š” Forms๊ฐ€ ํ˜„์žฌ ์ด๋ฏธ์ง€๋ฅผ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ๊ณณ์—์„œ ๊ธ€๋ฆฌํ”„๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Forms์˜ ๋งŽ์€ ๋ถ€๋ถ„์—์„œ ๋ถ„๋ช…ํžˆ ๋ฐ”๋žŒ์งํ•œ ๊ธฐ๋Šฅ์ด์ง€๋งŒ CollectionView์—์„œ ์ปจํ…์ŠคํŠธ ์Šค์™€์ดํ”„ ์ œ์Šค์ฒ˜๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ๋„ ์ ˆ๋Œ€์ ์œผ๋กœ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค( FontIconSource ์‚ฌ์–‘ ์ฐธ์กฐ).

  • SwipeView - ์š”์†Œ๋ฅผ ์Šค์™€์ดํ”„ํ•˜์—ฌ ์ถ”๊ฐ€ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค( SwipeView ์‚ฌ์–‘ ์ฐธ์กฐ).

๋ ˆ์ด์•„์›ƒ ์‚ฌ์–‘

์ด ์‚ฌ์–‘์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•ญ๋ชฉ์„ ์„ธ๋กœ ๋ชฉ๋ก, ๊ฐ€๋กœ ๋ชฉ๋ก ๋˜๋Š” ๊ทธ๋ฆฌ๋“œ์— ๋ฐฐ์น˜ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•˜๋„๋ก ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋Š” ๋ชจ๋‘ ์ด๋Ÿฌํ•œ ๋ ˆ์ด์•„์›ƒ ์œ ํ˜•์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. (iOS์—์„œ ์ด ์‚ฌ์–‘์€ UITableView๊ฐ€ ์•„๋‹Œ โ€‹โ€‹UICollectionView๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.)

CollectionView์— ์ง€์ •๋œ ์‚ฌ์–‘์€ ๊ฐ ๋ Œ๋”๋Ÿฌ์˜ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ์ด ์ง€์ •๋œ ๊ฒฝ์šฐ iOS์—์„œ ๋ Œ๋”๋Ÿฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ UICollectionViewFlowLayout์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Android์—์„œ ๊ธฐ๋ณธ๊ฐ’์€ GridLayoutManager์ž…๋‹ˆ๋‹ค. UWP, GridView์—์„œ.

Forms๋Š” repeater์˜ ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ์— ์ฐธ์—ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(ํ•ญ๋ชฉ ๋ณด๊ธฐ ์ž์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ ์™ธ์—). ๋ ˆ์ด์•„์›ƒ์˜ ์ด ๋ถ€๋ถ„์€ ์™„์ „ํžˆ ๊ธฐ๋ณธ์ž…๋‹ˆ๋‹ค.

๊ฐ ๋ Œ๋”๋Ÿฌ์—์„œ ์‚ฌ์šฉํ•  ๋ ˆ์ด์•„์›ƒ ๋ฐฉ๋ฒ• ์„ ํƒ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ Android์—์„œ StaggeredGridLayoutManager๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์„ ํƒ ๋ฐฉ๋ฒ•์„ ์ˆ˜์ •ํ•˜๊ณ  ์›ํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ ๊ด€๋ฆฌ์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ด๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ListView API ์ œ๊ฑฐ

  • IsPullToRefreshEnabled - ์ด์ œ RefreshView์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • IsRefreshing - ์ด์ œ RefreshView์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • RefreshCommand - ์ด์ œ RefreshView์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
  • HasUnevenRows - ์ด์ œ ItemSizingStrategy์ž…๋‹ˆ๋‹ค.
  • RowHeight - ์ด์ œ ๋ฐฐ์น˜ํ•  ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์— ์˜ํ•ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.
  • SeparatorVisibility - CollectionView์—๋Š” ๊ธฐ๋ณธ ์ œ๊ณต ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์›ํ•˜๋Š” ๊ฒฝ์šฐ ํ…œํ”Œ๋ฆฟ์—์„œ ์ด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • SeparatorColor - CollectionView์—๋Š” ๊ธฐ๋ณธ ์ œ๊ณต ๊ตฌ๋ถ„ ๊ธฐํ˜ธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์›ํ•˜๋Š” ๊ฒฝ์šฐ ํ…œํ”Œ๋ฆฟ์—์„œ ์ด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • GroupShortName - ์ด ์†์„ฑ์€ ์ ํ”„ ๋ชฉ๋ก ๋ฐ ์˜๋ฏธ๋ก ์  ํ™•๋Œ€/์ถ•์†Œ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ–ˆ์Šต๋‹ˆ๋‹ค. CollectionView 1๋‹จ๊ณ„์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

API

์ปจํ…์ŠคํŠธ ํ•ญ๋ชฉ

ContextItem์€ ์ข…์ข… ์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด์˜ ์ผ๋ถ€๋กœ ํ‘œ์‹œ๋˜๋Š” ์ปจํ…์ŠคํŠธ ์ƒํ˜ธ์ž‘์šฉ์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

public class ContextItem
{
    public static readonly BindableProperty TextProperty;
    public string Text { get; set; }

    public static readonly BindableProperty CommandProperty;
    public ICommand Command { get; set; }

    public static readonly BindableProperty CommandParameterProperty;
    public object CommandParameter { get; set; }

    public static readonly BindableProperty IsEnabledProperty;
    public bool IsEnabled { get; set; }

    public static readonly BindableProperty IconProperty;
    public ImageSource Icon { get; set; }

    public event EventHandler Invoked;
}

์†์„ฑ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ํ…์ŠคํŠธ | ํ•ญ๋ชฉ์— ํ‘œ์‹œ๋˜๋Š” ํ…์ŠคํŠธ ์„ค๋ช…์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๋ช…๋ น | ์ด ํ•ญ๋ชฉ์ด ํ˜ธ์ถœ๋  ๋•Œ ์‹คํ–‰ํ•  ๋ช…๋ น์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๋ช…๋ น ๋งค๊ฐœ๋ณ€์ˆ˜ | |
| ํ™œ์„ฑํ™”๋จ | ์‚ฌ์šฉ์ž๊ฐ€ ์ปจํ…์ŠคํŠธ ํ•ญ๋ชฉ๊ณผ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ์•„์ด์ฝ˜ | ํ•ญ๋ชฉ์˜ ๊ทธ๋ž˜ํ”ฝ ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |

์ด๋ฒคํŠธ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ํ˜ธ์ถœ | ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ์ด ์ด ํ•ญ๋ชฉ์ด ๋‚˜ํƒ€๋‚ด๋Š” ๋ช…๋ น์ด ์‹คํ–‰๋˜์–ด์•ผ ํ•จ์„ ๋‚˜ํƒ€๋‚ผ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. |

์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด

์ƒํ™ฉ์— ๋งž๋Š” ๋ฉ”๋‰ด์— ํ‘œ์‹œํ•  ์ผ๋ จ์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ์ง€์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ContextMenu๋Š” ๋ชจ๋“  VisualElement์— ์ œ๊ณต๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ธฐ๋ณธ ํ”Œ๋žซํผ ๊ทœ์น™์— ๋”ฐ๋ผ ํ™œ์„ฑํ™”/ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

public static class ContextMenu
{
    public static readonly BindableProperty MenuItemsProperty =
            BindableProperty.CreateAttached("MenuItems", typeof(ContextMenuItems), typeof(VisualElement));
}


public class ContextMenuItems : IList<ContextItem>
{
}

์ƒˆ๋กœ๊ณ ์นจ ๋ณด๊ธฐ

#5882๋กœ ์ด๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

์„ ํƒ ๋ชจ๋“œ

CollectionView์— ๋Œ€ํ•œ ์„ ํƒ ๋ชจ๋“œ ๋™์ž‘์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

public enum SelectionMode 
{
    None,
    Single,
    Multiple
}

SelectionChangedEventArgs

public class SelectionChangedEventArgs : EventArgs
{
    public IReadOnlyList<object> PreviousSelection { get; }
    public IReadOnlyList<object> CurrentSelection { get; }
}

์†์„ฑ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ์ด์ „์„ ํƒ | ์„ ํƒ ํ•ญ๋ชฉ์ด ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „์— ์„ ํƒ๋œ ํ•ญ๋ชฉ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. |
| ํ˜„์žฌ ์„ ํƒ | ์„ ํƒ ๋ณ€๊ฒฝ ํ›„์— ์„ ํƒ๋œ ํ•ญ๋ชฉ์˜ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. |

IItemsLayout

๊ตฌํ˜„ ํด๋ž˜์Šค๊ฐ€ ํ•ญ๋ชฉ์„ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•ด CollectionView์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ์„ ์ง€์ •ํ•จ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋งˆ์ปค ์ธํ„ฐํŽ˜์ด์Šค.

public interface IItemsLayout {}

ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ ๋ฐฉํ–ฅ

ItemsLayout ๋Œ€ํ•œ ๊ฐ€๋Šฅํ•œ ๋ฐฉํ–ฅ์„ ์—ด๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋˜๋ฉด CollectionView๊ฐ€ ๋ฐฉํ–ฅ ๋ฐฉํ–ฅ์œผ๋กœ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค.

public enum ItemsLayoutOrientation
{
    Vertical,
    Horizontal
}

ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ

Forms ์ œ๊ณต ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

public abstract class ItemsLayout : IItemsLayout
{
    public ItemsLayoutOrientation Orientation { get; }

    protected ItemsLayout(ItemsLayoutOrientation orientation);

    public static readonly BindableProperty SnapPointsAlignmentProperty;
    public SnapPointsAlignment SnapPointsAlignment { get; set; }

    public static readonly BindableProperty SnapPointsTypeProperty;
    public SnapPointsType SnapPointsType { get; set; }  

    public static readonly BindableProperty ItemSpacingProperty;
    public Thickness ItemSpacing {get; set;}
}

์†์„ฑ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ ๋ฐฉํ–ฅ | ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ CollectionView๊ฐ€ ํ™•์žฅ๋˜๋Š” ๋ฐฉํ–ฅ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ์Šค๋ƒ…ํฌ์ธํŠธ ์œ ํ˜• | ๋ณด๊ธฐ๋ฅผ ์Šคํฌ๋กคํ•  ๋•Œ ์Šค๋ƒ… ์ ์˜ ๋™์ž‘์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |
| SnapPointsAlignment | ์Šค๋ƒ… ํฌ์ธํŠธ๊ฐ€ ๋ทฐ์˜ ํ•ญ๋ชฉ๊ณผ ์ •๋ ฌ๋˜๋Š” ๋ฐฉ์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ํ•ญ๋ชฉ ๊ฐ„๊ฒฉ | ๊ฐ ํ•ญ๋ชฉ ์ฃผ์œ„์˜ ๋นˆ ๊ณต๊ฐ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |

๋ชฉ๋ก ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ

public class ListItemsLayout : ItemsLayout
{
    public ListItemsLayout(ItemsLayoutOrientation orientation) : base (orientation);

    public static readonly IItemsLayout VerticalList = new ListItemsLayout(ItemsLayoutOrientation.Vertical); 
    public static readonly IItemsLayout HorizontalList = new ListItemsLayout(ItemsLayoutOrientation.Horizontal); 
}

์ •์  ๋ฉค๋ฒ„

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ์ˆ˜์ง ๋ชฉ๋ก | ์ƒˆ ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ ๋ชฉ๋ก์ด ์„ธ๋กœ๋กœ ์ปค์ง€๋Š” ๋‹จ์ผ ์—ด ๋ชฉ๋ก์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ์ˆ˜ํ‰ ๋ชฉ๋ก | ์ƒˆ ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ ๋ชฉ๋ก์ด ๊ฐ€๋กœ๋กœ ์ปค์ง€๋Š” ๋‹จ์ผ ํ–‰ ๋ชฉ๋ก์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |

GridItemsLayout

๋‹ค์ค‘ ํ–‰ ๋˜๋Š” ๋‹ค์ค‘ ์—ด ๋ ˆ์ด์•„์›ƒ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

public class GridItemsLayout : ItemsLayout
{
    public static readonly BindableProperty SpanProperty;
    public int Span { get; set; }

    public GridItemsLayout([Parameter("Span")] int span, [Parameter("Orientation")] ItemsLayoutOrientation orientation) : base (orientation);
}

SnapPointsAlignment

ListItemsLayout ์Šค๋ƒ… ํฌ์ธํŠธ์— ๋Œ€ํ•œ ๊ฐ€๋Šฅํ•œ ์ •๋ ฌ์„ ์—ด๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

public enum SnapPointsAlignment
{
    Start,
    Center,
    End
}

์—ด๊ฑฐํ˜• ๊ฐ’

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ์‹œ์ž‘ | ์Šค๋ƒ… ํฌ์ธํŠธ๋Š” ํ•ญ๋ชฉ์˜ ์•ž์ชฝ ๊ฐ€์žฅ์ž๋ฆฌ์— ๋งž์ถฐ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. |
| ์„ผํ„ฐ | ์Šค๋ƒ… ํฌ์ธํŠธ๋Š” ํ•ญ๋ชฉ์˜ ์ค‘์‹ฌ์— ๋งž์ถฐ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. |
| ๋ | ์Šค๋ƒ… ํฌ์ธํŠธ๋Š” ํ•ญ๋ชฉ์˜ ํ›„ํ–‰ ๊ฐ€์žฅ์ž๋ฆฌ์— ๋งž์ถฐ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. |

์Šค๋ƒ…ํฌ์ธํŠธ ์œ ํ˜•

ListItemsLayout ์Šค๋ƒ… ํฌ์ธํŠธ์— ๋Œ€ํ•œ ๊ฐ€๋Šฅํ•œ ๋™์ž‘์„ ์—ด๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

public enum SnapPointsType
{
    None,
    Optional,
    Mandatory,
    OptionalSingle,
    MandatorySingle,
}

์—ด๊ฑฐํ˜• ๊ฐ’

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ์—†์Œ | ์Šคํฌ๋กค์ด ํ•ญ๋ชฉ์— ๋งž์ถฐ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. |
| ์„ ํƒ์‚ฌํ•ญ | ์Šค๋ƒ… ํฌ์ธํŠธ๊ฐ€ ์ถฉ๋ถ„ํžˆ ๊ฐ€๊น๋‹ค๋ฉด ์ฝ˜ํ…์ธ ๊ฐ€ ๊ด€์„ฑ ๋ฐฉํ–ฅ์„ ๋”ฐ๋ผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์Šคํฌ๋กค์ด ๋ฉˆ์ถ”๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์Šค๋ƒ… ํฌ์ธํŠธ๋กœ ์Šค๋ƒ…๋ฉ๋‹ˆ๋‹ค. |
| ํ•„์ˆ˜ | ์ฝ˜ํ…์ธ ๋Š” ํ•ญ์ƒ ๊ด€์„ฑ ๋ฐฉํ–ฅ์„ ๋”ฐ๋ผ ์Šคํฌ๋กค์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฉˆ์ถ”๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์Šค๋ƒ… ์ง€์ ์œผ๋กœ ์Šค๋ƒ…๋ฉ๋‹ˆ๋‹ค. |
| ์˜ต์…”๋„์‹ฑ๊ธ€ | ์„ ํƒ ์‚ฌํ•ญ๊ณผ ๊ฐ™์€ ๋™์ž‘์ด์ง€๋งŒ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ•ญ๋ชฉ๋งŒ ์Šคํฌ๋กคํ•ฉ๋‹ˆ๋‹ค. |
| ํ•„์ˆ˜์‹ฑ๊ธ€ | ํ•„์ˆ˜์™€ ๊ฐ™์€ ๋™์ž‘์ด์ง€๋งŒ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ•ญ๋ชฉ๋งŒ ์Šคํฌ๋กคํ•ฉ๋‹ˆ๋‹ค. |

์†์„ฑ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ์ŠคํŒฌ | ์ œํ•œ๋œ ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐฐ์น˜ํ•  ํ•ญ๋ชฉ ์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. |

ItemSizing์ „๋žต

CollectionView์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•ญ๋ชฉ ์ธก์ • ์ „๋žต์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

public enum ItemSizingStrategy
{
    MeasureAllItems,    
    MeasureFirstItem
}

์—ด๊ฑฐํ˜• ๊ฐ’

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ๋ชจ๋“  ํ•ญ๋ชฉ ์ธก์ • | ๊ฐ ํ•ญ๋ชฉ์€ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ธก์ •๋ฉ๋‹ˆ๋‹ค. |
| ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ ์ธก์ • | ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งŒ ์ธก์ •๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ํ›„์† ํ•ญ๋ชฉ์€ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ๊ณผ ๋™์ผํ•œ ํฌ๊ธฐ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. |

ํ•ญ๋ชฉ์—…๋ฐ์ดํŠธ ์Šคํฌ๋กค ๋ชจ๋“œ

์—…๋ฐ์ดํŠธํ•˜๋Š” ๋™์•ˆ ํ•ญ๋ชฉ์˜ ์Šคํฌ๋กค ๋™์ž‘์„ ์ง€์ •ํ•˜๋Š” ์ƒ์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

public enum ItemsUpdatingScrollMode
{
    KeepItemsInView,
    KeepScrollOffset,
    KeepLastItemInView
}

์—ด๊ฑฐํ˜• ๊ฐ’

| API | ์„ค๋ช… |
| -------------- | -------------- |
| KeepItemsInView | ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ ๋ทฐํฌํŠธ์— ํ‘œ์‹œ๋˜๋Š” ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ์„ ์œ ์ง€ํ•˜๋„๋ก ์Šคํฌ๋กค ์˜คํ”„์…‹์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. |
| KeepScrollOffset | ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ ๋ชฉ๋ก์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์„ ๊ธฐ์ค€์œผ๋กœ ์Šคํฌ๋กค ์˜คํ”„์…‹์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. |
| KeepLastItemInView | ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ ๋ทฐํฌํŠธ์—์„œ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณด์ด๋Š” ํ•ญ๋ชฉ์„ ์œ ์ง€ํ•˜๋„๋ก ์Šคํฌ๋กค ์˜คํ”„์…‹์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. |

์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ

ํ•ญ๋ชฉ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

public class CollectionView : View
{
    public static readonly BindableProperty ItemsLayoutProperty;
    public IItemsLayout ItemsLayout { get; set; }

    public static readonly BindableProperty ItemsSourceProperty;
    public IEnumerable ItemsSource { get; set; }

    public static readonly BindableProperty ItemTemplateProperty;
    public DataTemplate ItemTemplate { get; set; }

    public static readonly BindableProperty ItemsUpdatingScrollMode;
    publio ItemsUpdatingScrollMode ItemsUpdatingScrollMode { get; set; }

    public static readonly BindableProperty HeaderProperty;
    public object Header { get; set; }

    public static readonly BindableProperty HeaderTemplateProperty;
    public DataTemplate HeaderTemplate { get; set; }

    public static readonly BindableProperty IsHeaderStickyProperty;
    public bool IsHeaderSticky { get; set; }

    public static readonly BindableProperty FooterProperty;
    public object Footer { get; set; }

    public static readonly BindableProperty FooterTemplateProperty;
    public DataTemplate FooterTemplate { get; set; }

    public static readonly BindableProperty IsFooterStickyProperty;
    public bool IsFooterSticky { get; set; }

    public static readonly BindableProperty EmptyViewProperty;
    public object EmptyView { get; set; }

    public static readonly BindableProperty EmptyViewTemplateProperty;
    public DataTemplate EmptyViewTemplate { get; set; }

    public static readonly BindableProperty GroupDisplayBindingProperty;
    public BindingBase GroupDisplayBinding { get; set; }

    public static readonly BindableProperty GroupHeaderTemplateProperty;
    public DataTemplate GroupHeaderTemplate { get; set; }

    public static readonly BindableProperty GroupFooterTemplateProperty;
    public DataTemplate GroupFooterTemplate { get; set; }

    public static readonly BindableProperty ItemSizingStrategy;
    public bool ItemSizingStrategy { get; set; }

    public static readonly BindableProperty IsGroupingEnabledProperty;
    public bool IsGroupingEnabled { get; set; }

    public static readonly BindableProperty SelectionModeProperty;
    public SelectionMode SelectionMode { get; set; }

    public static readonly BindableProperty SelectedItemProperty;
    public object SelectedItem { get; set; }

    public static readonly BindableProperty SelectedItemsProperty;
    public IList<object> SelectedItems { get; set; }

    public static readonly BindableProperty SelectionChangedCommandProperty;
    public ICommand SelectionChangedCommand;

    public static readonly BindableProperty SelectionChangedCommandParameterProperty;
    public object SelectionChangedCommandParameter;

    public static readonly BindableProperty RemainingItemsThresholdProperty;
    public int RemainingItemsThreshold { get; set; }

    public void ScrollTo(object item, object group = null, 
        ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true);

    public void ScrollTo(int index, int groupIndex = -1, 
        ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true);

    public event EventHandler<SelectionChangedEventArgs> SelectionChanged;

    public event EventHandler<EventArgs> RemainingItemsThresholdReached; 
}

์†์„ฑ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ | ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋ ˆ์ด์•„์›ƒ ์‚ฌ์–‘์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ํ•ญ๋ชฉ ํฌ๊ธฐ ์กฐ์ • ์ „๋žต | ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ์ปจํŠธ๋กค์— ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์šฉ์ž ํžŒํŠธ์ž…๋‹ˆ๋‹ค. MeasureAllItems (๊ธฐ๋ณธ๊ฐ’)์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๊ฐ ํ•ญ๋ชฉ์ด ๊ฐœ๋ณ„์ ์œผ๋กœ ์ธก์ •๋ฉ๋‹ˆ๋‹ค. ํ•ญ๋ชฉ ํฌ๊ธฐ๊ฐ€ ๊ท ์ผํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ด ๊ฐ’์„ MeasureFirstItem ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งŒ ์ธก์ •๋˜๊ณ  ๋ชจ๋“  ํ›„์† ํ•ญ๋ชฉ์—๋Š” ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ๊ณผ ๋™์ผํ•œ ํฌ๊ธฐ๊ฐ€ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. |
| ํ•ญ๋ชฉ ํ…œํ”Œ๋ฆฟ | ๊ฐ ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” DataTemplate์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.|
| ํ•ญ๋ชฉ์—…๋ฐ์ดํŠธ ์Šคํฌ๋กค ๋ชจ๋“œ | ํ•ญ๋ชฉ์ด ์—…๋ฐ์ดํŠธ๋  ๋•Œ ์Šคํฌ๋กค ๋™์ž‘์„ ์ง€์ •ํ•˜๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| IsGroupingํ™œ์„ฑํ™” | ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ํ—ค๋” | ์ปจํŠธ๋กค์˜ ๋งจ ์œ„์— ํ‘œ์‹œ๋  ๋ฌธ์ž์—ด, ๋ฐ”์ธ๋”ฉ ๋˜๋Š” ๋ณด๊ธฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ํ—ค๋” ํ…œํ”Œ๋ฆฟ | ํ—ค๋”์˜ ํ˜•์‹์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ ํ…œํ”Œ๋ฆฟ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| IsHeaderSticky | ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กคํ•  ๋•Œ ํ—ค๋”๊ฐ€ ์ œ์ž๋ฆฌ์— ๋‚จ์•„ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ True |
| ๋ฐ”๋‹ฅ๊ธ€ | ์ปจํŠธ๋กค์˜ ๋งจ ์•„๋ž˜์— ํ‘œ์‹œ๋  ๋ฌธ์ž์—ด, ๋ฐ”์ธ๋”ฉ ๋˜๋Š” ๋ณด๊ธฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๋ฐ”๋‹ฅ๊ธ€ ํ…œํ”Œ๋ฆฟ | ๋ฐ”๋‹ฅ๊ธ€ ์„œ์‹์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ ํ…œํ”Œ๋ฆฟ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| IsFooterSticky | ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํฌ๋กคํ•  ๋•Œ ๋ฐ”๋‹ฅ๊ธ€์ด ์ œ์ž๋ฆฌ์— ์œ ์ง€๋˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ True |
| ๋นˆ๋ณด๊ธฐ | ItemsSource๊ฐ€ ๋น„์–ด ์žˆ์„ ๋•Œ ํ‘œ์‹œ๋  ๋ฌธ์ž์—ด, ๋ฐ”์ธ๋”ฉ ๋˜๋Š” ๋ณด๊ธฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ์— ํ‹ฐ๋ทฐํ…œํ”Œ๋ฆฟ | EmptyView์˜ ํ˜•์‹์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ ํ…œํ”Œ๋ฆฟ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๊ทธ๋ฃน ํ—ค๋” ํ…œํ”Œ๋ฆฟ | ๊ทธ๋ฃน ํ—ค๋”์— ๋Œ€ํ•œ DataTemplate์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๊ทธ๋ฃน ๋ฐ”๋‹ฅ๊ธ€ ํ…œํ”Œ๋ฆฟ | ๊ทธ๋ฃน ๋ฐ”๋‹ฅ๊ธ€์— ๋Œ€ํ•œ DataTemplate์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.* |
| ํ•ญ๋ชฉ ์†Œ์Šค | ์ปจํŠธ๋กค์— ํ‘œ์‹œํ•  ๊ฐœ์ฒด ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. |
| ์„ ํƒ ๋ชจ๋“œ | ์ปจํŠธ๋กค์˜ ์„ ํƒ ๋™์ž‘์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ์„ ํƒ ํ•ญ๋ชฉ | SelectionMode ์ค‘ Single SelectionMode ์— ๋Œ€ํ•ด ์„ ํƒํ•œ ํ•ญ๋ชฉ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒํ•œ ํ•ญ๋ชฉ์ด ํ•ญ๋ชฉ ์†Œ์Šค์—์„œ ์ œ๊ฑฐ๋˜๋ฉด SelectedItem ๊ฐ€ null ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. |
| ์„ ํƒ ํ•ญ๋ชฉ | SelectionMode ์ค‘ Multiple SelectionMode ์— ๋Œ€ํ•ด ์„ ํƒํ•œ ํ•ญ๋ชฉ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒํ•œ ํ•ญ๋ชฉ์ด ํ•ญ๋ชฉ ์†Œ์Šค์—์„œ ์ œ๊ฑฐ๋˜๋ฉด SelectedItems ์—์„œ ์ œ๊ฑฐ๋˜๊ณ  SelectionChanged ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. |
| ์„ ํƒ ๋ณ€๊ฒฝ ๋ช…๋ น โ€‹โ€‹| ์„ ํƒ ํ•ญ๋ชฉ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ์‹คํ–‰ํ•  ICommand๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| SelectionChanged๋ช…๋ น ๋งค๊ฐœ๋ณ€์ˆ˜ | SelectionChangedCommand์— ๋Œ€ํ•œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๊ทธ๋ฃน๋””์Šคํ”Œ๋ ˆ์ด๋ฐ”์ธ๋”ฉ | ๊ทธ๋ฃน ํ—ค๋”๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๋ฐ”์ธ๋”ฉ์„ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. |
| ๋‚จ์€ ํ•ญ๋ชฉ ์ž„๊ณ„๊ฐ’ | RemainingItemsThresholdReached ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  CollectionView์— ์•„์ง ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ํ•ญ๋ชฉ์˜ ์ž„๊ณ„๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ์„ ์˜๋ฏธํ•˜๋Š” -1์ž…๋‹ˆ๋‹ค. A 0์ด๋ฉด ํ˜„์žฌ ItemsSource ์žˆ๋Š” ์ตœ์ข… ํ•ญ๋ชฉ์ด ํ‘œ์‹œ๋  ๋•Œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์ด 0๋ณด๋‹ค ํฌ๋ฉด ItemsSource ์•„์ง ์Šคํฌ๋กค๋˜์ง€ ์•Š์€ ํ•ญ๋ชฉ ์ˆ˜๊ฐ€ ํ˜„์žฌ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. |

ํ–‰๋™ ์–‘์‹

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ScrollTo(๊ฐ์ฒด ํ•ญ๋ชฉ, ๊ฐ์ฒด ๊ทธ๋ฃน = null, ScrollToPosition ์œ„์น˜ = ScrollToPosition.MakeVisible, bool ์• ๋‹ˆ๋ฉ”์ด์…˜ = true) | ์ง€์ •๋œ ํ•ญ๋ชฉ์„ ๋ณด๊ธฐ๋กœ ์Šคํฌ๋กคํ•ฉ๋‹ˆ๋‹ค. |
| ScrollTo(int ์ธ๋ฑ์Šค, int groupIndex = -1, ScrollToPosition ์œ„์น˜ = ScrollToPosition.MakeVisible, bool ์• ๋‹ˆ๋ฉ”์ด์…˜ = true) | ์ง€์ •๋œ ์ธ๋ฑ์Šค์˜ ํ•ญ๋ชฉ์„ ๋ณด๊ธฐ๋กœ ์Šคํฌ๋กคํ•ฉ๋‹ˆ๋‹ค. |

์ด๋ฒคํŠธ

| API | ์„ค๋ช… |
| -------------- | -------------- |
| ์„ ํƒ ๋ณ€๊ฒฝ๋จ | SelectedItem ๋˜๋Š” SelectedItems ์†์„ฑ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” SelectionMode ์†์„ฑ์„ ๋ณ€๊ฒฝํ•œ ๊ฒฐ๊ณผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. |
| RemainingItemsThresholdReached | CollectionView๊ฐ€ RemainingItemsThreshold ํ•ญ๋ชฉ๋งŒ ํ‘œ์‹œ๋˜์ง€ ์•Š์„ ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์Šคํฌ๋กค๋˜๋ฉด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋” ๋งŽ์€ ํ•ญ๋ชฉ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. |

์‹œ๋‚˜๋ฆฌ์˜ค

์ฑ„ํŒ… ์‹ ์ฒญ

๊ฐœ๋ฐœ์ž๋Š” ์ฑ„ํŒ… ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์žˆ๋Š” ์•ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๊ฐ€ ๋ชฉ๋ก ํ•˜๋‹จ์— ๋‚˜ํƒ€๋‚˜๊ณ  ํ™”๋ฉด์—์„œ ์œ„๋กœ ์Šคํฌ๋กค๋ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ œ์•ˆ๋œ API๋กœ ์ด UI๋ฅผ ์–ด๋–ป๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๊ฐœ๋ฐœ์ž๋Š” CollectionView.ItemsUpdatingScrollMode ์†์„ฑ์„ KeepLastItemInView ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์Šคํฌ๋กค ์œ„์น˜๊ฐ€ CollectionView์˜ ๋์— ์žˆ์œผ๋ฉด ์ƒˆ ํ•ญ๋ชฉ์ด ๋งจ ์•„๋ž˜์— ํ‘œ์‹œ๋˜๊ณ  ์Šคํฌ๋กค๋˜์–ด ๋ณด๊ธฐ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ์Šคํฌ๋กค ์œ„์น˜๊ฐ€ ๋‹ค๋ฅธ ๊ณณ์— ์žˆ์œผ๋ฉด ์ƒˆ ํ•ญ๋ชฉ์ด ๋งจ ์•„๋ž˜์— ํ‘œ์‹œ๋˜์ง€๋งŒ ์Šคํฌ๋กค ์œ„์น˜๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์œ„์น˜๋กœ ์Šค๋ƒ…

๊ฐœ๋ฐœ์ž์˜ ์•ฑ์€ ๋ถ€๋™์‚ฐ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ชฉ๋ก์„ ์Šคํฌ๋กคํ•  ๋•Œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฉˆ์ถœ ๋•Œ๊นŒ์ง€ ์Šคํฌ๋กค์ด ๋ถ€๋“œ๋Ÿฌ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋กค์ด ์ค‘์ง€๋˜๋ฉด ์•ฑ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์Šคํฌ๋กค(์• ๋‹ˆ๋ฉ”์ด์…˜)์„ ์Šค๋ƒ…ํ•˜์—ฌ ๋งจ โ€‹โ€‹์œ„ ๋ชฉ๋ก์ด ํŽ˜์ด์ง€ ๋งจ ์œ„์— ์™„๋ฒฝํ•˜๊ฒŒ ์ •๋ ฌ๋˜๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ƒ…์€ ํ•ญ์ƒ ์›€์ง์ž„์ด ๊ฐ€์žฅ ์ ์€ ๋ฐฉํ–ฅ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๊ฐœ๋ฐœ์ž๋Š” ๋‹ค์Œ ์„ค์ •๊ณผ ํ•จ๊ป˜ ListItemLayout ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • Orienation : Vertical
  • SnapPointsAlignment : Start
  • SnapPointsType : Mandatory

ํ…Œ์ด๋ธ”๋ทฐ

๊ฐœ๋ฐœ์ž๋Š” TableView์™€ ๊ฐ™์€ ๋ชจ์–‘์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๋Š” ์ˆ˜์ง ๋ฐฉํ–ฅ์ด ์žˆ๋Š” ListItemsLayout์„ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ItemsTemplate์€ ํ…Œ์ด๋ธ” ์…€์˜ ๋ชจ์–‘๊ณผ ๋Š๋‚Œ์„ ๋‹ค์‹œ ๋งŒ๋“œ๋Š” DataTemplate์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. "์„ค์ •" ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋‘ ๊ฐ€์ง€ ์ด์ƒ์˜ ์„ค์ • ์œ ํ˜•์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ์˜๋„๋œ ๊ฒฝ์šฐ(์˜ˆ: ์ผ๋ถ€ ์…€์€ ์„ค์ •์„ ์ผœ๊ณ  ๋Œ ์ˆ˜ ์žˆ๊ณ  ๋‹ค๋ฅธ ์…€์€ ๋ณด์กฐ ์„ค์ • ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋„๋ก ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ) ๊ฐœ๋ฐœ์ž๋Š” ๋‹ค์Œ์„ ์›ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผœ๊ธฐ/๋„๊ธฐ ์„ค์ •์šฉ DataTemplate(ํ† ๊ธ€ ์Šค์œ„์น˜ ์‚ฌ์šฉ)๊ณผ ํƒ์ƒ‰์šฉ DataTemplate(๋ณด์กฐ ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ํƒ์ƒ‰ ์Šคํƒ์œผ๋กœ ํ‘ธ์‹œํ•˜๋Š” TapGesture ์‚ฌ์šฉ)์„ ๊ตฌํ˜„ํ•˜๋Š” DataTemplateSelector๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋ฌดํ•œ ์Šคํฌ๋กค

๊ฐœ๋ฐœ์ž๋Š” "๋‰ด์Šค" ํ”ผ๋“œ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์•ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. "๋‰ด์Šค" ํ”ผ๋“œ์—๋Š” ์ž ์žฌ์ ์ธ ํ•ญ๋ชฉ์ด ๋ฌดํ•œํžˆ ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ˜„์žฌ ๋กœ๋“œ๋œ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ๋์— ๊ฐ€๊นŒ์›Œ์ง€๋ฉด ์•ฑ์€ ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์— ๋น„๋™๊ธฐ์‹ ํ˜ธ์ถœ์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„/๋Œ€์—ญํญ ์ œํ•œ ๋‚ด์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ๊ณต๋ฐฑ์„ ๋ณด๊ฑฐ๋‚˜ ์Šคํฌ๋กค์„ ์ค‘์ง€ํ•˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ด ์•ฑ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ œ์•ˆ๋œ API๋กœ ์–ด๋–ป๊ฒŒ ์ด๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๋ฅผ ์œ„ํ•ด ๊ฐœ๋ฐœ์ž๋Š” RemainingItemsThreshold ์†์„ฑ์„ ์„ค์ •ํ•˜๊ณ  RemainingItemsThresholdReached ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•ธ๋“ค๋Ÿฌ๋Š” ์„œ๋ฒ„์— ๋Œ€ํ•œ ๋น„๋™๊ธฐ์‹ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๊ธฐ๋ณธ ItemsSource ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

collectionview blocker roadmap enhancement โž•

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์‹œ์ฐจ ํ—ค๋”๋ฅผ ์ง€์›ํ•˜๋Š” Scrolling ์ด๋ฒคํŠธ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  178 ๋Œ“๊ธ€

์‹œ์ฐจ ํ—ค๋”๋ฅผ ์ง€์›ํ•˜๋Š” Scrolling ์ด๋ฒคํŠธ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์— ๋Œ€ํ•ด ์ข‹์•„ํ•  ๊ฒƒ์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธ€๊ผด ์•„์ด์ฝ˜ ์†Œ์Šค

FontIconSource์˜ ๊ฒฝ์šฐ ์œ ๋‹ˆ์ฝ”๋“œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ). f370 ๊ฐ’์„ ๊ฐ€์ง„ FontIconSource๋ฅผ ๋ณด๊ณ  ์žˆ๋‹ค๋ฉด ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์ „ํ˜€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์•„์ด์ฝ˜ ๊ธ€๊ผด์„ ์„ ํƒํ•˜๊ณ  Forms์—์„œ fa-app-store-ios ๋ฅผ f370 ํ•ด๋‹นํ•˜๋Š” ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋ฉด ์ด์ œ ํ•œ ๋ˆˆ์— ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์•„์ด์ฝ˜์€ Font Awesome์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ด๋ฉฐ iOS App Store ์•„์ด์ฝ˜์ž…๋‹ˆ๋‹ค. ๊ฒฐ์ฝ” Forms๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ธ€๊ผด(๋˜๋Š” ํ•ด๋‹น ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ฒƒ)์— ๋Œ€ํ•ด ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋ง์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ผ๋ถ€ ๊ณต๊ฐœ ์š”์ง€์—์„œ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜ Community Toolkit ๋“ฑ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋Š ์ชฝ์ด๋“  ์šฐ๋ฆฌ๋Š” ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ด๋ฅผ ์œ„ํ•ด XAML Extension์—์„œ ๊ตฌ์›Œ์งˆ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

<Image Source="{FontIcon fa-app-store-ios,Color={StaticResource primaryColor}}" />

๋ฉ”๋‰ด

์•ž์„œ @davidortinau ์™€ iOS CollectionView ๋ฌธ์„œ์— ํ‘œ์‹œ๋œ ๊ฒƒ๊ณผ ๊ฐ™์€ ์…€ ๋ฉ”๋‰ด ์ ‘๊ทผ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ

๋‚ด๊ฐ€ ํŽธํ–ฅ๋˜์–ด ์žˆ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๋งค์šฐ ๋งŽ์€ ๋ถ€๋ถ„์ด MVVM ๋””์ž์ธ ํŒจํ„ด์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. SelectionChanged & RemainingItemsThresholdReached ์ด๋ฒคํŠธ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ๋ชจ๋‘ API์— ์ค‘์š”ํ•˜์ง€๋งŒ ViewModel์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฒ„์ „์œผ๋กœ ์ด๋Ÿฌํ•œ OOB๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ™˜์ƒ์ ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค... ๋‚˜๋Š” ๋ช…๋ นํ•œ๋‹ค.

RemainingItemsThresholdReached๋Š” ํ‰๋ฒ”ํ•œ ์˜ค๋ž˜๋œ EventArgs๋ฅผ ๋ณด๋‚ด๊ธฐ๋งŒ ํ•˜๋ฉด ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…๋ น์— null์„ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ๊ฐ€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SelectionChanged์˜ ๊ฒฝ์šฐ ์ด์ „ ํ•ญ๋ชฉ์— ๋น„ํ•ด ์ƒˆ ํ•ญ๋ชฉ์„ ์•„๋Š” ๊ฒƒ์ด ๋” ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ์œผ๋ฏ€๋กœ ๋‹จ์ˆœํžˆ ์ƒˆ ํ•ญ๋ชฉ OOB๋ฅผ SelectionChangedCommand์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ์šฉ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ์ตœ์†Œํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ผ๋ถ€ EventToCommandBehavior์™€ ํ•จ๊ป˜ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ์ตœ์†Œํ•œ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋ชฉ๋ก ๋ณด๊ธฐ๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ์™„๋ฒฝํ•œ ์ƒ˜ํ”Œ์€ ๋‹ค์Œ ์œ„์น˜์—์„œ ์บ˜๋ฆฐ๋” ์ œ์–ด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
-์ผ(์…€)์€ ๋‹ค์–‘ํ•œ ์Šคํƒ€์ผ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์Šน์ง„์ผ, ์ƒ์ผ, ์žฅ์• ์ธ / ๋ฌด์„ธ์ผ / ๊ณตํœด์ผ๋กœ ...
๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ •์˜ ๊ธ€๊ผด์ด ํฌํ•จ๋œ ์•„์ด์ฝ˜, ์„ ํƒํ•œ ๊ฒฝ์šฐ ์…€์— ๊ทธ๋ฆผ์ž๊ฐ€ ์žˆ๊ณ , r์— ์žˆ๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์Šคํƒ€์ผ
๋ถ„๋…ธ, ๋ฒ”์œ„์˜ ์‹œ์ž‘๊ณผ ๋์—์„œ ๊ธฐํƒ€
- ๋‚ ์งœ ๋ฒ”์œ„ ์„ ํƒ ๊ฐ€๋Šฅ
-month ํ—ค๋” ๋ฐ ์‚ฌ์šฉ์ž ์ •์˜ ํ—ค๋” ์Šคํƒ€์ผ
-month ํ—ค๋”์—๋Š” ํ˜„์žฌ ๋‹ฌ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํŠน๋ณ„ํ•œ ๋ณด๊ธฐ/๋™์ž‘/ํ‘œ์‹œ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋ฒ„ํŠผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

GroupFooterTemplate๋„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ Forms์—์„œ ๋งค์šฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค :-) CollectionView๋Š” ์ง€๋‚œ 5๋…„ ๋™์•ˆ ๋‚ด๊ฐ€ ๋งŒ๋“  ๊ฑฐ์˜ ๋ชจ๋“  Forms ์•ฑ์—์„œ ๊ฐ’๋น„์‹ผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ œ๊ฑฐํ•˜๊ณ  ์ œํ•œ ์‚ฌํ•ญ์„ ํ•ด๊ฒฐํ•˜๋ฉฐ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹ - ๊ธฐ๋ณธ ํ”Œ๋žซํผ์˜ ํž˜์„ ํ™œ์šฉํ•˜๊ณ  ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

Forms์— ๋Œ€ํ•ด ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ์„  ์‚ฌํ•ญ์ด ํ•˜๋‚˜๋งŒ ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
(์‹ค์ œ๋กœ 2017๋…„ @davidortinau๋‹˜์˜

์ด๊ฒƒ์€ ์ •๋ง ๊ต‰์žฅํ•˜๊ณ  ์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์˜จ ๊ฒƒ์ž…๋‹ˆ๋‹ค! API๋Š” ๊นจ๋—ํ•˜๊ณ  ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค(HasUnevenRows์˜ ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!).

@dhaligas๊ฐ€ ์ œ์•ˆํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์Šคํฌ๋กค ์ด๋ฒคํŠธ๊ฐ€ ๋งค์šฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์‹œ์ฐจ ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ๊ฒฝ์šฐ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์˜ˆ๋ฅผ ๋“ค์–ด ์Šคํฌ๋กคํ•˜๋Š” ๋™์•ˆ ๋ถ€๋™ ์ž‘์—… ๋ฒ„ํŠผ์„ ์ˆจ๊น๋‹ˆ๋‹ค.

FontIconSource๋Š” ์ข‹์€ ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ํ”Œ๋žซํผ(iOS ๋˜๋Š” UWP์™€ ์œ ์‚ฌ)์— ๋Œ€ํ•ด ์œ ๋‹ˆ์ฝ”๋“œ๊ฐ€ ๋งคํ•‘๋œ ๊ธฐ๋ณธ ์•„์ด์ฝ˜ ๋ชฉ๋ก์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ •ํ™•ํžˆ ํ•„์š”ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. API๋Š” ํ›จ์”ฌ ๋” ๊น”๋”ํ•ด ๋ณด์ด๋ฉฐ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์กฐํ™”๋œ ์—ฌ๋Ÿฌ ๋ณด๊ธฐ/์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋” ๊นจ๋—ํ•˜๊ณ  ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ๋‚ด ์˜๊ฒฌ:

@dansiegel ๋‚จ์€ ํ•ญ๋ชฉ ์ž„๊ณ„๊ฐ’์ด ์ถฉ์กฑ๋˜๋ฉด ๋ช…๋ น์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. SelectedItems์— ํ•„์š”ํ•œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. SelectedItems๊ฐ€ ObservableCollection(๋˜๋Š” INotifyCollectionChanged๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ)์ธ ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋งํ•œ ๋ชจ๋“  ๊ฒƒ(๋ณ€๊ฒฝ ์‚ฌํ•ญ, ๋ณ€๊ฒฝ๋œ ์‚ฌํ•ญ, ์‹ฌ์ง€์–ด ์ด์œ ๊นŒ์ง€)์ด ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋ณต์žก์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด CollectionView์— ๊ฐ€๋Šฅํ•œ ํ•œ ์ ์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์Šคํฌ๋กค๋ง: ์Šคํฌ๋กค๋ง ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ Android์˜ ๊ฒฝ์šฐ ์ด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์ง€๋งŒ iOS์˜ ๊ฒฝ์šฐ UITableViewSource๋ฅผ ๋ž˜ํ•‘ํ•˜๊ณ  Scrolled ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜์ด์žฌํ‚นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ™•์žฅ์„ฑ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–ด๋Œ‘ํ„ฐ ๋ฐ TableViewSources์— ๋Œ€ํ•ด ๋‚ด๋ถ€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง๊ณ  ๋„ค์ดํ‹ฐ๋ธŒ ๋ Œ๋”๋Ÿฌ์—์„œ "CreateAdapter" ๋ฐ "CreateViewSource" ๋ฉ”์„œ๋“œ(๋ฐ ๋‹ค๋ฅธ ํ”Œ๋žซํผ์˜ ๊ฒฝ์šฐ ์œ ์‚ฌ)๋ฅผ ๋…ธ์ถœํ•˜์—ฌ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ๊ณ ์œ ํ•œ ํ˜•์‹์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Android์—์„œ ๋Œ์–ด์„œ ๋†“๊ธฐ ์ง€์›์„ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ง€์ • ListAdapter๊ฐ€ ์žˆ์œผ๋ฉฐ ์•ž์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์Šคํฌ๋กค ๋ฐ ๋Œ์–ด์„œ ๋†“๊ธฐ๋ฅผ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ง€์ • UITableViewSources๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ํด๋ž˜์Šค ๋“ฑ์˜ ๋ž˜ํ•‘์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๊ฐ€ ์ข‹์•„ํ•˜๋Š” ์ฝ”๋“œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์–ด๋Œ‘ํ„ฐ/๋ทฐ ์†Œ์Šค์—๋งŒ ์ ์šฉ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒˆ API์—์„œ๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋™์ž‘์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ง€์ ์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

์ •๋ง ํ›Œ๋ฅญํ•˜๊ณ  ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ธ ๊ฒƒ ๊ฐ™์•„์š”!
iOS๋Š” ์ด๋ฏธ UICollectionView ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ CollectionView๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ํ˜ผ๋ž€๊ณผ ์ž˜๋ชป๋œ Google ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ?

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ CollectionView ์‚ฌ์–‘์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ƒ๊ฐ์ด ์žˆ๊ณ  ๋Œ€ํ™”๋ฅผ ๋”ฐ๋ผ๊ฐ€๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ถ€ ํ•ญ๋ชฉ์„ ๋ณ„๋„์˜ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

๋‚˜์ค‘์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

public class MultipleFontIconsSource : ImageSource
{
    public List<FontIconSource> Icons { get; set; }
}

์Šคํƒœํ‚น ์•„์ด์ฝ˜์„ ์ง€์›ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. https://fontawesome.com/how-to-use/on-the-web/styling/stacking-icons

๋‚ด ํ”ผ๋“œ๋ฐฑ:

  1. CollectionView ํด๋ž˜์Šค์— ํ•ญ๋ชฉ ์„ ํƒ ๊ธฐ๋Šฅ์„ ๋„ฃ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ํŠน์ • ๊ธฐ๋Šฅ์ด ์žˆ๋Š” CollectionView์—์„œ ํŒŒ์ƒ๋œ ์ถ”์ƒ ๊ธฐ๋ณธ ํด๋ž˜์Šค ListCollectionView๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
public class CollectionView : View
{
   // Common capabilities related to a view capable of displaying a list of items
    public static readonly BindableProperty ItemsLayoutProperty;
    public IItemsLayout ItemsLayout { get; set; }

    public static readonly BindableProperty ItemsSourceProperty;
    public IEnumerable ItemsSource { get; set; }
}

public class ListCollectionView : CollectionView
{
     // Item selection capabilities and other capabilities 

    public static readonly BindableProperty SelectionModeProperty;
    public SelectionMode SelectionMode { get; set; }

    public static readonly BindableProperty SelectedItemProperty;
    public object SelectedItem { get; set; }

    public static readonly BindableProperty SelectedItemsProperty;
    public IList<object> SelectedItems { get; set; }

    public static readonly BindableProperty SelectedItemsProperty;
    public IList<object> SelectedItems { get; set; }
}

๋‚ด ์•„์ด๋””์–ด๋Š” Windows XAML์˜ ItemsControl๊ณผ ์œ ์‚ฌํ•œ CollectionView๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ItemsControl์€ ํ•ญ๋ชฉ์„ ๋ฐฐ์น˜ํ•˜๋Š” Panel ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Forms์—๋Š” CollectionView ๋ฐ IItemsLayout์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ IItemLayout์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ์€ ์Šคํƒ ๋ ˆ์ด์•„์›ƒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ Windows XAML์˜ StackPanel๊ณผ ๊ฒฐํ•ฉ๋œ ItemsSource๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅํ•œ StackLayout !

ํ•ญ๋ชฉ ์„ ํƒ ์™ธ์—๋„ CollectionView์— ๋„ฃ์ง€ ์•Š์€ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฉฐ ์ด๋ฅผ ListCollectionView์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด CollectionView์—๋Š” ์Šคํฌ๋กค์ด ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒํ•˜๋ฉด ์ด ์Šค๋ ˆ๋“œ๋ฅผ ๋ฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. IItemsLayout ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ด๋ฆ„์„ ICollectionViewLayout์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ์—๋Š” ์ด๋ฏธ Layout ๋ฐ ItemsView ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๊ธด ์ด๋ฆ„์ด์ง€๋งŒ ICollectionViewLayout์€ ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์ด ์•„๋‹ˆ๋ผ CollectionView์—๋งŒ ํ•ด๋‹นํ•˜๋Š” ์šฉ๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ•๋ ฅํ•œ ํ‘œ์‹œ์ž…๋‹ˆ๋‹ค.

  2. ItemsLayout ํด๋ž˜์Šค์˜ ์ด๋ฆ„์„ OrientedCollectionViewLayout์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ถ”์ƒ ๊ธฐ๋ณธ ํด๋ž˜์Šค๊ฐ€ ์‹ค์ œ๋กœ ๋ฌด์—‡์„ ์œ„ํ•œ ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ๊ฐ•๋ ฅํ•œ ํ‘œ์‹œ์ด๋ฉฐ ๋ชจ๋“  ํŒŒ์ƒ ํด๋ž˜์Šค๋Š” ํ•ญ๋ชฉ์„ ์ง€ํ–ฅ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ๋ ˆ์ด์•„์›ƒํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด๋ฆ„์— "Oriented"๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚˜์ค‘์— "CollectionViewLayout"์ด๋ผ๋Š” ์ถ”์ƒ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ๋ฐฉํ–ฅ์ด ์žˆ๋Š” ํด๋ž˜์Šค๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ ๋ ˆ์ด์•„์›ƒ ํด๋ž˜์Šค์— ๋ช‡ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๊ณตํ†ต ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ.

  3. ViewCell์„ ์ œ๊ฑฐํ•˜๊ณ  DataTemplate๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ํ™˜์˜ํ•˜๋ฉฐ ์žฌ์‚ฌ์šฉ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  1. RefreshView์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
    ์–ด๋–ป๊ฒŒ๋“  RefreshView๊ฐ€ iOS์˜ UIRefreshControl์— ๋งคํ•‘๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๊นŒ? Android ๋ฐ UWP์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

๊ด€์‹ฌ์ด ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์œผ๋ฉด ์œ„์˜ ์ฒซ ๋ฒˆ์งธ ์˜๊ฒฌ์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” @andreinitescu ๊ฐ€ ์Šคํฌ๋กคํ•˜์ง€ ์•Š๋Š” ์ปฌ๋ ‰์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด

์Šคํฌ๋กค ๊ธฐ๋Šฅ์„ ์ œ์–ดํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด๊ฐ€ ๋งˆ์Œ์— ๋“ค๊ธด ํ•˜์ง€๋งŒ ListView์˜ ๋ชจ๋“  ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์ด๋‚˜ ๋จธ๋ฆฌ ์œ„์—์„œ ์ œ์•ˆ๋œ CollectionView๋ฅผ ํฌํ•จํ•˜๋Š” ์Šคํฌ๋กค๋˜์ง€ ์•Š๋Š” "์ปฌ๋ ‰์…˜"์— ๋Œ€ํ•œ ์„ค๋“๋ ฅ ์žˆ๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋„ ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค๋˜์ง€ ์•Š๋Š” ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋‚˜์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ํ•ญ์ƒ ์‚ฌ์†Œํ•œ ํ•ญ๋ชฉ ๋ชฉ๋ก์œผ๋กœ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ListView๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜์ ์ธ ์ด์œ ๋Š” ์„ ํƒ์„ ์›ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋ชฉ๋ก์„ ๊ฐ€๋กœ๋กœ ๋ ˆ์ด์•„์›ƒํ•˜๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ์ œ์•ˆ๋œ ์‚ฌ์–‘์— ํฌํ•จ๋œ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์Šคํฌ๋กค ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@bmacombe ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅํ•œ StackLayout์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด "๊ฐ„๋‹จํ•˜๋‹ค"๋Š” ๋ฐ ๋™์˜ํ•˜์ง€๋งŒ ๊ทธ๊ฒŒ ์ œ๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์š”์ง€๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ์— ํฌํ•จํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์•ฝ๊ฐ„์˜ ๊ณ„ํš๋งŒ ์žˆ์œผ๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์œ„์—์„œ ์ด๋ฏธ ๋งํ–ˆ๋“ฏ์ด ๊ธฐ๋ณธ ํด๋ž˜์Šค(Windows XAML์˜ ItemsControl๊ณผ ์œ ์‚ฌ) ๋ฐ CollectionView(ListView)์˜ ๋‘ ๊ฐ€์ง€ ํด๋ž˜์Šค์— ๊ธฐ๋Šฅ์„ ๋ถ„์‚ฐํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ๋Š” ๊ณ„์ธต ๊ตฌ์กฐ์— ์„ ํƒ๊ธฐ ํด๋ž˜์Šค๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.primitives.selector ์ฐธ์กฐ).

์Šคํฌ๋กคํ•˜์ง€ ์•Š๋Š” ์˜ต์…˜์ด ์žˆ๋Š” ์‚ฌ์†Œํ•œ ์ด์œ ๋Š” ์ผ๋ถ€ ํŽ˜์ด์ง€์—๋Š” ์ „์ฒด ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ScrollView์™€ ํ•ญ๋ชฉ ๋ชฉ๋ก์ด ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ํ˜„์žฌ๋กœ์„œ๋Š” ScrollView์— ListView๋ฅผ ๋‘๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ์ž ์žฌ์ ์œผ๋กœ ListView์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๊ฐ–๊ณ  ์žˆ๊ณ  ๊ฑฐ๊ธฐ์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅํ•œ CollectionView๋Š” ์—ฌ๋Ÿฌ ๋ฒˆ ํ•„์š”ํ–ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ BindableStack์„ ์ž‘์„ฑํ–ˆ์ง€๋งŒ ํ•˜๋‚˜์—์„œ ๊ตฌ์šด ๊ฒƒ์ด ์ž‘์—…ํ•˜๊ธฐ์— ํ›จ์”ฌ ๋” ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@adammeaney ๊ทธ๊ฒƒ์€ ๋ง์ด ๋˜๋ฉฐ ์ง€๊ธˆ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋น„์Šทํ•œ ์ผ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

@andreinitescu ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ด๋ผ๋Š” ๋ฐ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด ํ•„์š”ํ•œ ๊ฒƒ๊ณผ ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ฐ™์€ ํŽ˜์ด์ง€์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ค ์œ ํ˜•์˜ "์Šคํฌ๋กค ์—†์Œ" ์˜ต์…˜์ด ์žˆ๋Š” ํ•œ ๋‘ ์ ‘๊ทผ ๋ฐฉ์‹ ๋ชจ๋‘ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ž์‹ ์˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ๋Š” ํ•ญ์ƒ ๋งŽ์€ ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค์— ๊ตฌ์ถ•ํ•˜๊ฑฐ๋‚˜ ์ฆ๋ถ„ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ์œ ์‚ฌํ•œ ํด๋ž˜์Šค๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Forms ํŒ€์€ ํŠนํžˆ ๊ธฐ๋ณธ ํ”Œ๋žซํผ ๊ตฌํ˜„์„ ๊ณ ๋ คํ•˜์—ฌ ๊ฐ€์žฅ ์ž˜ ๊ตฌํ˜„ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

@bmacombe ๊ณ„ํš์„ ํ•˜๋ฉด ํ•œ ๋Œ๋กœ ๋‘ ๋งˆ๋ฆฌ์˜ ์ƒˆ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š” CollectionView ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์— IItemLayout์ด ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ Œ๋”๋Ÿฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด iOS์˜ ๊ธฐ๋ณธ UIStackView ๋˜๋Š” UWP์˜ StackPanel ๋˜๋Š” Android์˜ LinearLayout์— ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฝ๋„๋ก ๊ธฐ์กด StackLayout์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด๊ธฐ๋ฅผ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ์ธ์ƒ์€ ์ƒˆ๋กœ์šด ListView๊ฐ€ ๊ธฐ์กด ListView์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋™์‹œ์— ์—ฌ๊ธฐ ์—์„œ "RepeatableBinder" ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ

์ด ์‚ฌ์–‘์„ ์ถ”์ง„ํ•˜๊ธฐ ์ „์— ListView2์˜ ์œ„์น˜๋ฅผ โ€‹โ€‹ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋™์ผํ•œ ํ•„์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ค‘๋ณต์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์‚ฌ์–‘์—์„œ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ CollectionView์— ๋„ฃ๋Š” ๊ฒƒ์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

2680 ์ด ์‚ฌ์–‘์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ScrollBar ํ™œ์„ฑํ™”์™€ ๊ด€๋ จํ•˜์—ฌ.

@andreinitescu

RefreshView์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์–ด๋–ป๊ฒŒ๋“  RefreshView๊ฐ€ iOS์˜ UIRefreshControl์— ๋งคํ•‘๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๊นŒ? Android ๋ฐ UWP์—์„œ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

UWP์—์„œ๋Š” RefreshContainer๋ฅผ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. Android์—์„œ๋Š” ์•„๋งˆ๋„ SwipeRefreshLayout ์ž…๋‹ˆ๋‹ค.

@krdmllr

iOS๋Š” ์ด๋ฏธ UICollectionView ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ CollectionView๋ฅผ ๊ฒ€์ƒ‰ํ•  ๋•Œ ํ˜ผ๋ž€๊ณผ ์ž˜๋ชป๋œ Google ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฌธ์ œ์ž…๋‹ˆ๊นŒ?

๋ฌธ์ œ์ง€๋งŒ ์ƒˆ๋กœ์šด ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. GestureRecognizer, ListView, Grid ๋ฐ Forms์˜ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ ํ•ญ๋ชฉ์— ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์•ฝ๊ฐ„ ๊ณ ์‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. "ํ™”๋ฉด์— ๋งŽ์€ ํ•ญ๋ชฉ"์— ๋Œ€ํ•ด ๊ฐ€๋Šฅํ•œ ์ด๋ฆ„์ด ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค.

"CollectionView"๋Š” ํ˜„์žฌ Forms์— ์žˆ๋Š” ๊ฒƒ๊ณผ ์ถฉ๋Œํ•˜์ง€ ์•Š์œผ๋ฉฐ UWP ์ปจํŠธ๋กค ์ด๋ฆ„("ListView"๊ฐ€ ํ•˜๋Š” ๋ฐฉ์‹)๊ณผ ์ถฉ๋Œํ•˜์ง€ ์•Š์œผ๋ฉฐ UICollectionView์™€ _์ •ํ™•ํžˆ_ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค("UI" ์ ‘๋‘์‚ฌ ๋•Œ๋ฌธ์—). ๊ฒ€์ƒ‰ ๋ชฉ์ ์œผ๋กœ๋Š” 100% ์ด์ƒ์ ์ด์ง€๋Š” ์•Š์ง€๋งŒ ์ปจํŠธ๋กค์˜ ์˜๋„๋ฅผ ๊ฐ€์žฅ ์ž˜ ํ‘œํ˜„ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๋ˆ„๊ตฐ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์ฆ‰์‹œ ์‚ฌ๋ž‘์— ๋น ์ง€๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์ œ์•ˆํ•˜๋ฉด ๊ธฐ๊บผ์ด ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.

(์ด๋ฆ„์„ "ListView2ColonRevengeOfTheListView"๋กœ ์ง€์ •ํ•˜๊ณ  ์‹ถ์—ˆ์ง€๋งŒ @davidortinau๊ฐ€ ์ €๋ฅผ ๊ฒฉ์ถ”

@dansiegel

์ด์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ข‹์€ ๋งฅ๋ฝ์€ ์™ผ์ชฝ์œผ๋กœ ์Šค์™€์ดํ”„ํ•  ๋•Œ ํ•˜๋‚˜์˜ ๋ฉ”๋‰ด๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์Šค์™€์ดํ”„ํ•  ๋•Œ ๋‹ค๋ฅธ ๋ฉ”๋‰ด๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ์ด๋ฉ”์ผ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

SwipeView ์‚ฌ์–‘์„ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@GalaxiaGuy

์Šคํƒœํ‚น ์•„์ด์ฝ˜ ์ง€์›

์ข‹์€ ์ ์ž…๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋ฉด ์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์ œ๊ณต UWP ๊ธ€๋ฆฌํ”„์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํƒ ์œ ํ˜•์ด ๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์•ฝ๊ฐ„์˜ ์กฐ์‚ฌ๋ฅผ ํ•ด์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค(๋‹ต์€ "์˜ˆ"๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค).

์—…๋ฐ์ดํŠธ: ์ด ์‚ฌ์–‘์˜ FontIconSource ๋ถ€๋ถ„์ด ์ž์ฒด ์‚ฌ์–‘ ์œผ๋กœ ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์•จ๋ฒ”์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ์‚ฌ์ง„์„ ์„ ํƒํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด ์„ ํƒ ํ•ญ๋ชฉ์—์„œ ํ•ญ๋ชฉ์„ ์—ฌ๋Ÿฌ ๊ฐœ ์„ ํƒํ•˜๋Š” ์‚ฌ์šฉ์ž ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค. OneDrive ๋˜๋Š” WhatsApp๊ณผ ๊ฐ™์€ ์•ฑ์—์„œ ํ”ํžˆ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค.

20180527_181626000_ios

@hartez

์ฆ‰, ๋ˆ„๊ตฐ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์ฆ‰์‹œ ์‚ฌ๋ž‘์— ๋น ์ง€๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์ œ์•ˆํ•˜๋ฉด ๊ธฐ๊บผ์ด ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ด์œ ๋กœ ์ด๋ฏธ ์ƒˆ ์ด๋ฆ„์„ ์ œ์•ˆํ–ˆ์Šต๋‹ˆ๋‹ค.

SelectionMode ์ด Multiple ์ผ ๋•Œ SelectedItem ์˜ ๊ฐ’์€ ์–ผ๋งˆ์ž…๋‹ˆ๊นŒ? ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜์žˆ๋Š” 5 ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์„ ํƒ ์ˆœ์„œ์— ๋”ฐ๋ผ ๋งˆ์ง€๋ง‰์œผ๋กœ ์„ ํƒํ•œ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.
  2. ์†Œ์Šค ์ˆœ์„œ๋กœ ๋งˆ์ง€๋ง‰์œผ๋กœ ์„ ํƒํ•œ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.
  3. ์„ ํƒ ์ˆœ์„œ์— ๋”ฐ๋ผ ๋งˆ์ง€๋ง‰์œผ๋กœ ์„ ํƒ/์„ ํƒ ํ•ด์ œ๋œ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.
  4. ์†Œ์Šค ์ˆœ์„œ์— ๋”ฐ๋ผ ๋งˆ์ง€๋ง‰์œผ๋กœ ์„ ํƒ/์„ ํƒ ํ•ด์ œ๋œ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.
  5. ์—†๋Š”



    (2), (3), (4)๋Š” ๊ทธ๋‹ค์ง€ ์œ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ชจ๋“  ์˜ต์…˜์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด ๊ทธ๊ฒƒ๋“ค์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. (1)์ด ๊ฐ€์žฅ ๋…ผ๋ฆฌ์ ์ธ ์„ ํƒ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. (5) SelectionMode ๊ฐ€ Multiple ๊ฒฝ์šฐ SelectedItem ๋ฅผ ์ „ํ˜€ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ ค๋Š” ๊ฒฝ์šฐ.

@AmrAlSayed0

SelectionMode๊ฐ€ ๋‹ค์ค‘์ผ ๋•Œ SelectedItem์˜ ๊ฐ’์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ง€๊ธˆ ๋Œ€๋‹ต์€ " SelectionMode ๋ฅผ Multiple ๋กœ ์ „ํ™˜ํ•˜๊ธฐ ์ „์˜ ์ƒํƒœ"์ž…๋‹ˆ๋‹ค.

@๋กœ๊ธฐํฌ

์„ ํƒ ํ•ญ๋ชฉ์—์„œ ํ•ญ๋ชฉ์„ ์—ฌ๋Ÿฌ ๊ฐœ ์„ ํƒํ•˜๋Š” ์‚ฌ์šฉ์ž ์‹œ๋‚˜๋ฆฌ์˜ค์ž…๋‹ˆ๋‹ค.

์ด ์„ ํƒ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์ง€์›๋˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฌป๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? AFAIK, ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ชจ๋“  ๊ธฐ๋ณธ ์ปจํŠธ๋กค์ด ์ด๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ CollectionView์—์„œ _์ง€์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค_.

SelectionMode์— ๋Œ€ํ•œ ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅํ•œ ์Šคํƒ€์ผ์€ ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. SelectionMode=None, Transparent ๋“ฑ์ธ ๊ฒฝ์šฐ ์ด๊ฒƒ์€ Radlist๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์œผ๋กœ ๋ฐ”์ธ๋”ฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹œ๊ฐ์  ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋งค์šฐ ์œ ์šฉํ•˜๊ณ  ์‰ฌ์šด ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๊ฐ ์„ ํƒ ๋ชจ๋“œ์— ๋Œ€ํ•œ ์Šคํƒ€์ผ์€ ์ด๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

@andreinitescu

https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment -401015625(๋ฐ ๊ธฐํƒ€)์—์„œ ๊ท€ํ•˜์˜ ์˜๊ฒฌ์— ์‘๋‹ต:

๋‹น์‹ ์€ ๋งŽ์€ ์ข‹์€ ์ ์„ ์ง€์ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ๋ฌด์‹œํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ํ™•์‹คํžˆ ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์•„์ง ๋ชจ๋“  ๋‹ต์„ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด API๊ฐ€ ์–ด๋””์—์„œ ์ž‘๋™ํ•˜๊ณ  ์–ด๋””์—์„œ ๋ฌด๋„ˆ์ง€๋Š”์ง€ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์ด API๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ์ œ์•ˆํ•˜๋Š” ํด๋ž˜์Šค ๋ถ„๋ฅ˜๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ๋๋‚ด์•ผ ํ•  ์œ„์น˜์— ๊ฝค ๊ฐ€๊น๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋‹น์‹ (๊ทธ๋ฆฌ๊ณ  ๋ช‡๋ช‡ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค)์ด ํ…œํ”Œ๋ฆฟ ํ•ญ๋ชฉ์˜ StackLayouts ๋ฐ Grids(์ฆ‰, "BindableRepeater")๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋Š” ์ค‘๊ฐ„ ํด๋ž˜์Šค๋ฅผ ๊ฐ–๋Š” ๋ฐ ๋งค์šฐ ์—ด์ค‘ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ํƒ์ƒ‰ ์ค‘์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€ ์ค‘ ํ•˜๋‚˜๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@alexhardwicke

์ผ๋ฐ˜์ ์œผ๋กœ ์ƒˆ API์—์„œ๋Š” ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋™์ž‘์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์ง€์ ์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

๋ Œ๋”๋Ÿฌ์˜ UpdateX ๋ฉ”์„œ๋“œ๋Š” protected virtual ์ž…๋‹ˆ๋‹ค. :)

์ง„์ง€ํ•˜๊ฒŒ, ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์ด ๊ณผ๊ฑฐ์˜ ๊ณจ์นซ๊ฑฐ๋ฆฌ์˜€์Œ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ CollectionView ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋™์•ˆ ์ด๋ฅผ ์—ผ๋‘์— ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‹ค์‹œ ์ƒ๊ฐํ•ด ๋ณด๋ฉด CollectionView๊ฐ€ ์ด ๋ณด๊ธฐ์˜ ํด๋ž˜์Šค ์ด๋ฆ„์œผ๋กœ ์ข‹์€ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
    Windows XAML์—์„œ CollectionView๋Š” ๊ทธ๋ฃนํ™” ํ•„ํ„ฐ๋ง์— ์‚ฌ์šฉ๋˜๋Š” ํ•ญ๋ชฉ์˜ ๋ฐ์ดํ„ฐ ์›๋ณธ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. https://msdn.microsoft.com/en-us/library/system.windows.data.collectionview(v=vs . 110).aspx
    ์•„๋งˆ๋„ ์–ด๋Š ์‹œ์ ์—์„œ Xamarin Forms๋Š” ๋™์ผํ•œ ๋ชฉ์ ์„ ์œ„ํ•œ ํด๋ž˜์Šค๋ฅผ ๊ฐ–๊ฒŒ ๋  ๊ฒƒ์ด๋ฉฐ, ํŠนํžˆ XAML Standard์— ๋Œ€ํ•ด ์ƒ๊ฐํ•  ๋•Œ ๋™์ผํ•œ ์ด๋ฆ„(CollectionView)์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์˜๋ฏธ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์•„์ง๋„ ๊ณ„ํš๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?).

    ๋ณด๊ธฐ ํ‰ํ•˜๊ณ  ์žฌ๋ฏธ์žˆ์ง€๋งŒ ListView2๊ฐ€ ์ข‹์€ ์„ ํƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด ์ด๋ฆ„์ด ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ์œ ์ผํ•œ ์ด๋ฆ„์ธ ๊ฒฝ์šฐ ๋ฒ„์ „ ๊ด€๋ฆฌ์— ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด .NET์—์„œ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

    ๊ธฐ์กด API์˜ ์ƒˆ ๋ฒ„์ „์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•ด ์ˆซ์ž ์ ‘๋ฏธ์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ํŠนํžˆ API์˜ ๊ธฐ์กด ์ด๋ฆ„์ด ์œ ์ผํ•˜๊ฒŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ์ด๋ฆ„์ธ ๊ฒฝ์šฐ(์ฆ‰, ์‚ฐ์—… ํ‘œ์ค€์ธ ๊ฒฝ์šฐ) ์˜๋ฏธ ์žˆ๋Š” ์ ‘๋ฏธ์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ(๋˜๋Š” ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ) name)์€(๋Š”) ์ ์ ˆํ•œ ์˜ต์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค.

    _ํ”„๋ ˆ์ž„์›Œํฌ ๋””์ž์ธ ์ง€์นจ: ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ .NET ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ๊ทœ์น™, ๊ด€์šฉ๊ตฌ ๋ฐ ํŒจํ„ด, 2ํŒ_
    https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/general-naming-conventions

    ๋‚˜์ค‘์— ์–ด๋Š ์‹œ์ ์—์„œ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด ์ƒˆ๋กญ๊ณ  ๋ฐ˜์ง์ด๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ด๊ณ  ์„ฑ๋Šฅ์ด ์ข‹์€ ListView2 :). ๋นจ๋ฆฌ ๊ฐ๊ธฐ, ๋น„๋ก ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ListView2์˜ ์ด๋ฆ„์„ ListView๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๊ฐ„๋‹จํ•˜๊ณ  ํ™˜์˜๋ฐ›๋Š” ๋ฆฌํŒฉํ† ๋ง์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  2. Xamarin Forms์—๋Š” ์ด๋ฏธ ItemsView๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.ํ•ญ๋ชฉ ๋ ˆ์ด์•„์›ƒ ์†์„ฑ์ด ์—†๋‹ค๋Š” ์ ์„ ์ œ์™ธํ•˜๋ฉด Windows XAML์˜ ItemsControl๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.
    ์ƒˆ CollectionView ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹  ๊ธฐ์กด ItemsView๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?๋˜ํ•œ ์ƒˆ ListView์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋กœ?

  3. API ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„์—๋Š” ๋ชฉ๋ก ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•˜์ง€๋งŒ ๋‹จ์ˆœํ•˜๊ณ  ๊ฐ€๋ณ๊ณ  ์Šคํฌ๋กคํ•  ์ˆ˜ ์—†๊ณ  ์Šคํฌ๋กคํ•  ์ˆ˜ ์—†๋Š” ํ•ญ๋ชฉ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ "BindableRepeater"์™€ ๊ฐ™์€ ๊ฒƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ์žˆ๋Š” ๊ธฐ๋ณธ ํ”Œ๋žซํผ ์ปจํŠธ๋กค์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ๋œ ๋ช…๋ฐฑํ•œ ๋„์ „์ด ์žˆ์Šต๋‹ˆ๋‹ค. -์„ ํƒ ๊ฐ€๋Šฅํ•œ ํ•ญ๋ชฉ ๋ชฉ๋ก.
    Uno๊ฐ€ ํ•ด๋‚ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ƒˆ CollectionView ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹  ๊ธฐ์กด ItemsView๋ฅผ ์ƒˆ ListView์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๊นŒ?

ItemsView<T> ๊ฐ€ ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. TemplatedItemsList . ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ด ์ƒˆ๋กœ์šด ์ปจํŠธ๋กค์—์„œ ํ”ผํ•˜๋ ค๊ณ  ํ•˜๋Š” cruft์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค.

๋‚˜์ค‘์— ์–ด๋Š ์‹œ์ ์—์„œ ๋ชจ๋“  ์‚ฌ๋žŒ๋“ค์ด ์ƒˆ๋กญ๊ณ  ๋ฐ˜์ง์ด๋Š” ๊ฒƒ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ด๊ณ  ์„ฑ๋Šฅ์ด ์ข‹์€ ListView2 :). ๋นจ๋ฆฌ ๊ฐ๊ธฐ, ๋น„๋ก ๋ธŒ๋ ˆ์ดํ‚น ์ฒด์ธ์ง€์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ListView2์˜ ์ด๋ฆ„์„ ListView๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๊ฐ„๋‹จํ•˜๊ณ  ํ™˜์˜๋ฐ›๋Š” ๋ฆฌํŒฉํ† ๋ง์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ ๋‚™๊ด€์ฃผ์˜๋Š” ๋งค๋ ฅ์ ์ด์ง€๋งŒ ListView(1)์ด ์˜์›ํ•˜๊ณ  ListView2 ์ด๋ฆ„ ๋ฐ”๊พธ๊ธฐ์™€ ๊ฐ™์€ ์ฃผ์š” ๋ณ€๊ฒฝ์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฐ€์ • ํ•˜์— ์ž‘์—…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Windows XAML๊ณผ ๋™๋“ฑํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์ƒˆ ์ปจํŠธ๋กค์ด ์•ฝ์†์„ ์ง€ํ‚ค๋Š” ํ•œ ์›ํ•˜๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. Uno ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฏ€๋กœ ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์ด Xamarin Forms์—์„œ ๋ฌด์—‡์„ ๊ฐ€์ ธ์˜ค๊ณ  ์žˆ๋Š”์ง€ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@gmwilhelm

https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment -400925994

์ข‹์€ ์ง€์ . API์— ์ž ์ •์ ์œผ๋กœ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. iOS์™€ Android์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์™„์ „ํžˆ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž ์ •์ ์œผ๋กœ ๋งํ•˜์ง€๋งŒ UWP๋Š” ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ด๊ณ  ์œ ์พŒํ•˜๊ฒŒ ๋Œ€์นญ์ ์ด๋ผ๋Š” ๊ฒƒ์„ ๋ถ€์ •ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

GroupItemsBinding ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ListView์™€ ๊ฐ™์ด ๊ทธ๋ฃน์ด ์ปฌ๋ ‰์…˜ ์—์„œ ํŒŒ์ƒ๋˜๋„๋ก ์š”๊ตฌํ•˜๋Š” ๋Œ€์‹  Group์— ์ปฌ๋ ‰์…˜ ์œ ํ˜• ์†์„ฑ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค . ์ด ๊ธฐ์กด ListView ์ œํ•œ์œผ๋กœ ์ธํ•ด ์—ฌ๋Ÿฌ ๊ฒฝ์šฐ์— ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ์„ฑ๋Šฅ์ด ๋งŽ์ด ์†Œ๋ชจ๋˜๋Š” ๋ณต์ œ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. GroupItemsBinding ์ถ”๊ฐ€ํ•˜๋ฉด ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ๋ณด๋‹ค ์œ ์—ฐํ•œ ๋งคํ•‘์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, GroupDisplayBinding ๋ฌธ์„œ์— ์‚ฌ์šฉ๋œ ์˜ˆ๋Š” ๋‹ค์Œ๊ณผ

```C#
class Group // Group์€ ObservableCollection์—์„œ ํŒŒ์ƒ๋  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
{
๊ณต๊ฐœ ๊ทธ๋ฃน(๋ฌธ์ž์—ด firstInitial) { FirstInitial = firstInitial; }

public string FirstInitial { get; private set; }

public ObservableCollection<Person> Persons { get; set; } // We use a property for the group items instead

}

๋ชฉ๋ก ๋ณด๊ธฐ ๋งŒ๋“ค๊ธฐ ๋ชฉ๋ก ๋ณด๊ธฐ()
{
var listView = ์ƒˆ๋กœ์šด ListView {
GroupItemsBinding = ์ƒˆ ๋ฐ”์ธ๋”ฉ(nameof(Group.Persons))
// ...
};
// ...
}

```

์ด๊ฒƒ์ด UICollectionView๊ฐ€ ๋ ˆ์ด์•„์›ƒ ์ธก๋ฉด์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ž„์„ ๊ฐ์•ˆํ•  ๋•Œ ์ปจํŠธ๋กค์˜ ๊ธฐ๋Šฅ๊ณผ ํ˜ผ๋™์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ช…ํ™•ํžˆํ•˜๊ธฐ ์œ„ํ•ด์ด ์ปจํŠธ๋กค์€ ์•„์ง ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํ•ฉ๋‹ˆ๊นŒ? ์ฐธ์กฐํ•˜๋ ค๊ณ  ํ–ˆ์ง€๋งŒ ํ”„๋กœ์ ํŠธ์—์„œ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@titonton ์ด๊ฒƒ์€ CollectionView์— ๋Œ€ํ•œ ์‚ฌ์–‘์„ ๋…ผ์˜ํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ์ œ์ด๋ฉฐ ๊ตฌํ˜„์ด ์•„์ง ์‹œ์ž‘๋˜์ง€๋„ ์•Š์•˜์œผ๋ฉฐ ์‚ฌ์–‘์ด ํ™•์ •๋  ๋•Œ๊นŒ์ง€ ๊ทธ๋Ÿด ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@AmrAlSayed0 ์‚ฌ์‹ค 11์ผ ์ „์— "Sprint 139์—์„œ ์ง„ํ–‰ ์ค‘"์œผ๋กœ ์ด๋™ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹œ์ž‘ํ–ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

API์— ๋Œ€ํ•œ ๊ฒฐ์ •์ด ๋ฌด์—‡์ธ์ง€ ๋ช…ํ™•ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์‹œ์ž‘๋˜์—ˆ๋Š”์ง€๋Š” ๋งค์šฐ ๋ถˆ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.

@opcodewriter ๊ทธ๊ฒŒ ๋‚ด๊ฐ€ ์ƒ๊ฐํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. @AmrAlSayed0 ์„ค๋ช… ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ ์ด ์‚ฌ์–‘์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋ช…ํ™•ํžˆ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

@migueldeicaza @hartez ์ด๋ฆ„์„ CollectionView ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ค์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. CatalogView ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

1

์นดํƒˆ๋กœ๊ทธ๋Š” ์ข…์ข… ํ•˜๋‚˜ ์ด์ƒ์˜ ์—ด๊ณผ ์œ ์‚ฌํ•œ ๊ธ€๊ผด, ํ…์ŠคํŠธ, ๋ ˆ์ด์•„์›ƒ ๋“ฑ์„ ๊ฐ€์ง„ ์—ฌ๋Ÿฌ ํ–‰์˜ ํ•ญ๋ชฉ์œผ๋กœ ๋””์ž์ธ๋ฉ๋‹ˆ๋‹ค.

๊ฒฌ๋ณธ:

022

@hartez ์ด์ œ API๊ฐ€ ๊ฑฐ์˜ ์™„์„ฑ๋œ ๊ฒƒ ๊ฐ™๋‚˜์š”? ์ด์— ๋Œ€ํ•ด ์ง€๊ธˆ๊นŒ์ง€ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ ์ค‘ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ด ์ œ์–ด ๊ธฐ๋Šฅ์„ ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค. :)

@adrianknight89 ๋‚˜๋Š” ์ด๊ฒƒ์ด ์ž‘์—… ๋ถ„๊ธฐ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. https://github.com/xamarin/Xamarin.Forms/tree/lv2spike

์•„์ง ์ž ์‹œ ๋™์•ˆ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ๊ฐ€ ์ค€๋น„๋˜์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜์ง€๋งŒ ์ง„ํ–‰ ์ƒํ™ฉ์„ ํ™•์ธํ•˜๊ณ  ์ฆ‰๊ฐ์ ์ธ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์•ž์œผ๋กœ ๋ช‡ ์ฃผ ๋™์•ˆ ํ˜„์žฌ ๋…ธ๋ ฅ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜ ์‹œ์—ฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ์š”. ์ด๋ฏธ ๋‚ด๋ถ€ ๋ฐ๋ชจ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌํ˜„์— ๋Œ€ํ•ด์„œ๋Š” ์ด๋ฏธ ๊ฝค ๋ฉ€๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ๋งŽ์€ API๊ฐ€ ๊ณ ์ •๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ด์•ผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์—ฌ๊ธฐ API ์‚ฌ์–‘์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
ํ˜„์žฌ ์‚ฌ์–‘์ด ์—ฌ๊ธฐ์™€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ( https://github.com/xamarin/Xamarin.Forms/issues/1718) ์—์„œ ๋…ผ์˜๋œ ๋‚ด์šฉ์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๋” ์ •ํ™•ํ•˜๊ฒŒ ๋งํ•˜๋ฉด, API๋Š” ์Šคํฌ๋กคํ•  ์ˆ˜ ์—†๊ณ  ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅํ•œ StackLayout ๊ฐ™์€ ์ปจํŠธ๋กค์„ ํ—ˆ์šฉํ•  ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์œ ์—ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ƒˆ ์ปจํŠธ๋กค์„ ์‚ฌ์šฉํ•˜๋ฉด StackLayout์ฒ˜๋Ÿผ ์Šคํฌ๋กค๋ฐ” ์—†์ด ๋ฌถ์ธ ํ•ญ๋ชฉ์„ ์Šคํƒ์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ค๋žซ๋™์•ˆ ๊ธฐ๋‹ค๋ ค ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ‘

๋งŽ์€ ๋‚ด๋ถ€ ํ† ๋ก ๊ณผ ์ ์ ˆํ•œ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ ์‹œ๋„ ๋์— ์šฐ๋ฆฌ๋Š” CollectionView๊ฐ€ #1718์—์„œ ๋…ผ์˜๋œ ๋ ˆ์ด์•„์›ƒ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ _์•Š์„_ ๊ฒƒ์ด๋ผ๊ณ  ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, Xamarin.Forms ๋ ˆ์ด์•„์›ƒ์˜ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ๊ฐœ์ฒด ์ปฌ๋ ‰์…˜์˜ ๋ฐ”์ธ๋”ฉ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

CollectionView์˜ ์›๋ž˜ ๋ชฉํ‘œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค์–‘ํ•œ ์ตœ์‹  ๊ธฐ๋ณธ ๋ชฉ๋ก/๊ทธ๋ฆฌ๋“œ ์ปจํŠธ๋กค(UICollectionView, RecyclerView, ListView/GridView ๋“ฑ)์„ ์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

Forms Layouts(FlexLayout, StackLayout, etc. ). ๊ทธ๋ฆฌ๊ณ  ๋ช‡ ๊ฐ€์ง€ ๋ช…๋ฐฑํ•œ ๊ธฐ๋Šฅ ์ค‘๋ณต์ด ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๋‘ ์‹œ๋‚˜๋ฆฌ์˜ค ๋ชจ๋‘ DataTemplate ์‚ฌ์šฉ). ๊ทธ๋Ÿฌ๋‚˜ ๊ฒฐ๊ตญ์—๋Š” ๊ทผ๋ณธ์ ์ธ ์•„ํ‚คํ…์ฒ˜ ์ฐจ์ด๊ฐ€ ํฌ๋ฉฐ ํ•จ๊ป˜ ๋ณผํŠธ๋กœ ๋ฌถ์œผ๋ ค๊ณ  ํ•˜๋ฉด ๋‹จ์ˆœํžˆ ๋ณ„๋„์˜ ์ปจํŠธ๋กค๋กœ ๋‘๋Š” ๊ฒƒ๋ณด๋‹ค ์œ ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๋” ์–ด๋ ต๊ณ  ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ช‡ ๋…„ ์•ˆ์— ListView3๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๋ณต์žกํ•œ ๊ฒƒ์„ ๋งŒ๋“ค๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์˜ ๊ฒฐ๊ณผ๋Š” CollectionView๊ฐ€ Forms ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋ณธ ๋ชฉ๋ก/๊ทธ๋ฆฌ๋“œ ์ปจํŠธ๋กค์„ ํ™œ์šฉํ•˜๊ณ  ๋ ˆ์ด์•„์›ƒ ์—”์ง„๊ณผ ๊ฐ€์ƒํ™”์˜ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋ฌธ์ œ์— ๊ณ„์† ์ดˆ์ ์„ ๋งž์ถœ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  #1718์€ Forms ์‚ฌ์šฉ์ž๊ฐ€ ItemsSource ๋ฐ ItemTemplate ๋ฅผ ๋‹ค์–‘ํ•œ Forms Layout ์—”์ง„์— ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” API๋ฅผ ๋ฐ˜์˜ํ•˜๋„๋ก ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

๋‘ ์ปจํŠธ๋กค ๋Œ€ ํ•˜๋‚˜์˜ _์ด์œ _์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด:

์—ฌ๊ธฐ์— ์„ค๋ช…๋œ ๊ฒƒ(CollectionView๋กœ)๊ณผ #1718์˜ ์ œ์•ˆ ๊ฐ„์˜ ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด์ ์€ ๋ ˆ์ด์•„์›ƒ์ด ๋ฐœ์ƒํ•˜๋Š” _where_์ž…๋‹ˆ๋‹ค.

CollectionView๋Š” ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ์—”์ง„(ํ”Œ๋žซํผ ๊ฐœ๋ฐœ์ž์— ์˜ํ•ด ํฌ๊ฒŒ ์ตœ์ ํ™”๋จ)์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์ด์•„์›ƒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค. Forms์˜ ์ผ๋ถ€ ์‚ฌ์šฉ์ž ์ •์˜ ์ฝ”๋“œ๊ฐ€ ๊ด€๋ จ๋˜์ง€๋งŒ(์˜ˆ: Android ๋ฐ iOS์—์„œ SnapPoints ๋กœ์ง๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ) ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ์—”์ง„(๋ฐ ๊ธฐ๋ณธ ๊ฐ€์ƒํ™” ๊ตฌํ˜„)์ด ๋ฌด๊ฑฐ์šด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์„ฑ๋Šฅ๊ณผ ๊ด€๋ จํ•˜์—ฌ ํฐ ์ฐจ์ด๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ CollectionView์— ์ œ๊ณตํ•˜๋Š” ๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋Š” ํ•ด์„์„ ์œ„ํ•ด ๊ฐ ํ”Œ๋žซํผ์˜ ๋ Œ๋”๋Ÿฌ์— ์ „๋‹ฌ๋  ๋ฟ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํšจ๊ณผ์ ์œผ๋กœ ํ˜„์ง€ ์–ธ์–ด๋กœ ๋ฒˆ์—ญ๋˜๋Š” ์‚ฌ์–‘์ž…๋‹ˆ๋‹ค(Android์˜ LinearLayoutManager/GridLayoutManager, iOS์˜ UICollectionViewFlowLayout ๋“ฑ). DataTemplate ์™ธ์— Forms๋Š” ๋ ˆ์ด์•„์›ƒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋Œ€์กฐ์ ์œผ๋กœ, Forms ๋ ˆ์ด์•„์›ƒ(FlexLayout, StackLayout, AbsoluteLayout ๋“ฑ)์€ ์™„์ „ํžˆ Forms ๋ ˆ์ด์–ด์— ๋ฐฐ์น˜๋ฉ๋‹ˆ๋‹ค. Forms Layout์˜ ๋ Œ๋”๋Ÿฌ๋Š” ๊ฑฐ์˜ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ƒํ™”๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ํ•ญ๋ชฉ์ด ์ƒ์„ฑ๋˜์–ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ ˆ์ด์•„์›ƒ์— ๋ฐฐ์น˜๋ฉ๋‹ˆ๋‹ค.

์ด ๋‘ ๊ฐ€์ง€๋ฅผ ๊ฒฐํ•ฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์–ด๋ ค์šด ์งˆ๋ฌธ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

  1. ๋ Œ๋”๋Ÿฌ ๋งคํ•‘์€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? StackLayout์„ ์‚ฌ์šฉํ•˜๋Š” CollectionView์—๋Š” RecyclerView๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” CollectionView์™€ ๋งค์šฐ ๋‹ค๋ฅธ ๋ Œ๋”๋Ÿฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์„ ํ•จ๊ป˜ ๋งค์‰ฌํ•˜๊ณ  ํ•„์š”ํ•˜์ง€ ์•Š์„ ๋•Œ RecyclerView๋ฅผ ์ˆจ๊น๋‹ˆ๊นŒ? DefaultRenderer์—์„œ ํŒŒ์ƒ๋œ ๋ Œ๋”๋Ÿฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹ค์ œ๋กœ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ถ”๊ฐ€ ViewGroup ๋ ˆ์ด์–ด๊ฐ€ ํ•ญ์ƒ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ScrollView๋ฅผ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๊นŒ? UICollectionView๋Š” ์ž์ฒด ์Šคํฌ๋กค ํ‘œ์‹œ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€๋งŒ StackLayout์ด ์Šคํฌ๋กคํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ Forms์— ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์Šคํฌ๋กค์„ ์ž๋™์œผ๋กœ ์‚ฝ์ž…ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ๋ ˆ์ด์–ด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๊นŒ? ๋ ˆ์ด์•„์›ƒ์ด UICollectionView๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ•œ ScrollView๋ฅผ ๋น„ํ™œ์„ฑํ™”/์ œ๊ฑฐํ•ฉ๋‹ˆ๊นŒ?

  3. ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•ด ScrollTo ๋ฉ”์„œ๋“œ๋Š” ์–ด๋””๋กœ ์ด๋™ํ•ฉ๋‹ˆ๊นŒ?

... ๋“ฑ๋“ฑ. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๋ฌธ์ œ๋Š” _ํ•ด๊ฒฐ ๊ฐ€๋Šฅ_ํ•˜์ง€๋งŒ ๋ชจ๋“  ์†”๋ฃจ์…˜์€ _๋ณต์žก์„ฑ_์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  #1718์—์„œ ์ง€์ ํ–ˆ๋“ฏ์ด Forms Layout์— ItemsSource ๋ฐ ItemsTemplate์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋ฆฌ ์–ด๋ ต๊ฑฐ๋‚˜ ๋ณต์žกํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋‘ ๊ฐ€์ง€ ๋ณ„๊ฐœ์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ฒฐํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์ด์ ์„ ๋ˆ„๋ฆด ๊ฐ€์น˜๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ์š”. ์ด๋ฏธ ๋‚ด๋ถ€ ๋ฐ๋ชจ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ตฌํ˜„์— ๋Œ€ํ•ด์„œ๋Š” ์ด๋ฏธ ๊ฝค ๋ฉ€๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งŽ์€ API๊ฐ€ ๊ณ ์ •๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ด์•ผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ์—ฌ๊ธฐ API ์‚ฌ์–‘์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์—ฌ๊ธฐ์— ๊ฒŒ์‹œ๋œ API๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. "์•„์ฃผ ๋ฉ€๋ฆฌ"๋Š” ์•„๋งˆ๋„ ๊ณผ์žฅ๋œ ํ‘œํ˜„์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์–‘์˜ ๋…ผ์Ÿ์˜ ์—ฌ์ง€๊ฐ€ ์—†๋Š” ๋ถ€๋ถ„ ์ค‘ ์ผ๋ถ€๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๊ณ  ๋ง‰๋‹ค๋ฅธ ๊ณจ๋ชฉ์œผ๋กœ ๊ฐ€์ง€ ์•Š์„ ๊ฒƒ์ž„์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด ์ง€๊ธˆ๊นŒ์ง€ ๊ตฌํ˜„ํ•œ ๊ฒƒ ์ค‘ ๋งŽ์€ ๋ถ€๋ถ„์ด ๋ฆด๋ฆฌ์Šค ๋ฒ„์ „์— ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์–‘์˜ ๋ชจ๋“  ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ๊ตฌํ˜„ํ•œ ๋ชจ๋“  ๊ฒƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—ฌ์ „ํžˆ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์‚ฌ์–‘์ด ์—ฌ๊ธฐ์™€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ #1718์—์„œ ๋…ผ์˜๋œ ๋‚ด์šฉ์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋” ์ •ํ™•ํ•˜๊ฒŒ ๋งํ•˜๋ฉด, API๋Š” ์Šคํฌ๋กคํ•  ์ˆ˜ ์—†๊ณ  ๋ฐ”์ธ๋”ฉ ๊ฐ€๋Šฅํ•œ StackLayout ๊ฐ™์€ ์ปจํŠธ๋กค์„ ํ—ˆ์šฉํ•  ๋งŒํผ ์ถฉ๋ถ„ํžˆ ์œ ์—ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค์ด๋ฉฐ, ์šฐ๋ฆฌ๊ฐ€ ์ž‘์—…ํ•œ ๊ฒƒ ์ค‘ ์ผ๋ถ€๋Š” CollectionView๊ฐ€ ์ด๋Ÿฌํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ํ•ฉ๋ฆฌ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๊ฒฐ์ •์„ ๋‚ด๋ ธ์Šต๋‹ˆ๋‹ค. https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment -424413234๋ฅผ ์ฐธ์กฐ

์ด๊ฒƒ์ด UICollectionView๊ฐ€ ๋ ˆ์ด์•„์›ƒ ์ธก๋ฉด์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž‘์—…์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ž„์„ ๊ฐ์•ˆํ•  ๋•Œ ์ปจํŠธ๋กค์˜ ๊ธฐ๋Šฅ๊ณผ ํ˜ผ๋™์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด(https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment-401186893), ์ €๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์นดํƒˆ๋กœ๊ทธ๋ทฐ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์นดํƒˆ๋กœ๊ทธ๋Š” ์ข…์ข… ํ•˜๋‚˜ ์ด์ƒ์˜ ์—ด๊ณผ ์œ ์‚ฌํ•œ ๊ธ€๊ผด, ํ…์ŠคํŠธ, ๋ ˆ์ด์•„์›ƒ ๋“ฑ์„ ๊ฐ€์ง„ ์—ฌ๋Ÿฌ ํ–‰์˜ ํ•ญ๋ชฉ์œผ๋กœ ๋””์ž์ธ๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ํฅ๋ฏธ๋กœ์šด ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. ํ™•์‹คํžˆ ๊ธฐ์กด ์ปจํŠธ๋กค ์ด๋ฆ„๊ณผ ์ถฉ๋Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@hartez Xamarin Forms์˜ ๋‚ด๋ถ€์— ์ ์  ๋” ์ต์ˆ™ํ•ด์ง€๊ณ  ์žˆ๋Š”(๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ UITableView ๋ฐ UICollectionView์— ๋Œ€ํ•ด ๊ฝค ์นœ์ˆ™ํ•ด์ง„) ์ธํ„ฐ๋„ท์˜ ์ž„์˜์˜ ์‚ฌ๋žŒ์œผ๋กœ์„œ ์ด๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ์›€์ง์ž„์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ๋ ˆ์ด์•„์›ƒ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์—ฌ์ „ํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ(ํ”Œ๋žซํผ๋ณ„๋กœ ๋ณ„๋„์˜ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋”๋ผ๋„)?

์‚ฌ์šฉ์ž ์ •์˜ ๋ ˆ์ด์•„์›ƒ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์—ฌ์ „ํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ(ํ”Œ๋žซํผ๋ณ„๋กœ ๋ณ„๋„์˜ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋”๋ผ๋„)?

์ „์ ์œผ๋กœ. IItemsLayout์œผ๋กœ ํ‘œ์‹œ๋œ ๊ณ ์œ ํ•œ ๋ ˆ์ด์•„์›ƒ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž ์ง€์ • ๋ Œ๋”๋Ÿฌ๋Š” ์›ํ•˜๋Š” ๋Œ€๋กœ ํ•ด์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐœ๋… ์ฆ๋ช…์œผ๋กœ CollectionView์šฉ Android ๋ Œ๋”๋Ÿฌ๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฅ˜ํ•˜๊ณ  Flex Layout ์†์„ฑ์ด ํฌํ•จ๋œ FlexLayout : IItemsLayout ํด๋ž˜์Šค๋ฅผ ํ•ด์„ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์†์„ฑ์„ Google์˜ FlexBoxLayoutManager์— ์ „๋‹ฌ ํ•˜๊ณ  ํ•ด๋‹น ๋ ˆ์ด์•„์›ƒ ๊ด€๋ฆฌ์ž๋ฅผ RecyclerView์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ฐœ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ์˜ˆ์ œ๋ฅผ GitHub์— ๊ฒŒ์‹œํ•˜์—ฌ ์‚ฌ๋žŒ๋“ค์ด ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์‰ฌ์šด ์ฐธ์กฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชฉํ‘œ๋Š” ์ด๊ฒƒ์„ ๋งค์šฐ ์œ ์—ฐํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@hartez
https://github.com/xamarin/Xamarin.Forms/issues/3749์— ์„ค๋ช…๋œ ๋ฌธ์ œ๊ฐ€ CollectionView๋กœ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๊นŒ?
์—ฌ๊ธฐ์„œ CollectionView ์—๋Š” ItemTemplate ์†์„ฑ๋งŒ ์žˆ๋Š” ๊ฒƒ์„ ๋ณด์•˜๊ธฐ ๋•Œ๋ฌธ์— ListView ์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

@hartez
CollectionView๋กœ #3749์— ์„ค๋ช…๋œ ๋ฌธ์ œ๊ฐ€ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๊นŒ?
์—ฌ๊ธฐ์„œ CollectionView ์—๋Š” ItemTemplate ์†์„ฑ๋งŒ ์žˆ๋Š” ๊ฒƒ์„ ๋ณด์•˜๊ธฐ ๋•Œ๋ฌธ์— ListView ์™€ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค.

@andreinitescu ๊ทธ ํ† ๋ก ์„ ์ง€์ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” DataTemplate์—์„œ ์ด ๋ฌธ์ œ๋ฅผ ์•Œ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋‹ค์Œ ์ฃผ์— DataTemplate์˜ ์—ญ์‚ฌ๋ฅผ ์‚ดํŽด๋ณด๋Š” ๋ฐ ์‹œ๊ฐ„์„ ํ• ์• ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. DataTemplate์ด ์™œ ์ด๋Ÿฐ ์‹์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์ž๋™์œผ๋กœ ์˜ฌ๋ฐ”๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก CreateContent ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€(๋‘˜ ๋‹ค ListView ๋ฐ CollectionView).

@hartez ๋‚ด ์ž์‹ ์˜ ๋ฆฌํ”ผํ„ฐ ์ปจํŠธ๋กค์„ ๋งŒ๋“ค ๋•Œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ๋ฐฉ๋ฒ•์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค.

// ํ…œํ”Œ๋ฆฟ ์„ ํƒ๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€ ๋˜๋Š” ํ…œํ”Œ๋ฆฟ๋งŒ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
var templateToUse = itemTemplate์€ DataTemplateSelector templateSelector์ž…๋‹ˆ๊นŒ? templateSelector.SelectTemplate(ํ•ญ๋ชฉ, null) : itemTemplate;

๋”ฐ๋ผ์„œ ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ CreateContent๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๊ณ  ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ItemTemplate๊ณผ ItemTemplateSelector๋ฅผ ๋ณ„๋„์˜ ์†์„ฑ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ด์ƒ์ ์ด๋ผ๋Š” @andreinitescu์˜ ์˜๊ฒฌ์—๋Š” ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ œ WPF ๋ฐ SL ๋ฐฐ๊ฒฝ ๋•Œ๋ฌธ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@bmacombe IMHO, WPF/SL์— ๋งž๊ฒŒ ์ •๋ ฌํ•˜๋Š” ๊ฒƒ์€ ์„ ํ˜ธ๋„์˜ ๋ฌธ์ œ์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‹ค์ œ๋กœ ๋ฌธ์ œ์ด๋ฉฐ ํ˜ผ๋ž€์„ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค. #3544 ์ฐธ์กฐ

@andreinitescu ํ˜ผ๋ž€์„

CollectionView์—์„œ ์Šคํฌ๋กค ์ด๋ฒคํŠธ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? CollectionView๊ฐ€ ์ถœ์‹œ๋  ๋•Œ๊นŒ์ง€ ListView https://github.com/xamarin/Xamarin.Forms/issues/4323์— ๋Œ€ํ•œ ์ œ์•ˆ์ด

๊ทธ๋ฆฌ๊ณ  ์˜ˆ๋ฅผ ๋“ค์–ด PInterest์™€ ๊ฐ™์€ ๋ถˆ๊ทœ์น™ํ•˜๊ณ  ๋™์ ์ธ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  ์ด๋ฏธ์ง€์—๋Š” ๊ณ ์œ ํ•œ ๋†’์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค :-)

์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋ ˆ์ด์•„์›ƒ์ด ์ง€์›๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹ ์ด ์„œ์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

image

์—…๋ฐ์ดํŠธ: ์ด๋ฆ„ ์ œ์•ˆ ๋ชฉ๋ก์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์€ "ItemsView"์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๊ฒƒ์ด iOS "UICollectionView"๋งŒํผ ์™„์ „ํ•˜๋‹ค๋Š” ์ธ์ƒ์„ ์ฃผ๋Š” "CollectionView"๋ผ๋Š” ์šฉ์–ด์˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” ์—ฌ์ „ํžˆ Xamarin์„ ์ฒ˜์Œ ์‚ฌ์šฉํ•˜์ง€๋งŒ DataTemplateSelector๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ListView๋กœ ์ž‘์—…ํ•ด ์™”์Šต๋‹ˆ๋‹ค.
DataTemplateSelector์™€ ํ•จ๊ป˜ CollectionView๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ ์˜ˆ์™ธ:

System.InvalidOperationException: LoadTemplate์ด null์ด ์•„๋‹ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

DataTemplateSelector์™€ ๊ด€๋ จ๋œ ์•Œ๋ ค์ง„ ๋ฒ„๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ž˜๋ชป ๊ตฌํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CollectionView์™€ ํ•จ๊ป˜ DataTemplateSelector๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@hartez @davidortinau KeepItemsInView ๊ฐ€ KeepLastItemInView ์™€ ์ •๋ ฌ๋˜๋„๋ก KeepFirstItemInView ๋กœ ๋ช…๋ช…๋˜์ง€ ์•Š์€ ์ด์œ ๊ฐ€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ํ˜„์žฌ ์ด๋ฆ„์€ ๋ณต์ˆ˜ํ˜•(์ฆ‰, ์—ฌ๋Ÿฌ ํ•ญ๋ชฉ์„ ์ œ์•ˆํ•จ)์ธ ๋ฐ˜๋ฉด ์„ค๋ช…์—๋Š” ๋ทฐํฌํŠธ์—์„œ ๋ณด์ด๋Š” ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งŒ ์œ ์ง€ํ•œ๋‹ค๊ณ  ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ํ˜„์žฌ ๋ทฐํฌํŠธ์— ์žˆ๋Š” ๋ทฐ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด API๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค๋ฅธ ๋ฐค์— ListView ์…€์— ์‚ฝ์ž…ํ•˜๊ณ  ๋ทฐํฌํŠธ ๊ฐ€์‹œ์„ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž๋™ ์žฌ์ƒ/์ผ์‹œ ์ค‘์ง€๋˜๋Š” ๋น„๋””์˜ค ๋ณด๊ธฐ๋ฅผ ๋งŒ๋“œ๋Š” ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์—ˆ์ง€๋งŒ ํ˜„์žฌ ItemAppearing ๋ฐ ItemDisappearing ์—์„œ๋Š” ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค CollectionView ๋ณด๋‹ค ์•ˆ์ •์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๊ธฐ๋Šฅ์„ ์ง€์›.

autoplayvideos demo

๋˜ ๋‹ค๋ฅธ ์ข‹์€ ์ ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ˜„์žฌ ํ”ผ๋“œ๋ฅผ ์Šคํฌ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ๋™์•ˆ ๋ถ€๋ชจ๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ๋˜๋Š” ์ตœ์†Œํ™”๋œ ์ข…์† ๋ณด๊ธฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. YouTube์—์„œ ํ˜„์žฌ ๋™์˜์ƒ์„ ๊ณ„์† ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋™์‹œ์— ํƒ์ƒ‰์„ ๊ณ„์†ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด CollectionView ๊ฐ€ btw๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜ ์ง€์›ํ•ด์•ผ ํ•˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์ƒ๊ฐํ•ด ๋ณผ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

youtube1-5abab8210e23d9003787855d

๊ทธ๋ž˜์„œ ๋‚˜๋Š” ํ˜„์žฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋นŒ๋“œ์™€ ๋น„๊ตํ•˜์—ฌ ์ผ๋ถ€ ํฌ๊ธฐ ์กฐ์ • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ ํ˜„์žฌ ๋‚˜์ดํ‹€๋ฆฌ ๋นŒ๋“œ ๋น„ํŠธ(4.0.1.43780-nightly)๋ฅผ ๊ฐ€์ง€๊ณ  ๋†€์•˜์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์€ RowSpacing/ColumnSpacing ๋˜๋Š” GridSpacing๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ๋ณ„ ํ•ญ๋ชฉ์— ์—ฌ๋ฐฑ/ํŒจ๋”ฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•ญ๋ชฉ์˜ ๊ฐ„๊ฒฉ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์‰ฌ์›Œ์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ Padding ๋˜๋Š” EdgeOffset์„ CollectionView ๋˜๋Š” ๋ ˆ์ด์•„์›ƒ์— ์ถ”๊ฐ€ํ•˜์—ฌ ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋œ ํ•ญ๋ชฉ๊ณผ ๊ฐ™์€ ํ•ญ๋ชฉ์„ ์ž˜๋ผ๋‚ด๋Š” Margin ์‚ฌ์šฉ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
android-margin-image
Margin์€ ๋˜ํ•œ ์—ฌ๊ธฐ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Android์—์„œ "๋“œ๋ž˜๊ทธ" ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ž๋ฆ…๋‹ˆ๋‹ค.
android-margin

๋‚ด๊ฐ€ ์ œ์•ˆํ•˜๋Š” ๊ฒƒ์€ RowSpacing/ColumnSpacing ๋˜๋Š” GridSpacing๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ๋ณ„ ํ•ญ๋ชฉ์— ์—ฌ๋ฐฑ/ํŒจ๋”ฉ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•ญ๋ชฉ์˜ ๊ฐ„๊ฒฉ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์‰ฌ์›Œ์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ๋ ˆ์ด๋”์— ์žˆ์Šต๋‹ˆ๋‹ค. #4681 ์ฐธ์กฐ.

์—…๋ฐ์ดํŠธ: ์ด๋ฆ„ ์ œ์•ˆ ๋ชฉ๋ก์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฒƒ์€ "ItemsView"์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ด๊ฒƒ์ด iOS "UICollectionView"๋งŒํผ ์™„์ „ํ•˜๋‹ค๋Š” ์ธ์ƒ์„ ์ฃผ๋Š” "CollectionView"๋ผ๋Š” ์šฉ์–ด์˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

"FloatView"๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ItemAppearing/Disappearing ์ด๋ฒคํŠธ ์™ธ์—๋„ ํ•ญ๋ชฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ณ„ํš:
View GetView(object item)
ํ•ญ๋ชฉ์ด ๊ตฌ์ฒดํ™”๋˜์ง€ ์•Š์œผ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜์ง ๋ชฉ๋ก์„ ์‚ฌ์šฉ ํ•˜๊ณ  ์žˆ๋Š”๋ฐ iOS์™€ Android์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ๋ฐฉ์‹์— ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

iOS์—์„œ ๋ ˆ์ด๋ธ”์€ ๋„ˆ๋น„์˜ 100%๋ฅผ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.
screenshot 2019-01-15 13 56 01

Android์—์„œ๋Š” ์ฝ˜ํ…์ธ  ๋„ˆ๋น„๋งŒ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.
screenshot 2019-01-15 13 57 59

์ •์  ๋„ˆ๋น„ ์ •์˜๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋ ˆ์ด์•„์›ƒ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
Grid Width="Auto" ์†์„ฑ์„ ์กด์ค‘ํ•˜๋Š” Android ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ˆ˜์ง ๋ชฉ๋ก์„ ์‚ฌ์šฉ ํ•˜๊ณ  ์žˆ๋Š”๋ฐ iOS์™€ Android์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ๋ฐฉ์‹์— ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@shwanton ์ด ๋ฒ„๊ทธ์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ์ด์Šˆ๋ฅผ ์—ด์–ด ์ฃผ์‹œ๋ฉด ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@shwanton ์•ผ๊ฐ„ ํ”ผ๋“œ๋กœ ์ „ํ™˜ํ–ˆ์„ ๋•Œ ์ˆ˜์ •๋œ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@krdmllr ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ๋นŒ๋“œ์—์„œ ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•. ListView์˜ ItemTapped์™€ ์œ ์‚ฌํ•œ ItemTapped ์ด๋ฒคํŠธ๊ฐ€ CollectionView์— ์žˆ์Šต๋‹ˆ๊นŒ? ์ŠคํŽ™์—๋Š” ์•ˆ๋ณด์ด๋„ค์š”. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@uvirra DataTemplateSelector ๋ฌธ์˜์— ๋Œ€ํ•œ ๊ธฐ์กด ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. #4826์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

@hartez ListView ๋Œ€ํ•ด ์กด์žฌํ•˜๋Š” ์„ธ ๊ฐ€์ง€์™€ ๊ฐ™์€ ํ’ˆ๋ชฉ ์žฌํ™œ์šฉ ์ „๋žต์ด ํ•„์š”ํ• ๊นŒ์š”? CollectionView ํ™œ์šฉํ•˜๋Š” ๊ธฐ๋ณธ ๊ฐ€์ƒํ™”์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ์–ธ๊ธ‰ํ•˜์…จ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

RefreshView ์ด iOS์—์„œ ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€ ์ €๋„ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ListView ๋Œ€ํ•œ ํ˜„์žฌ ์ƒˆ๋กœ ๊ณ ์นจ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด UITableView ์˜ Bounces ์†์„ฑ์ด ์ผœ์ ธ ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ Android์—์„œ๋Š” ์ƒˆ๋กœ ๊ณ ์นจ ๋ณด๊ธฐ๊ฐ€ ๊ฐ€์žฅ ๋งŽ์ด ๋ณด์ด๋Š” ํ•ญ๋ชฉ(์ด๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์„ ํ˜ธ).

@hartez ListView ๋Œ€ํ•ด ์กด์žฌํ•˜๋Š” ์„ธ ๊ฐ€์ง€์™€ ๊ฐ™์€ ํ’ˆ๋ชฉ ์žฌํ™œ์šฉ ์ „๋žต์ด ํ•„์š”ํ• ๊นŒ์š”? CollectionView ํ™œ์šฉํ•˜๋Š” ๊ธฐ๋ณธ ๊ฐ€์ƒํ™”์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ์–ธ๊ธ‰ํ•˜์…จ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋””์ž์ธ์€ ์žฌํ™œ์šฉ ์ „๋žต๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์š”๊ตฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์šฐ๋ฆฌ๋Š” ๊ธฐ๋ณธ ์ปจํŠธ๋กค์ด ์ œ๊ณตํ•˜๋Š” ๊ฐ€์ƒํ™”๋ฅผ ํ™œ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ ์ปจํŠธ๋กค์€ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ํฌ๋ง์€ "์•„๋‹ˆ์š”"์ด๋ฉฐ ๋งŽ์€ ๋ณต์žก์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— (์‚ฌ์šฉ์ž์™€ ์œ ์ง€ ๊ด€๋ฆฌ ๋ชจ๋‘) ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ตœ์„ ์„ ๋‹คํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ฒฐ๊ตญ ๊ทธ๋Ÿฐ ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฐ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ๋””์ž์ธ์— ๋งค์šฐ, ๋งค์šฐ ์กฐ์‹ฌ์Šค๋Ÿฝ๊ฒŒ ์ ‘๊ทผํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์Šคํฌ๋กค๋œ ์ด๋ฒคํŠธ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์ตœ์‹  UI/UX์˜ ๋Œ€๋ถ€๋ถ„์€ ์Šคํฌ๋กค ์‹œ ์‹œ์ฐจ ํ—ค๋”, ํ•ญ๋ชฉ ํ‘œ์‹œ/์ˆจ๊ธฐ๊ธฐ(๋ฒ„ํŠผ, ํ—ค๋”, ํ•„ํ„ฐ, ๊ธฐํƒ€ ๋“ฑ๋“ฑ)๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
์ด์™€ ๊ฐ™์€ ์ƒˆ๋กญ๊ณ  ๋†€๋ผ์šด ์ปจํŠธ๋กค์€ ์ตœ์‹  ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. recyclerview์™€ UICollectionview๋Š” ๋ชจ๋‘ ์Šคํฌ๋กค๋œ ์ด๋ฒคํŠธ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

Carouselview(collectionview ๊ธฐ๋ฐ˜)๋„ ๋ฐฉํ–ฅ, ์Šคํฌ๋กค ๊ฐ’ ๋ฐ ๋ธํƒ€๊ฐ€ ์žˆ๋Š” ์Šคํฌ๋กค ์ด๋ฒคํŠธ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. https://github.com/xamarin/Xamarin.Forms/issues/4996

์ด๊ฒƒ์€ ํ˜„๋Œ€์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ง€์›ํ•ด์•ผ ํ•˜๋Š” ์ƒˆ๋กญ๊ณ  ๋†€๋ผ์šด ์ปจํŠธ๋กค์ด๋ผ๋Š” @Evolutionlab ์˜ ์˜๊ฒฌ์„ ๋”ฐ๋ฅด๊ธฐ ์œ„ํ•ด ๋” ๋‚˜์€ ๊ฐ€์ƒํ™” ์ง€์›์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

https://docs.microsoft.com/en-us/windows/uwp/debug-test-perf/listview-and-gridview-data-optimization

์ด๊ฒƒ์ด ์ดํ•ดํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋งŽ๋‹ค๋ฉด ๋Œ€์‹  ViewModel์—์„œ ๊ฐ€์ƒํ™”๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก VisibleItems์— ์•ก์„ธ์Šคํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์•ž์œผ๋กœ๋„ ํž˜์จ์ฃผ์„ธ์š”!

@hartez ๊ฐœ๋ฐœ์ž๊ฐ€ ์„ ํƒํ•œ ํ•ญ๋ชฉ์˜ ์ˆ˜์— ๋Œ€ํ•œ ์ตœ์†Œ/์ตœ๋Œ€ ์ž„๊ณ„๊ฐ’์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ฉด ์ข‹์„ ๊ฑฐ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ 5์žฅ ์ด์ƒ์˜ ์‚ฌ์ง„์„ ์„ ํƒํ•  ์ˆ˜ ์—†๋„๋ก ๋งž์ถค ์‚ฌ์ง„ ๊ฐค๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ž„๊ณ„๊ฐ’์— ๋„๋‹ฌํ•˜๋ฉด ์…€์˜ ํƒญ ์ด๋ฒคํŠธ๊ฐ€ ํ•ญ๋ชฉ ์„ ํƒ์„ ์ทจ์†Œํ•˜์ง€ ์•Š๋Š” ํ•œ ๋ฌด์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ CurrentSelection ์นด์šดํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ SelectionChanged ์ด๋ฒคํŠธ์— SelectedItems (์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์Œ)๋ฅผ ์„ค์ •ํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ SelectionChanged ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋Š˜ CollectionView๋ฅผ ์กฐ๊ธˆ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด UWP๊ฐ€ Android์™€ iOS๋ณด๋‹ค ํ›จ์”ฌ ๋’ค์ณ์ ธ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ , ๊ทธ ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์™„๋ฃŒ๋˜๋ฉด ์ „์ฒด UWP๋ฅผ ์ง€์›ํ•  ๊ณ„ํš์ธ์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”?

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ItemAppearing/Disappearing ์ด๋ฒคํŠธ ์™ธ์—๋„ ํ•ญ๋ชฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ณ„ํš:
View GetView(object item)
ํ•ญ๋ชฉ์ด ๊ตฌ์ฒดํ™”๋˜์ง€ ์•Š์œผ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ItemAppearing์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๊ด€ํ•œ ์–ด๋–ค ๋‰ด์Šค๋„ ๋ณด์ง€ ์•Š๋Š”๋‹ค

๋‚˜๋Š” CollectionView ๊ฐ€์ง€๊ณ  ๋†€๋‹ค๊ฐ€ ๊ณ ๋ฅด์ง€ ์•Š์€ ํ–‰ ๋†’์ด ๋ฌธ์ œ์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ์— ItemSizingStrategy ๋„์ž…๋œ ๊ฒƒ์„ ๋ณด์•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ์ด์ƒํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

DataTemplateGallery ๊ฐ€์ง€๊ณ  ๋†€์•˜๊ณ  MeasureAllItems ์ „ํ™˜ํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค(iPhone 6, iOS 12.1.4).

์˜ค๋ฅธ์ชฝ์œผ๋กœ ์Šค์™€์ดํ”„ํ•˜๊ณ  ๋Œ์•„์˜ค๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.

@hartez ์ด๊ฒƒ์ด ์ž‘๋™ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๊ฑฐ๋‚˜ ๊ณ„์† ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๊นŒ(๋ฌธ์ œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ)?

RemainingItemsThresholdReached๊ฐ€ ์•„์ง ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

4.0.0.169046-pre5์˜ CollectionView ์ปจํŠธ๋กค XAML์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์•„๋ฌด๋„ RemainingItemsThresholdReached๊ฐ€ 4.0 ๋ฆด๋ฆฌ์Šค์˜ ์ผ๋ถ€๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ƒ˜ํ”Œ ์ฝ”๋“œ๋ฅผ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

@Dresel ์ด๊ฒƒ์ด ๋ฒ„๊ทธ๋ผ๊ณ  ์ƒ๊ฐ๋˜๋ฉด ์ƒˆ ํ‹ฐ์ผ“์„ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ถ”์ ๋˜๋ฉด ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

@melucas @chandrubk RemainingItemsThresholdReached ๋Š” ์•„์ง ์ž‘์—… ์ค‘์ธ ๊ฒƒ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

https://github.com/xamarin/Xamarin.Forms/branches/all

์ €๋„ ์ด ๊ธฐ๋Šฅ์ด ์—†์œผ๋ฉด CollectionView ๋ฅผ ๋งŒ์งˆ ์ˆ˜ ์—†๋Š” ์ฆ‰์‹œ ์ด ๊ธฐ๋Šฅ(์ƒˆ๋กœ ๊ณ ์นจ ๋ณด๊ธฐ์™€ ํ•จ๊ป˜)์ด ๊ตฌํ˜„๋˜๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

4323

ScrollView์™€ ๊ฐ™์€ Scrolled ์ด๋ฒคํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์•ˆ ์ธ์‚ฌ,

4323

ScrollView์™€ ๊ฐ™์€ Scrolled ์ด๋ฒคํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์•ˆ ์ธ์‚ฌ,

๋‚˜๋Š” ์ด๊ฒƒ์„ ์ง€์ง€ํ•œ๋‹ค.
๋˜ํ•œ ์Šคํฌ๋กค์ด ์ค‘์ง€/์™„๋ฃŒ๋˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์–ป์„ ์ˆ˜ ์žˆ๋„๋ก IOS์—์„œ UICollectionview์ด์žˆ๋Š” UIScrollView์˜ ํ•˜์œ„ ํด๋ž˜์Šค scrollViewDidEndDecelerating ๋กœ๋ถ€ํ„ฐ UIScrollViewDelegate

Android์—์„œ๋Š” RecyclerView.OnScrollListener ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ง€์ • ์ƒˆ๋กœ ๊ณ ์นจ, ์‹œ์ฐจ, ๋™๊ธฐํ™”๋œ ์Šคํฌ๋กค ์š”์†Œ, ๊ธฐํƒ€ ๋“ฑ๋“ฑ์— ๋Œ€ํ•œ ๋ณด๋‹ค ๊ณ ๊ธ‰์Šค๋Ÿฝ๊ณ  ์„ธ๋ จ๋œ ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ์—ด๋ฆฝ๋‹ˆ๋‹ค.

Recycler View์™€ ๊ฐ™์€ Android์šฉ ๊ธฐ๋ณธ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

Recycler View์™€ ๊ฐ™์€ Android์šฉ ๊ธฐ๋ณธ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์–ด๋–ค ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋ง์”€ํ•˜์‹œ๋Š” ๊ฑด๊ฐ€์š”? ์ด๋ฅผ ์œ„ํ•œ Android ๋ Œ๋”๋Ÿฌ๋Š” RecyclerView์— ๊ตฌ์ถ•๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ํ•ญ๋ชฉ ์ถ”๊ฐ€/์ œ๊ฑฐ์™€ ๊ฐ™์€ ์ž‘์—…์— ์ด๋ฏธ ๊ธฐ๋ณธ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•,

4.0.0.304370-pre8์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
(์•„๋ž˜ ๋งํฌ)์˜ ์˜ˆ์ œ๋Š” CarouselView๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ UWP์— ์•„๋ฌด ๊ฒƒ๋„ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ CollectionView๋Š” ๋ชฉ๋ก์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. UWP์šฉ CarouselView๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ํŠน์ • ๊ตฌ์„ฑ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

https://devblogs.microsoft.com/xamarin/xamarin-forms-4-0-feature-preview-an-entirely-new-point-of-collectionview/

๊ฐ์‚ฌ ํ•ด์š”.

์•ˆ๋…•ํ•˜์„ธ์š” @noypi ์ž…๋‹ˆ๋‹ค .

CollectionView๋Š” ๊ธฐ์ˆ ์ ์œผ๋กœ UWP์—์„œ ๋‹ค์†Œ "์ž‘๋™"ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ CollectionView ๋ฐ CarouselView์˜ ์ „์ฒด ๊ตฌํ˜„์€ ์ฒ˜์Œ๋ถ€ํ„ฐ Android ๋ฐ iOS์—์„œ ์—„๊ฒฉํ•˜๊ฒŒ ์ˆ˜ํ–‰๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ UWP์— ๋Œ€ํ•œ ๊ณต์‹ ์ž‘์—…์€ ์˜ˆ์ •๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ ์ง€์†์ ์œผ๋กœ ํ”ผ๋“œ๋ฐฑ์„ ์ˆ˜์ง‘ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ UWP์—์„œ ์–ด๋–ค ์ข…๋ฅ˜์˜ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ๋…ผ์˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด paul๋กœ ์ด๋ฉ”์ผ์„ ๋ณด๋‚ด์ฃผ์„ธ์š”. [email protected].

์‚ฌ์–‘์— ๋”ฐ๋ฅด๋ฉด TableView๊ฐ€ CollectionView๋กœ ์™„์ „ํžˆ ๋Œ€์ฒด๋ฉ๋‹ˆ๊นŒ?

๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ: ๋” ์ด์ƒ ์…€์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— iOS์šฉ ๋ณ€์ƒ‰ ํ‘œ์‹œ๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ListView๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ง€์ • ๋ Œ๋”๋Ÿฌ๋ฅผ ํ†ตํ•ด ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์–‘์— ๋”ฐ๋ฅด๋ฉด TableView๊ฐ€ CollectionView๋กœ ์™„์ „ํžˆ ๋Œ€์ฒด๋ฉ๋‹ˆ๊นŒ?

TableView๋Š” ์—ฌ์ „ํžˆ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ์ปจํŠธ๋กค์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ์งˆ๋ฌธ: ๋” ์ด์ƒ ์…€์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— iOS์šฉ ๋ณ€์ƒ‰ ํ‘œ์‹œ๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ListView๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ง€์ • ๋ Œ๋”๋Ÿฌ๋ฅผ ํ†ตํ•ด ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค.

iOS์—์„œ CollectionView๋Š” UICollectionView๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ•ด๋‹น ์…€์€ UICollectionViewCells์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  UICollectionViewCells์—๋Š” ์•ก์„ธ์„œ๋ฆฌ ๋ณด๊ธฐ(์˜ˆ: ๊ณต๊ฐœ ํ‘œ์‹œ๊ธฐ)๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ณต๊ฐœ ํ‘œ์‹œ ๋˜๋Š” ์ฒดํฌ ํ‘œ์‹œ์™€ ๊ฐ™์€ UI ์š”์†Œ์˜ ๊ฒฝ์šฐ ItemTemplate์—์„œ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŠน์ • ์œ ํ˜•์˜ ํ•ญ๋ชฉ์—์„œ ์„ ํƒ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ํ…œํ”Œ๋ฆฟ์ด ์žˆ๊ณ  ๊ทธ ์ค‘ ์ผ๋ถ€์—์„œ ์„ ํƒ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@hartez ItemTemplate์„ DataTemplateSelector๋กœ ์„ค์ •ํ•  ๋•Œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•จ: System.InvalidOperationException: LoadTemplate should not be null

ํ…œํ”Œ๋ฆฟ์ด ์ฆ‰์‹œ ์ง€์›๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

@hartez ItemTemplate์„ DataTemplateSelector๋กœ ์„ค์ •ํ•  ๋•Œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•จ: System.InvalidOperationException: LoadTemplate should not be null

ํ…œํ”Œ๋ฆฟ์ด ์ฆ‰์‹œ ์ง€์›๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋“ค์€ ๊ทธ๋ž˜์•ผ ํ•œ๋‹ค; ์•„๋งˆ๋„ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฌธ์ œ๋ฅผ ์—ด์–ด์ฃผ์„ธ์š”.

@toomasz ๋ฌธ์ œ๋ฅผ ์—ด๊ธฐ ์ „์— Nuget์„ ์ตœ์‹  ์‹œํ—˜ํŒ(๋˜๋Š” ์•ผ๊ฐ„)์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์„ ํƒ๊ธฐ๋ฅผ ๋‹ค์‹œ ํ…Œ์ŠคํŠธํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋ณด๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋Š” DataTemplateSelector ๋Œ€ํ•œ ์ง€์›์ด ์—†์„ ๋•Œ ๋ฐœ์ƒํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@hartez ํ˜„์žฌ ๋จธ๋ฆฌ๊ธ€&๋ฐ”๋‹ฅ๊ธ€๊ณผ ์ƒˆ๋กœ๊ณ ์นจ ๋ณด๊ธฐ์— ๋Œ€ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ธ๊ฐ€์š”? ์‹œ๊ฐ„ ์—ฌ์œ ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‹ถ์ง€๋งŒ ๋‹น์‹ ์˜ ๋ฐœ์„ ๋ฐŸ๊ณ  ์žˆ์ง€๋Š” ์•Š์€์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@adrianknight89 4.0์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค! ์—„์ฒญ๋‚œ

@hartez ํ˜„์žฌ ๋จธ๋ฆฌ๊ธ€&๋ฐ”๋‹ฅ๊ธ€๊ณผ ์ƒˆ๋กœ๊ณ ์นจ ๋ณด๊ธฐ์— ๋Œ€ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ธ๊ฐ€์š”? ์‹œ๊ฐ„ ์—ฌ์œ ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‹ถ์ง€๋งŒ ๋‹น์‹ ์˜ ๋ฐœ์„ ๋ฐŸ๊ณ  ์žˆ์ง€๋Š” ์•Š์€์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ธ ์ž‘์—…์€ ์—†์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ฐธ๊ณ ๋กœ, ์˜ค๋Š˜ ํ† ๋ก  ํ›„ ๋จธ๋ฆฌ๊ธ€ ๋ฐ ๋ฐ”๋‹ฅ๊ธ€๊ณผ ๊ด€๋ จ๋œ ๋‘ ๊ฐœ์˜ ์ƒˆ๋กœ์šด ์†์„ฑ์ธ IsHeaderSticky ๋ฐ IsFooterSticky ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ•ญ๋ชฉ๊ณผ ํ•จ๊ป˜ ์Šคํฌ๋กคํ• ์ง€ ์•„๋‹ˆ๋ฉด ์ œ์ž๋ฆฌ์— ์œ ์ง€ํ• ์ง€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋จธ๋ฆฌ๊ธ€/๋ฐ”๋‹ฅ๊ธ€๊ณผ ํ•จ๊ป˜ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํ›Œ๋ฅญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์–ด๋–ค ์‹์œผ๋กœ๋“  ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ๋‚˜์ค‘์— ํ•ด๋‹น ์†์„ฑ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

UWP์—์„œ ์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ๋ฅผ ์ง€์›ํ•  ๊ณ„ํš์ด ์žˆ๋‚˜์š”?

์˜ˆ. ๊ตฌํ˜„์€ ํ˜„์žฌ ๋‹ค๋ฅธ ํ”Œ๋žซํผ์— ์•ฝ๊ฐ„ ๋’ค์ฒ˜์ ธ ์žˆ์ง€๋งŒ ์™„์ „ํžˆ ์ง€์›ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. https://gist.github.com/hartez/7d0edd4182dbc7de65cebc6c67f72e14 ์—์„œ ๊ธฐ๋Šฅ ์ง„ํ–‰ ์ƒํ™ฉ์„

RefreshView์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
์ตœ์‹  Xamarin 4 ๋ฒ ํƒ€ ๋ฒ„์ „์ด ์žˆ๊ณ  RefreshView ์œ ํ˜•์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

RefreshView์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?
์ตœ์‹  Xamarin 4 ๋ฒ ํƒ€ ๋ฒ„์ „์ด ์žˆ๊ณ  RefreshView ์œ ํ˜•์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

RefreshView๋Š” ์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์—์„œ ๊ธฐ๋Šฅ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GroupItemsBinding์„ ์ถ”๊ฐ€ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

GroupItemsBinding ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ทธ๋ฃน์˜ ์ž์‹ ํ•ญ๋ชฉ์ด ํฌํ•จ๋œ ์†์„ฑ์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๊ทธ๋Ÿฌ๋ฉด ๊ทธ๋ฃน์ด ์ปฌ๋ ‰์…˜์—์„œ ์ƒ์† ํ•˜๋„๋ก ๊ฐ•์ œํ•˜๋Š” ๋Œ€์‹  ์ž์‹ ์ปฌ๋ ‰์…˜ ์†์„ฑ์„ ํฌํ•จ ํ•  ์ˆ˜

์žฅ์ :

  • ๊ทธ๋ฃนํ™”๋œ ์ปฌ๋ ‰์…˜์„ JSON์œผ๋กœ/์—์„œ ์ง๋ ฌํ™”(์—ญ์ง๋ ฌํ™”)ํ•˜๋Š” ๊ธฐ๋Šฅ.
    ์ปฌ๋ ‰์…˜์—์„œ ๊ทธ๋ฃน์„ ์ƒ์†ํ•˜๋ฉด JSON(์—ญ)์ง๋ ฌํ™”๋ฅผ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค( JSON ๋ฐฐ์—ด์€ ์†์„ฑ์ด ์•„๋‹Œ ๊ฐ’ ๋ฒ”์œ„๋งŒ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ). ์•ฑ์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋กœ ์ „ํ™˜๋˜๊ฑฐ๋‚˜ ์•ฑ API๊ฐ€ ๋ณด๊ธฐ ๋ชจ๋ธ์„ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ ๋ณด๊ธฐ ๋ชจ๋ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ ค๋ฉด ๋ณด๊ธฐ ๋ชจ๋ธ์„ ์ง๋ ฌํ™” ํ•ด์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋‘ ๋ฒˆ์งธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๊ณ  ๊ฐ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ์—์„œ ๊ฐ’๋น„์‹ผ ๋ณต์ œ + ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ๊ทธ๋ฃน ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๊ณ ์œ ํ•œ ๊ธฐ๋ณธ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ธฐ๋Šฅ(์˜ˆ: ViewModelBase )
  • ์ปฌ๋ ‰์…˜์˜ ๋ชจ๋“  ์ƒ์†๋œ ์†์„ฑ์œผ๋กœ ๊ทธ๋ฃน ๊ฐœ์ฒด๋ฅผ ์˜ค์—ผ์‹œํ‚ค์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์˜ˆ๋ฅผ ๋“ค์–ด docs.microsoft.com์—์„œ ์ด
```C#
๊ณต๊ฐœ ํด๋ž˜์Šค PageTypeGroup : ๋ชฉ๋ก
{
๊ณต๊ฐœ ๋ฌธ์ž์—ด ์ œ๋ชฉ { get; ์„ธํŠธ; }
// ์ถ”๊ฐ€ ์†์„ฑ ...
}

like this instead:

```C#
public class PageTypeGroup
{
    public string Title { get; set; }
    // More properties ...

    public List<PageModel> Children { get; set; }
}

XAML ์‚ฌ์šฉ:

C# <CollectionView GroupItemsBinding = "{Binding Children}" ...> </CollectionView>

GroupItemsBinding์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด GroupItemsBinding="{Binding .}" ํ•ด๋‹นํ•˜๋Š” ๊ธฐ์กด ๊ตฌํ˜„๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค.

์ถ”์‹ : ์ €๋Š” ์ด ์ œ์•ˆ์„ 2018๋…„ 7์›”์— ๋” ์ผ์ฐ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค.

2019๋…„ 8์›” 23์ผ ์—…๋ฐ์ดํŠธ: ๊ทธ๋ฃนํ™”๊ฐ€ ๊ตฌํ˜„๋˜์—ˆ์ง€๋งŒ ์ด ์ˆ˜์ • ์‚ฌํ•ญ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฃน ๋ฐ์ดํ„ฐ ์ฐธ์กฐ

์ด๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ๋Šฆ์ง€ ์•Š๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ๊ทธ๋ฃนํ™” ์ˆ˜์ค€์„ ์ง€์›ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?
๋‚˜๋ฌด ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ: Flutter์—๋Š” ExpansionTile์ด ์žˆ์Šต๋‹ˆ๋‹ค ( ์˜ˆ์ œ )

CollectionView์™€ ๊ด€๋ จํ•˜์—ฌ ์ถ”๊ฐ€ํ•ด์•ผ ํ•  ํ›Œ๋ฅญํ•œ ๊ธฐ๋Šฅ์ด๋ผ๊ณ  ์ƒ๊ฐ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ˆ˜ํ‰ ๋ชฉ๋ก์—์„œ ์Šคํฌ๋กค์„ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜์ ์œผ๋กœ ๋””์ž์ด๋„ˆ๋Š” ํ™”๋ฉด์— ์™„์ „ํžˆ ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ์š”์†Œ์— "๊ทธ๋ฆผ์ž" ํšจ๊ณผ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ(๋‚ด๊ฐ€ ์•„๋Š” ํ•œ) Xamarin.Forms์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฉด ์กฐ์นด๊ฐ€ ๋  ๊ฒƒ ๊ฐ™์ง€ ์•Š๋‚˜์š”? ์˜ˆ๋ฅผ ๋“ค์–ด X ๋ฐฑ๋ถ„์œจ๋กœ๋งŒ ํ‘œ์‹œ๋˜๋Š” ์š”์†Œ์— "๊ทธ๋ฆผ์ž"๋ฅผ ์ ์šฉํ•˜๋Š” ๋ถ€์šธ๋งŒํผ ๊ฐ„๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Position ์†์„ฑ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด ์†์„ฑ์€ ํ˜„์žฌ ํ•ญ๋ชฉ์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ณด์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ViewPagerIndicator ๋ฐ ์œ ์‚ฌํ•œ ํ‘œ์‹œ๊ธฐ๋ฅผ ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

"ํ˜„์žฌ ํ•ญ๋ชฉ"์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Œ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ƒ…์ด ์ผœ์ ธ ์žˆ์œผ๋ฉด ๋ทฐ๊ฐ€ ์Šค๋ƒ…๋œ ํ•ญ๋ชฉ์„ ๊ฒฐ์ •ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฌ์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ƒ… ์—†์ด ์˜ฌ๋ฐ”๋ฅธ ์„ ํƒ์€ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ๋ณด๊ธฐ์˜ ์‹œ์ž‘ ๋˜๋Š” ์ค‘๊ฐ„์ ์„ ์ฐจ์ง€ํ•˜๋Š” ํ•ญ๋ชฉ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ์†์„ฑ์€ ๋˜ํ•œ ScrollTo()์˜ ๋Œ€์•ˆ์œผ๋กœ ์‰ฌ์šด ์–‘๋ฐฉํ–ฅ ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@hartez ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์ด 4.0 ๋ฆด๋ฆฌ์Šค๋ฅผ ์œ„ํ•ด ์ค€๋น„๋  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ–ˆ์ง€๋งŒ ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ๊ฒƒ์„ ๋ณด๊ณ  ๋†€๋ž์Šต๋‹ˆ๋‹ค. ์Šคํฌ๋กค ๋ฐ ์ƒˆ๋กœ ๊ณ ์นจ ๊ธฐ๋Šฅ ์—†์ด๋Š” CollectionView๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์Šคํ”„๋ฆฐํŠธ๊ฐ€ ์ถœ์‹œ๋˜๊ธฐ ์ „์— ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ค ์ˆ˜ ์žˆ๋‚˜์š”? ์•ž์œผ๋กœ ListView์™€ ํ•จ๊ป˜ ์•„๋ฌด๊ฒƒ๋„ ์ œ๊ณตํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์œผ๋ฉฐ ์ด ์ปจํŠธ๋กค์„ ๊ฐ€๋Šฅํ•œ ํ•œ ๋นจ๋ฆฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@hartez ๋ชฉ๋ก ๋ ˆ์ด์•„์›ƒ์ด ์žˆ๋Š” CollectionView๊ฐ€ ํ•ญ๋ชฉ ๋‚ด์šฉ์— ๋งž๊ฒŒ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
image
์ด ์˜ˆ์—์„œ ๋ฒ„ํŠผ์€ ์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ ๋ฐ”๋กœ ์•„๋ž˜์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. VerticalOptions๊ฐ€ ์‹œ์ž‘์ผ ๋•Œ ์ด๋Ÿฐ ์‹์œผ๋กœ ์ž‘๋™ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ž”์—ฌ ํ•ญ๋ชฉ ์ž„๊ณ„ ๊ฐ’์ด ์†์„ฑ ํ…Œ์ŠคํŠธ์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ

๊ฐœ๋ณ„ ํ•ญ๋ชฉ ๋™์ž‘์˜ CollectionView ํ๋ฆ„์ด ํ™”๋ฉด ํฌ๊ธฐ ๋ณ€๊ฒฝ๊ณผ ๊ด€๋ จํ•˜์—ฌ iOS ๊ธฐ๋ณธ ๋™์ž‘์„ ๋ชจ๋ฐฉํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

iOS์˜ ์ด๋ฏธ์ง€ ๊ฐค๋Ÿฌ๋ฆฌ ์…€์€ CollectionView๋กœ ์ƒ์„ฑ๋˜๋ฉฐ ๊ฐœ๋ณ„ ์…€์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋™์ž‘์€ ๋‹จ์ผ ํ–‰์— ๊ทธ๋ฆฌ๋Š” ์…€์˜ ์ˆ˜๊ฐ€ ํ™”๋ฉด ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํœด๋Œ€ํฐ์—์„œ๋Š” 4๊ฐœ ํ•ญ๋ชฉ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ํƒœ๋ธ”๋ฆฟ์—์„œ๋Š” 8๊ฐœ ๋˜๋Š” 9๊ฐœ ํ•ญ๋ชฉ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Forms ๋ฒ„์ „๋„ ์ด๊ฒƒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๊นŒ? ์ง€๊ธˆ๊นŒ์ง€ ์ฝ์€ ์˜ˆ์ œ์—์„œ๋Š” GridItemsLayout Span ์†์„ฑ์„ ์„ค์ •ํ•œ ์œ„์น˜๋งŒ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ํ•ญ๋ชฉ์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ํ•˜๋“œ ์ฝ”๋”ฉ๋œ ๊ฐ’์ด ์ƒ์„ฑ๋˜๋ฉฐ ์‹ค์ œ๋กœ ๋‹ค์–‘ํ•œ ํ™”๋ฉด ํฌ๊ธฐ์˜ ์„ธ๊ณ„์—์„œ ํ•˜๋“œ ์ฝ”๋”ฉ์€ 2014๋…„์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. :-P

UWP์—๋Š” 4๊ฐ€์ง€ ์„ ํƒ ๋ชจ๋“œ ์ƒํƒœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
{
์—†์Œ,
ํ•˜๋‚˜์˜
๋‹ค์ˆ˜์˜,
์—ฐ์žฅํ•˜๋‹ค,
}
image

image

Android ๋ฐ IOS์˜ Four state๋„ ์œ ์šฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
ํŒŒ์ผ ํƒ์ƒ‰๊ธฐ๋ฅผ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค.
image

๊ฐ„๋‹จํ•œ ํŒจ๋”ฉ ์†์„ฑ์— ๋Œ€ํ•œ ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ์ ์ ˆํ•œ ํฌ๊ธฐ์˜ ๋นˆ ๋จธ๋ฆฌ๊ธ€๊ณผ ๋ฐ”๋‹ฅ๊ธ€์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ(์ผ๋‹จ ํ•ด๋‹น ๊ธฐ๋Šฅ์ด ๊ฐœ๋ฐœ๋˜๋ฉด) ์•ฝ๊ฐ„์˜ ํ•ดํ‚น์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ 4๋ฉด ๋ชจ๋‘์— ํŒจ๋”ฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋Š” ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์š”๊ตฌ๋˜๋Š”.

์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ์—์„œ ๋ชฉ๋ก ํ•ญ๋ชฉ์„ ์žฌ์ •๋ ฌํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

์‚ฌ์–‘์— CollectionView์˜ ํŠน์ • ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์„ ํƒ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?

// Any possible API could be helpful
private void OnSelectionChanging(object sender, SelectionChangingEventArgs e)
{
  if (...)
      e.Cancel = true;
 }

ํ˜„์žฌ ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜์ง€๋งŒ ์ด๊ฒƒ์ด Selected VisualState๊ฐ€ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋ง‰์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // Deselect the item.
    if (sender is CollectionView cv && e.CurrentSelection...)
    {
        cv.SelectedItem = null;
    }
}

์ˆ˜์ง ์Šคํฌ๋กค ๋ง‰๋Œ€ ์ƒ‰์ƒ ๋ฐ ์ˆ˜ํ‰ ์Šคํฌ๋กค ๋ง‰๋Œ€ ์ƒ‰์ƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

์Šคํฌ๋กค ๋ฐฉํ–ฅ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๋‚ด์šฉ ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์œผ๋กœ ์Šคํฌ๋กค์„ ์‹œ์ž‘ํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

๋ถ„๋ฆฌ์ˆ˜๊ฑฐํ•˜๊ณ ์‹ถ๋‹ค...

"๋ฉ”๋ชจ๋ฆฌํ™”"ํ•˜๊ณ  ์Šคํฌ๋กค ์œ„์น˜๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋งค์šฐ ๋†€๋ผ์šด ๊ฒƒ์€ ๋งค์ดˆ ๋˜๋Š” X๊ฐœ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ํ•ญ๋ชฉ ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‘ ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งˆ๋‹ค ํšŒ์ƒ‰ ๋ฐฐ๊ฒฝ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ  ๋‹ค๋ฅธ ๋งŽ์€ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ ์„ ํƒ๊ธฐ๋กœ ์ด๋ฏธ ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? ์œ„์น˜ ์‚ฌ์šฉ
๋ชจ๋“ˆ๋กœ ์—ฐ์‚ฐ์ž?

2019๋…„ 8์›” 13์ผ ํ™”์š”์ผ 16:53 Legacyorder [email protected]์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

์ •๋ง ๋†€๋ผ์šด ๊ฒƒ์€ ๋‹ค๋ฅธ ์•„์ดํ…œ์„ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋ชจ๋“  ์ดˆ ๋˜๋Š” X ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ํ…œํ”Œ๋ฆฟ. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ชจ๋“  ๋‘ ๋ฒˆ์งธ ํ•ญ๋ชฉ ๋ฐ ๊ธฐํƒ€ ๋งŽ์€ ์Šคํƒ€์ผ์— ๋Œ€ํ•œ ํšŒ์ƒ‰ ๋ฐฐ๊ฒฝ
๊ฐ€๋Šฅ์„ฑ.

โ€”
์ด ์Šค๋ ˆ๋“œ์— ๊ฐ€์ž…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/xamarin/Xamarin.Forms/issues/3172?email_source=notifications&email_token=AC4YCKDFCH3WFENRCLPWEC3QELDE3A5CNFSM4FHJRXPKY5DAPWSM4FHJRXPKYY3PNVWWK3TUL52HS4DFVEXG43VMVBW63
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AC4YCKHXX5YSR7M3S4VU5QLQELDE3ANCNFSM4FHJRXPA
.

์›ํ˜• ์Šคํฌ๋กค์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ตฌํ˜„ํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ ๊ฐ™์•„์š”.

๋ชฉ๋ก์—์„œ ์ ˆ๋Œ€ ์œ„์น˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก CollectionView์— ๋Œ€ํ•œ ItemsLayout์œผ๋กœ "AbsoluteItemsLayout"์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ฝ”๋“œ ๋’ค์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ๋Œ€์‹  ๋‹ค๋ฅธ ์†”๋ฃจ์…˜์ด ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

GridItemsLayout์„ ์‚ฌ์šฉํ•  ๋•Œ ํ•ญ๋ชฉ์ด ์—ฌ๋Ÿฌ ํ–‰์ด๋‚˜ ์—ด์— ๊ฑธ์ณ ์žˆ๋„๋ก ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ํ™•์‹คํžˆ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ๊ธฐ๋Šฅ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Scrolled ์ด๋ฒคํŠธ๋ฅผ ์ด ์ปจํŠธ๋กค์— ๋…ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ ๋ชฉ์ ์€ ๋ชฉ๋ก์˜ ๋งจ ์•„๋ž˜์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์ถ”๊ฐ€ ํ•ญ๋ชฉ์„ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋ ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. CollectionView๊ฐ€ ScrollView ๋‚ด๋ถ€์— ์žˆ๋Š”์ง€ ๊ฐ์ง€ํ•˜๊ณ  ์Šคํฌ๋กค ๊ธฐ๋Šฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

Scrolled ์ด๋ฒคํŠธ๋ฅผ ์ด ์ปจํŠธ๋กค์— ๋…ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ ๋ชฉ์ ์€ ๋ชฉ๋ก์˜ ๋งจ ์•„๋ž˜์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์ถ”๊ฐ€ ํ•ญ๋ชฉ์„ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋ ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. CollectionView๊ฐ€ ScrollView ๋‚ด๋ถ€์— ์žˆ๋Š”์ง€ ๊ฐ์ง€ํ•˜๊ณ  ์Šคํฌ๋กค ๊ธฐ๋Šฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ ์†Œ์›์ด ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค! ๋ฒ„์ „ 4.2๋ฅผ ํ™•์ธํ•˜์„ธ์š” :)
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/scrolling

ScrollView ๋‚ด์— CollectionView๋ฅผ ํฌํ•จํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฐ€์ƒํ™”๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Scrolled ์ด๋ฒคํŠธ๋ฅผ ์ด ์ปจํŠธ๋กค์— ๋…ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ ๋ชฉ์ ์€ ๋ชฉ๋ก์˜ ๋งจ ์•„๋ž˜์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์ถ”๊ฐ€ ํ•ญ๋ชฉ์„ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋ ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. CollectionView๊ฐ€ ScrollView ๋‚ด๋ถ€์— ์žˆ๋Š”์ง€ ๊ฐ์ง€ํ•˜๊ณ  ์Šคํฌ๋กค ๊ธฐ๋Šฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ ์†Œ์›์ด ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค! ๋ฒ„์ „ 4.2๋ฅผ ํ™•์ธํ•˜์„ธ์š” :)
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/scrolling

ScrollView ๋‚ด์— CollectionView๋ฅผ ํฌํ•จํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฐ€์ƒํ™”๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €๋Š” 4.2.0.709249์— ์žˆ์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?
image

image

4.2.0.709249๋กœ Scrolled ์ด๋ฒคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
bin/obj ํด๋”๋ฅผ ์‚ญ์ œํ•˜๊ณ  NuGet ํ†ตํ•ฉ์„ ํ™•์ธํ•˜์—ฌ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

Android ๋ฐ iOS์šฉ 4.2์—์„œ ๊ณง RTL ์ง€์›์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

Android ๋ฐ iOS์šฉ 4.2์—์„œ ๊ณง RTL ์ง€์›์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

์ผ๋ถ€ ์ง€์›์€ ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค. FlowDirection ์ง€์›์€ CollectionView ํ•ญ๋ชฉ ๋‚ด์—์„œ ์ด๋ฏธ ์ž‘๋™ ์ค‘์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ ๋ถˆ์™„์ „ํ•œ ๊ฒƒ์€ ์ˆ˜ํ‰ CollectionView ๋ ˆ์ด์•„์›ƒ์˜ ์Šคํฌ๋กค ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค. ์Šคํฌ๋กค ๋ฐฉํ–ฅ์€ Android์˜ FlowDirection๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ๋Š” ์•„์ง ํ•ด์•ผ ํ•  ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์ž‘์—…์€ 4.3์—์„œ ์™„๋ฃŒ๋ฅผ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

CollectionView์™€ ํ•จ๊ป˜ FlowDirection์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ์—ด์–ด ์ฃผ์‹œ๋ฉด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

RTL ์ง€์›์œผ๋กœ ์ˆ˜ํ–‰๋˜์ง€ ์•Š์€ ์ž‘์—…์„ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์‚ฌ์–‘์—์„œ ์ง„ํ–‰ ์ค‘ ๋˜๋Š” ์™„๋ฃŒ๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

2019๋…„ 9์›” 5์ผ ๋ชฉ์š”์ผ ์˜ค์ „ 2์‹œ 19๋ถ„ EZ Hart์—์„œ ์•Œ๋ฆผ @github.com์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

Android ๋ฐ iOS์šฉ 4.2์—์„œ ๊ณง RTL ์ง€์›์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

์ผ๋ถ€ ์ง€์›์€ ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค. FlowDirection ์ง€์›์€ ์ด๋ฏธ
CollectionView ํ•ญ๋ชฉ ๋‚ด์—์„œ ์ž‘์—…. ์•„์ง ๋ถˆ์™„์ „ํ•œ ๊ฒƒ์€ ๋‘๋ฃจ๋งˆ๋ฆฌ
์ˆ˜ํ‰ CollectionView ๋ ˆ์ด์•„์›ƒ์˜ ๋ฐฉํ–ฅ. ์Šคํฌ๋กค ๋ฐฉํ–ฅ
Android์˜ FlowDirection๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•˜์ง€๋งŒ ์•„์ง ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ์ž‘์—…์ด
๋‹ค๋ฅธ ํ”Œ๋žซํผ์— ๋Œ€ํ•ด ๊ทธ๋ ‡๊ฒŒํ•˜์‹ญ์‹œ์˜ค.

CollectionView์™€ ํ•จ๊ป˜ FlowDirection์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด
๋ฌธ์ œ๋ฅผ ์—ด์–ด ์ฃผ์‹œ๋ฉด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/xamarin/Xamarin.Forms/issues/3172?email_source=notifications&email_token=ACDWB3GSYAQSADERHWVTJX3QIANMNA5CNFSM4FHJRXPKYY5DLOWSM4FHJRXPKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ACDWB3HMFCHBRZWD5AJMXH3QIANMNANCNFSM4FHJRXPA
.

์™„๋ฃŒ๋˜์ง€ ์•Š์Œ: ๊ฐ€๋กœ ๋ ˆ์ด์•„์›ƒ์˜ ์Šคํฌ๋กค ๋ฐฉํ–ฅ์ž…๋‹ˆ๋‹ค.

์ˆ˜ํ‰์œผ๋กœ ์Šคํฌ๋กค๋˜๋Š” CollectionView์—์„œ FlowDirection = RightToLeft๋ฅผ ์„ค์ •ํ•˜๋ฉด ํ˜„์žฌ iOS ๋ฐ UWP์—์„œ ์Šคํฌ๋กค ๋ฐฉํ–ฅ์ด ์˜ค๋ฅธ์ชฝ์—์„œ ์™ผ์ชฝ์ด ์•„๋‹™๋‹ˆ๋‹ค(Android์—์„œ _does_ ์ž‘๋™ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค).

LoadingDataTemplate์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

๋ฐ์ดํ„ฐ๋ฅผ ListView/CollectionView์— ๋น„๋™๊ธฐ์‹์œผ๋กœ ๋กœ๋“œํ•˜๋Š” ๋‚ด ๊ฒฝํ—˜์— ๋”ฐ๋ฅด๋ฉด listview/collectionview๊ฐ€ ์ฑ„์›Œ์งˆ ๋•Œ๊นŒ์ง€ ๋•Œ๋•Œ๋กœ ๋นˆ ๊ณต๊ฐ„์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

LoadingDataTemplate์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๊ฐ€ ์ฑ„์›Œ์ง€๊ณ  ํŽ˜์ด์ง€๊ฐ€ ์ด๋ฏธ ํ‘œ์‹œ๋œ ๊ฒฝ์šฐ ์ถ”๊ฐ€ ์‘๋‹ต์„ฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” CollectionView ๊ฐ€ ์ฒ˜์Œ ํ‘œ์‹œ๋  ๋•Œ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ItemsSource ์ปฌ๋ ‰์…˜์— ์ถ”๊ฐ€๋  ๋•Œ๊นŒ์ง€ ์—ฌ๋Ÿฌ ์ž๋ฆฌ ํ‘œ์‹œ์ž ์…€์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ๋Š” ๋ชฉ๋ก ๋งจ ์•„๋ž˜์— ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ๊ฒฝ์šฐ ๋ฐ”๋‹ฅ๊ธ€์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ฒซ ๋ฒˆ์งธ ๊ฒƒ์€ ๋” ๋งŽ์€ ์ž‘์—…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ์ฒ˜์Œ์—๋Š” ๋™์ผํ•œ ์ž๋ฆฌ ํ‘œ์‹œ์ž ๋ฐ์ดํ„ฐ ํ…œํ”Œ๋ฆฟ์ด ์žˆ๋Š” 3-5๊ฐœ์˜ ํ•ญ๋ชฉ์œผ๋กœ ์†Œ์Šค๋ฅผ ๋กœ๋“œํ•œ ๋‹ค์Œ ํ•ด๋‹น ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜๊ณ  ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค). ๋˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์€ CollectionView ์œ„์— ์Šค์ผˆ๋ ˆํ†ค ๋ทฐ๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋˜๋ฉด ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ˜„์žฌ ListView ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๋จผ์ € ๋กœ๋“œ ๋ณด๊ธฐ์— EmptyView ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด EmptyView ์— ๋Œ€ํ•œ ํ…œํ”Œ๋ฆฟ์„ ๋ณ€๊ฒฝํ•˜์—ฌ "nothing found" ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

@adrianknight89

๋˜ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์€ CollectionView ์œ„์— ์Šค์ผˆ๋ ˆํ†ค ๋ทฐ๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋˜๋ฉด ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ํ˜„์žฌ ListView ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ๋”ฐ๋ฅด๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ์ฆ‰, ์œ„์— ํ™œ๋™ ํ‘œ์‹œ๊ธฐ๋ฅผ ๋‘์‹ญ์‹œ์˜ค. ListView๋ฅผ IsVisible = false ๋ฐ ActivityIndicator IsVisible = true๋กœ ์„ค์ •ํ•œ ๋‹ค์Œ listview๊ฐ€ ์ฑ„์›Œ์ง„ ํ›„ ๋‘ ๊ฐ’์„ ๋ชจ๋‘ ๋ฐ˜์ „ํ•ฉ๋‹ˆ๋‹ค.

@adrianknight89

๋‚˜๋Š” ์ด๊ฒƒ์„ ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๋จผ์ € EmptyView๋ฅผ ๋กœ๋”ฉ ๋ณด๊ธฐ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด "nothing found" ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋„๋ก EmptyView์— ๋Œ€ํ•œ ํ…œํ”Œ๋ฆฟ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค! ๊ทธ๊ฒƒ์ด ์ž‘๋™ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ LoadingDataTemplate ๋ฐ EmptyView์™€ ๊ด€๋ จํ•˜์—ฌ CollectionView์— ๋ณ„๋„์˜ ํ…œํ”Œ๋ฆฟ ์†์„ฑ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ๋” ๋‹จ์ˆœํ™”๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ์†์„ฑ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ๋” ๋‚ซ๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœ์„ฑ ์ธก๋ฉด ์™ธ์— ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ชฉ์ ์„ ์œ„ํ•ด ๋‹จ์ผ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ EmptyView ๋Š” BackgroundView ๋กœ ์ด๋ฆ„์ด ์ง€์ •๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ ์–ด๋–ค ์šฉ๋„๋กœ๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (ํŽธ์ง‘: A BackgroundView ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

@LeoJHarris BackgroundView ์ง€์›์„ ์œ„ํ•ด #7447์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์œ„์˜ ๋‘ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด EmptyView ๋ฐ BackgroundView ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์ด ์—ฌ์ „ํžˆ 100% ์›ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๋‘ ๊ฐ€์ง€๋ฅผ ๋ชจ๋‘ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด EmptyView ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚ซ์Šต๋‹ˆ๋‹ค. ์‹œ๋‚˜๋ฆฌ์˜ค. BackgroundView ๋ฅผ ๋กœ๋”ฉ ํ™”๋ฉด์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋˜๋ฉด null๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@adrianknight89 ๋ฐ์ดํ„ฐ๊ฐ€ ์ค€๋น„๋˜๋ฉด CollectionView๊ฐ€ ์ด๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๋Œ€์‹  'null out' ์ฒ˜๋ฆฌํ•˜๋ฉด

CollectionView์˜ RemainingItemsThreshold๋ฅผ ํ™œ์šฉํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ์Šคํฌ๋กคํ•  ๋•Œ ๋‘ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  1. ์•ฑ์ด ๋ฉˆ์ถ”๊ณ  ๊ฐ•์ œ ์ข…๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. CollectionView ์Šคํƒ์˜ ํ•ญ๋ชฉ์ด ์„œ๋กœ ๊ฒน์ณ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค( ์ด๋ฏธ์ง€ ์ฐธ์กฐ).

์ด ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ณด๊ณ ๋œ ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๊นŒ?

@Bronson15 RemainingItemsThresholdReached ์ด๋ฒคํŠธ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ณ„์‹ ๊ฐ€์š”? ๋น ๋ฅธ ์Šคํฌ๋กค์€ ์—ฌ๋Ÿฌ ๋ฒˆ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฏ€๋กœ ๋ฐ์ดํ„ฐ ์†Œ์Šค ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ์ด๋ฒคํŠธ ํ˜ธ์ถœ์„ ๋ฌด์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ˆ„์ ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•ด ๋ณด์„ธ์š”.

์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์กฐ์‚ฌ๋ฅผ ์œ„ํ•ด ์žฌํ˜„์œผ๋กœ ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ด โ€‹โ€‹์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ Bronson15 ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
ObservableRangeCollection์œผ๋กœ ์‹œ๋„ํ•˜๊ณ  #2๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
์—ฌ์ „ํžˆ ์ •์ง€/๋นˆ ๋ชฉ๋ก์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์‹คํ–‰ํ•  ๋•Œ CPU ์ŠคํŒŒ์ดํฌ๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ๋ฌดํ•œ ๋ฃจํ”„๊ฐ€ ๋ณด์ž…๋‹ˆ๋‹ค.

ํŽธ์ง‘: iOS์—์„œ๋งŒ ์ค‘๋‹จ๋˜๊ณ  Android์—์„œ๋Š” ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ํŒ€,
RemainingItemsThreshold์™€ RemainingItemsThresholdReachedCommand๋ฅผ ์‚ฌ์šฉํ•ด๋„ RemainingItemsThresholdReachedCommand์— ํ• ๋‹น๋œ ํ•จ์ˆ˜๊ฐ€ ๋น ๋ฅด๊ฒŒ ์Šคํฌ๋กคํ•˜์ง€ ์•Š์•„๋„ ์ˆœ์ฐจ์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๋ฒˆ(์ฒ˜์Œ์—๋Š” ๋‘ ๋ฒˆ, ๋‹ค์Œ์—๋Š” 4๋ฒˆ ๋“ฑ) ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‹ ์„ ํ•œ Xamarin Forms ํ”„๋กœ์ ํŠธ(v.4.2.0.778463)๋กœ ์ด๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹น์‹ ์€ ๋‹น์‹ ์˜ ๋์—์„œ ๊ทธ๊ฒƒ์„ ์žฌํ˜„ํ•˜๋ ค๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹ค์Œ์€ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ ์Šค๋‹ˆํŽซ์ž…๋‹ˆ๋‹ค.

XAML:

<CollectionView
        x:Name="StackLayout"
        ItemsSource="{Binding LatestStories}"
        RemainingItemsThreshold="10"
        RemainingItemsThresholdReachedCommand="{Binding RemainingStoriesCommand}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
            <Grid
                                ColumnSpacing="16"
                                HeightRequest="110"
                                RowSpacing="0">

                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*">
                        </ColumnDefinition>
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <!--  Blog title  -->
                    <Label
                                    Grid.Column="1"
                                    Margin="0,8"
                                    FontSize="14"
                                    LineBreakMode="TailTruncation"
                                    LineHeight="{OnPlatform Default=-1,
                                                            Android=1.25,
                                                            iOS=1.25}"
                                    MaxLines="2"
                                    Text="{Binding Title}" />

                    <!--  Author name  -->
                    <Label
                                    Grid.Row="1"
                                    Grid.Column="1"
                                    Margin="0,8,0,0"
                                    FontSize="12"
                                    LineHeight="{OnPlatform Default=-1,
                                                            Android=1.5}"
                                    Text="{Binding Author}" />

                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
</CollectionView>

๋ชจ๋ธ ๋ณด๊ธฐ:

public class ArticleListViewModel
    {
        public ObservableRangeCollection<FeedItem> LatestStories { get; } = new ObservableRangeCollection<FeedItem>();
        public Command RemainingStoriesCommand => new Command(() => RemainingStories());

        public ArticleListViewModel()
        {
            RemainingStories();
        }

        private async void RemainingStories()
        {
            var feeds = await GetRemoteFeedsAsync();
            try
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    LatestStories.AddRange(feeds);
                });

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex, "");
            }
        }

        private async Task<List<FeedItem>> GetRemoteFeedsAsync()
        {
            try
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                var allItems = new List<FeedItem>();
                HttpResponseMessage response;
                var httpClient = new HttpClient();
                response = await httpClient.GetAsync("https://jsonplaceholder.typicode.com/photos").ConfigureAwait(false);
                if (response.IsSuccessStatusCode)
                {
                    var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    var testData = JsonConvert.DeserializeObject<List<TestJson>>(data);
                    if (LatestStories.Count == 0)
                    {
                        testData = testData.Take(20).ToList();
                    }
                    else
                    {
                        testData = testData.Skip(LatestStories.Count).Take(20).ToList();
                    }

                    foreach (var item in testData)
                    {
                        var newItem = new FeedItem
                        {
                            Title = item.id.ToString(),
                            Description = item.title,
                            ImagePath = item.thumbnailUrl,
                            Link = item.url,
                            PublishDate = "2019-09-11",
                            Category = ""
                        };
                        allItems.Add(newItem);
                    }
                }
                watch.Stop();
                Debug.WriteLine("TPL Total Time: " + watch.ElapsedMilliseconds);
                return allItems;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex, "");
                throw;
            }

        }
    }

@Bronson15 @andreabalducci @techduggu RemainingItemsThresholdReachedCommand ์ด ์ฒ˜๋ฆฌ๋˜๋Š” ๋™์•ˆ UI๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์Šคํฌ๋กค ํŒจํ„ด์œผ๋กœ ์ธํ•ด ๋ช…๋ น์„ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ณ„์† ๋ˆ„๋ฅด๋Š” ๊ฒƒ์ด ์ •์ƒ์ž…๋‹ˆ๋‹ค. ์ž ๊ธˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. https://github.com/xamarin/Xamarin.Forms/pull/7516/files#diff -2be3eff4d53f761cd581cca1d2ec3bc0R48

์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์›๊ฒฉ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ ๋ช…๋ น์„ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™”ํ•˜๊ฑฐ๋‚˜ ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋… ์ทจ์†Œ/๊ตฌ๋…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ๊ฒฝํ—˜์ƒ ์ฝœ๋ฐฑ์„ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™” ๋˜๋Š” ๊ตฌ๋… ์ทจ์†Œ/๊ตฌ๋…ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์—ฌ๋Ÿฌ ํ˜ธ์ถœ์ด ์‹œ์ž‘๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„ธ๋งˆํฌ์–ด๊ฐ€ ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

@hartez @samhouts @davidortinau ์•ž์œผ๋กœ ์ด ๋ฌธ์ œ๊ฐ€ ๊ฝค ์ž์ฃผ ์ œ๊ธฐ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์ œ์•ˆ์€ ๋‚˜๋จธ์ง€ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ๋ฌธ์„œ์˜ ์ผ๋ถ€์—ฌ์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๋ฌธ์„œ ํŒ€์ด ํ…Œ์ŠคํŠธ์šฉ ์›๊ฒฉ ํ”ผ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ์ฐธ์กฐ์šฉ ์ฝ”๋”ฉ ํŒจํ„ด์„ ์ถ”์ฒœํ•˜์—ฌ ์‚ฌ๋žŒ๋“ค์ด ๊ณ„์† ๋„์›€์„ ์š”์ฒญํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

@techduggu ์ฝ”๋“œ์— ๋‹ค๋ฅธ(์‚ฌ์†Œํ•œ) ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. Stack Exchange์—์„œ ์ฝ”๋“œ๋ฅผ ๊ฒ€ํ† ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๊ทธ๋Ÿฐ ๊ณณ์ด ์•„๋‹™๋‹ˆ๋‹ค.

@adrianknight89 "์Šคํฌ๋กค ํŒจํ„ด์œผ๋กœ ์ธํ•ด"๋ผ๋Š” ์šฉ์–ด๋ฅผ ๊ฐ•์กฐํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋” ๋งŽ์ด ์ฐพ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๊ฐ€๋ ค์›€์ฆ์„ ์œ ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. RecyclerView ๋ฐ ๊ธฐํƒ€ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณธ ํ›„ ์˜ˆ, ์Šคํฌ๋กค ํŒจํ„ด์œผ๋กœ ์ธํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ๋˜๊ณ  ํ•ด๋‹น ํŒจํ„ด์ด ์Šคํฌ๋กค ์ƒํƒœ์— ๋”ฐ๋ผ SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING ๋˜๋Š” SCROLL_STATE_SETTLING์ž„์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnScrollListener

๊ท€ํ•˜์˜ ์ฝ”๋“œ์™€ ์ด ์•ˆ๋“œ๋กœ์ด๋“œ ๊ฐ€์ด๋“œ(https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView)๋„ ์ž ๊ธˆ ๋˜๋Š” ์‚ฌ์šฉ์„ ํ†ตํ•ด ๋ฌดํ•œ ์Šคํฌ๋กค์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ ์Šคํฌ๋กค ์ƒํƒœ(๋Œ€๋ถ€๋ถ„ ์‚ฌ์šฉ์ž ์ง€์ • ๋ Œ๋”๋Ÿฌ๊ฐ€ ํ•„์š”ํ•จ). ๋”ฐ๋ผ์„œ Xamarin.Forms๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์‹œ๋„ํ–ˆ๊ณ  ๋งค๋ ฅ์ฒ˜๋Ÿผ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. :) ์ €์™€ ๊ฐ™์€ ์‚ฌ๋žŒ๋“ค(๋ฐ˜ ์ง€์‹์„ ๊ฐ€์ง„)์ด ์ œ๊ธฐํ•˜๋Š” ๊ทธ๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ด ์ œ์•ˆ์„ ๋ฌธ์„œ์˜ ์ผ๋ถ€๋กœ ํฌํ•จํ•˜๋„๋ก ๊ท€ํ•˜์˜ ์˜๊ฒฌ์„ ์ถ”์ฒœํ•˜๊ณ  ์ง€์ง€ํ•ฉ๋‹ˆ๋‹ค. :)

๋˜ํ•œ, reg. ์œ„์˜ ์ฝ”๋“œ ์กฐ๊ฐ์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•œ ์‚ฌ์†Œํ•œ ๋ฌธ์ œ - ์ด๊ฒƒ์€ ์ปฌ๋ ‰์…˜ ๋ณด๊ธฐ๋กœ ๋ฌดํ•œ ๋กœ๋”ฉ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ POC ํ”„๋กœ์ ํŠธ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์–ด๋ฆฌ์„์€ null ๊ฒ€์‚ฌ ๋“ฑ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋‹น์‹ ์˜ ์˜๊ฒฌ์„ ์•Œ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”!

@adrianknight89 ์•„ ๋„ค. ๋ฐ”์œ ์ˆ˜ํ‘œ๊ฐ€ ๋ˆ„๋ฝ๋˜์–ด ์Šคํƒœํ‚น ๋ฌธ์ œ์— ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ œ์•ˆํ•œ ๋Œ€๋กœ ์„ธ๋งˆํฌ์–ด๋ฅผ ๊ตฌํ˜„ํ–ˆ์œผ๋ฉฐ ItemsSource์— ์ƒˆ ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•  ๋•Œ ๋ณด๊ธฐ๊ฐ€ ์Šคํฌ๋กค ์œ„์น˜๋ฅผ ์ฒ˜์Œ์œผ๋กœ ์žฌ์„ค์ •ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•œ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด์ƒํ•˜๊ฒŒ๋„ ํ˜ธ์ถœ์„ ์‹œ๋„์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ; ํ…Œ์ŠคํŠธ ํŒŒ์ผ์—์„œ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์ด ๋ฌธ์ œ๊ฐ€ ๋‹ค์‹œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ชฉ๋ก์˜ ๋๊นŒ์ง€ ์Šคํฌ๋กคํ•  ๋•Œ ์—ฌ์ „ํžˆ ์ •์ง€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณด๊ธฐ๊ฐ€ ๋น„์–ด ์žˆ๊ณ  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ •์ง€๋ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์Šคํฌ๋กค ์œ„์น˜ ์žฌ์„ค์ •์€ ์—ฌ์ „ํžˆ โ€‹โ€‹์žˆ์ง€๋งŒ ์ž์ฃผ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ํ•ญ๋ชฉ์„ ๋กœ๋“œํ•˜๋Š” ๋ Œ๋”๋ง์€ ์žฅ์น˜์—์„œ๋„ ๋งค์šฐ ๊ณ ๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@techduggu ์ €๋Š” VS๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์ง€๋งŒ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด RemainingStories() ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๊ณ , try ๋‚ด์—์„œ ์›๊ฒฉ ํ˜ธ์ถœ์„ ์ด๋™ํ•˜๊ณ , HttpClient ๋Œ€ํ•ด using์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ด์ƒ์ ์œผ๋กœ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์— ๋‹จ์ผ ์ •์  ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ ˆ๋Œ€ ํ๊ธฐํ•˜์ง€ ์•Š์Œ), ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ์ค‘์ง€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. :)

@Bronson15 CollectionView์— ์Šคํฌ๋กค ์œ„์น˜๋ฅผ ์žฌ์„ค์ •ํ•˜๊ณ  UI๊ฐ€ ์ •์ง€๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. #7285๋กœ ์ˆ˜์ •๋œ ๊ฒƒ ๊ฐ™์€๋ฐ iOS ์ „์šฉ์ž…๋‹ˆ๋‹ค. ์ตœ์‹  ์•ผ๊ฐ„ Nuget์„ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์•ผ๊ฐ„ ํ”ผ๋“œ URL์€ ์–‘์‹์šฉ GitHub ํ™ˆํŽ˜์ด์ง€์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์ง€์†๋˜๋ฉด ์žฌ์ƒ์‚ฐ ์ฝ”๋“œ ๋ฌธ์ œ๋ฅผ ์—ด์–ด ๊ฒ€ํ† ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@adrianknight89 ์•ผ๊ฐ„ ๋นŒ๋“œ๋กœ ์Šคํฌ๋กคํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ๋Œ€๋ถ€๋ถ„ ํ•ด๊ฒฐ๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค(ํ•œ ๋ฒˆ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค). ๋ชฉ๋ก์ด ๋์ด ์•„๋‹ˆ๋ผ ๋์—†๋Š” ๋ฃจํ”„์— ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. AFAIK ์‚ฌ์–‘์— ๊ทธ๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ์†์„ฑ์ด ์—†์Šต๋‹ˆ๊นŒ?

@Bronson15 ๋ฌดํ•œ ๋ฃจํ”„๊ฐ€ ๋ฐœ์ƒํ•ด์„œ๋Š” ์•ˆ๋ฉ๋‹ˆ๋‹ค. iOS ๋˜๋Š” Android์—์„œ ๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ์›๊ฒฉ ํ”ผ๋“œ์˜ ๋์— ๋„๋‹ฌํ•˜๋ฉด ๋ฃจํ”„๋ฅผ ์ข…๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ๋‹ค๋ฅธ DB ํ˜ธ์ถœ์„ ๋ฐœํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ฆ‰์‹œ RemainingItemsThresholdReachedCommand ์—์„œ ๋ฆฌํ„ด).

๋ณด๊ธฐ ์Šคํฌ๋กค์ด ์ค‘์ง€๋˜๋ฉด ๋ช…๋ น์ด ๋” ์ด์ƒ ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์† ํ† ํฐ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” Azure Cosmos๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ† ํฐ์ด null์ด๋ฉด ๋” ์ด์ƒ ๋กœ๋“œํ•  ์ฝ˜ํ…์ธ ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋‚ด RemainingItemsThresholdReachedCommand ๋Š” ํ•ด๋‹น ํ† ํฐ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋น„์Šทํ•œ ๊ฒƒ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@adrianknight89 ์•— . ํฅ๋ฏธ๋กœ์šด. ๊ฒฐ๊ณผ ์นด์šดํŠธ์— ๋Œ€ํ•œ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  0์ด๋ฉด ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌดํ•œ ์Šคํฌ๋กค์„ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@adrianknight89 ๋Š” iOS ์ถฉ๋Œ ๋ฌธ์ œ์— ๋Œ€ํ•ด
Android์˜ 1000๊ฐœ ํ•ญ๋ชฉ์€ ๊ฑฐ์˜ ์‹ค์‹œ๊ฐ„์ด๋ฉฐ iOS์—์„œ๋Š” ๋ทฐ๊ฐ€ ๋ Œ๋”๋ง๋˜๊ธฐ๊นŒ์ง€ 5-7์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋””๋ฒ„๊ทธ, iPhone Xs ๋ฐ Redmi Note 7 ๋ชจ๋‘

@andreabalducci XS ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ

@adrianknight89 @andreabalducci ์˜ˆ, Xs Max์—์„œ ๋” ๋งŽ์€ ํ•ญ๋ชฉ์„ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์•ฝ 1-5์ดˆ๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ๋ณด๊ธฐ๋Š” ์ด๋ฏธ ๋ Œ๋”๋ง๋œ ๋ชฉ๋ก์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋Œ€์‹  ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๋น„์šฐ๊ณ  ๋‹ค์‹œ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

@adrianknight89 ๋‘ ๋ฌผ๋ฆฌ์  ์žฅ์น˜ ๋ชจ๋‘ iOS ์—๋ฎฌ๋ ˆ์ดํ„ฐ์— ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

iOS๊ฐ€ 20์ดˆ๋ฅผ ๋„˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ ํ…œํ”Œ๋ฆฟ์—์„œ ๋ชจ๋“  ์Šคํƒ ๋ ˆ์ด์•„์›ƒ์„ ์ œ๊ฑฐํ•˜๊ณ  ์ปดํŒŒ์ผ๋œ ๋ฐ”์ธ๋”ฉ์„ ํ™œ์„ฑํ™”ํ•œ FormattedString์œผ๋กœ ์•ฝ๊ฐ„์˜ ์†๋„ ์ „ํ™˜์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

iOS์—์„œ๋Š” ObservableRangeCollection(mvvm ๋„์šฐ๋ฏธ์—์„œ)์„ ์ถ”๊ฐ€ํ•  ๋•Œ ๋ณด๊ธฐ๊ฐ€ ๊ฒ€๊ฒŒ ํ‘œ์‹œ๋˜๊ณ  ๋ชจ๋‘ ๋‹ค์‹œ ๊ทธ๋ฆฌ๋ฉฐ Android์—์„œ๋Š” ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ๋ณ„๊ฐœ์˜ ๋ฌธ์ œ์ฒ˜๋Ÿผ ๋“ค๋ฆฐ๋‹ค. ๋‚จ์•„์žˆ๋Š” ์•„์ดํ…œ์ด ์•„๋‹Œ๊ฐ€ ์‹ถ์Šต๋‹ˆ๋‹ค.

GridItemsLayout์„ ์‚ฌ์šฉํ•  ๋•Œ ํ•ญ๋ชฉ์ด ์—ฌ๋Ÿฌ ํ–‰์ด๋‚˜ ์—ด์— ๊ฑธ์ณ ์žˆ๋„๋ก ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ํ™•์‹คํžˆ ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š” ๊ธฐ๋Šฅ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

@LynoDesu ์ด์— ๋Œ€ํ•œ ๋ฌธ์ œ๊ฐ€ ์ถ”์ ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. https://github.com/xamarin/Xamarin.Forms/issues/6357

@LynoDesu ์ด์— ๋Œ€ํ•œ ๋ฌธ์ œ๊ฐ€ ์ถ”์ ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค: #6357

์•„, ์ข‹์•„! ๊ฐ์‚ฌ ํ•ด์š”. ์—ฌ๊ธฐ์— ๊ธฐ์—ฌํ•˜๋ ค๋ฉด ์–ด๋””์„œ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

ํ™ˆํŽ˜์ด์ง€ ์œ„ํ‚ค์™€ Contributing.md๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”.

@adrianknight89 ๋Š” ๊ณต๋ฐฑ + ๋‹ค์‹œ ์‹œ์ž‘ ๋ฌธ์ œ๋ฅผ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. https://github.com/andreabalducci/XamarinCollectionView/blob/b186e563ff8391dfb473e62e5a4c4587e8d4e9da/cvrepro/cvrepro/ListViewModel.cs

๋นˆ ์ปฌ๋ ‰์…˜์œผ๋กœ ์‹œ์ž‘ํ•˜๋ฉด ๋ชจ๋“  ๋ฐ”์ธ๋”ฉ์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๊ธฐ ์ „์— ์ปฌ๋ ‰์…˜์— ํ•ญ๋ชฉ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

iPhone ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์•„๋งˆ๋„ #7548๊ณผ ๋™์ผํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— ๋ ˆํ”„๋กœ๋ฅผ ๊ฒŒ์‹œํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

CollectionView๋Š” IsGrouped๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Android์—์„œ ๋ฒ„๊ทธ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

CollectionView.GroupHeaderTemplate ๋Š” ์ „ํ˜€ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. iOS์—์„œ๋Š” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. Microsoft ์‚ฌ์ดํŠธ์˜ ๊ทธ๋ฃนํ™” ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    public class AnimalGroup : List<Animal>
    {
        public string Name { get; private set; }

        public AnimalGroup(string name, List<Animal> animals) : base(animals)
        {
            Name = name;
        }
    }

    public class Animal
    {
        public string Name { get; set; }
        public string Location { get; set; }
        public string Details { get; set; }
        public string ImageUrl { get; set; }
    }

    public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();

    Animals.Add(new AnimalGroup("Bears", new List<Animal>
        {
            new Animal
            {
                Name = "American Black Bear",
                Location = "North America",
                Details = "Details about the bear go here.",
                ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbรคr.jpg"
            },
            new Animal
            {
                Name = "Asian Black Bear",
                Location = "Asia",
                Details = "Details about the bear go here.",
                ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
            },
        }));
<CollectionView ItemsSource="{Binding Animals}"
                        IsGrouped="true">
            <CollectionView.GroupHeaderTemplate>
                <DataTemplate>
                    <Label Text="Header"
                           BackgroundColor="LightGray"
                           FontSize="Large"
                           FontAttributes="Bold" />
                </DataTemplate>
            </CollectionView.GroupHeaderTemplate>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10">
                        <Image Grid.RowSpan="2"
                               Source="{Binding ImageUrl}"
                               Aspect="AspectFill"
                               HeightRequest="60"
                               WidthRequest="60" />
                        <Label Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold" />
                        <Label Grid.Row="1"
                               Grid.Column="1"
                               Text="Child"
                               FontAttributes="Italic"
                               VerticalOptions="End" />
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/grouping

์ค‘์š”ํ•œ

CollectionView๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐ์ดํ„ฐ ๊ทธ๋ฃนํ™”๋Š” ํ˜„์žฌ iOS์—์„œ๋งŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

์•„, ๊ทธ ๋ถ€๋ถ„์„ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.

iOS์™€ Android ๋ชจ๋‘์—์„œ ๊ทธ๋ฃนํ™”๋œ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๊ณ  ์‹ถ์ง€๋งŒ ListView๋ฅผ ํ”ผํ•˜๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ํ˜„์žฌ CollectionView๋งŒํผ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ListView์— ๊ฐ‡ํ˜€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ณณ์ด ๋ฐ”๋กœ ๋ฌผ์–ด๋ณด๋Š” ๊ณณ์ด๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์›๋ž˜ ๊ฒŒ์‹œ๋œ ์‚ฌ์–‘์—๋Š” IsHeaderSticky ๋ฐ IsFooterSticky ๋Œ€ํ•œ ์†์„ฑ์ด ์žˆ์ง€๋งŒ ํ† ๋ก ์ด๋‚˜ ๊ตฌํ˜„๋œ ์†Œ์Šค ์ฝ”๋“œ ์–ด๋””์—๋„ ์ด์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์–ธ๊ธ‰์ด ์—†์Šต๋‹ˆ๋‹ค. ์•„์ง ์ด ๋ณด๊ธฐ์— ๋Œ€ํ•œ ๋กœ๋“œ๋งต์— ์žˆ์Šต๋‹ˆ๊นŒ?

collectionview์—์„œ๋Š” ItemAppeared, ITemDisappeared๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@IosDeveloperHarsh Scrolled ์ด๋ฒคํŠธ๋Š” ์ด๋ฒคํŠธ ์ธ์ˆ˜์— ๋งŽ์€ ์œ ์šฉํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์—์„œ ์ฒ˜์Œ๊ณผ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณด์ด๋Š” ํ•ญ๋ชฉ ์ƒ‰์ธ์„ ๋ณด์‹ญ์‹œ์˜ค.

@rafiwardak2003 CollectionView ๊ทธ๋ฃน์ด ์žˆ๋Š” ๊ฐค๋Ÿฌ๋ฆฌ ์ƒ˜ํ”Œ์€ ์˜ค๋Š˜ ํ˜„์žฌ Android์—์„œ ์ž‘๋™ํ•˜์ง€๋งŒ ๊ท€ํ•˜๊ฐ€ ์ œ๊ณตํ•œ ์ƒ˜ํ”Œ์„ ์‹คํ–‰ํ•˜์ง€๋Š” ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์–ด๋–ค Nuget์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ์ตœ์‹  ์‹œํ—˜ํŒ ๋˜๋Š” ์•ผ๊ฐ„์œผ๋กœ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค.

@cabal95 ์ €๋Š” ์ด์— ๋Œ€ํ•ด ๋‹ต๋ณ€ํ•  ์ž๊ฒฉ์ด ์—†์ง€๋งŒ ์ถ”์ธกํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๊ฒฐ๊ตญ ๊ตฌํ˜„๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์ด๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด ํ™œ์„ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ๋จธ๋ฆฌ๊ธ€/๋ฐ”๋‹ฅ๊ธ€ ์ž‘์—…์—์„œ ๋ˆ์ ํ•œ ๋‚ด์šฉ์ด ์ œ์™ธ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

SelectionChangedCommandParameter๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€์‹  ์„ ํƒํ•œ ํ•ญ๋ชฉ์„ ์ž๋™์œผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์ด๋Ÿฐ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

public ICommand => new Command<MySelectedItemModel>((item) => {}

ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

public ICommand => new Command<object>((item) =>{ var selectedItem = item as MySelectedItemModel;}

SelectionChangedCommandParameter๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€์‹  ์„ ํƒํ•œ ํ•ญ๋ชฉ์„ ์ž๋™์œผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์ด๋Ÿฐ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

public ICommand => new Command<MySelectedItemModel>((item) => {}

ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

public ICommand => new Command<object>((item) =>{ var selectedItem = item as MySelectedItemModel;}

์‚ฌ์šฉ์ž๊ฐ€ SelectedItem์ด ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฒƒ์„ Command์— ๋Œ€ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

SelectionChangedCommandParameter๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€์‹  ์„ ํƒํ•œ ํ•ญ๋ชฉ์„ ์ž๋™์œผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ์ด๋Ÿฐ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
public ICommand => new Command<MySelectedItemModel>((item) => {}
ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
public ICommand => new Command<object>((item) =>{ var selectedItem = item as MySelectedItemModel;}

์‚ฌ์šฉ์ž๊ฐ€ SelectedItem์ด ์•„๋‹Œ ๋‹ค๋ฅธ ๊ฒƒ์„ Command์— ๋Œ€ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‹น์‹ ์€ ์š”์ ์ด ์žˆ์ง€๋งŒ CollectionView ์ˆ˜์ค€์—์„œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์Šค ์ผ€์ด์Šค๋ฅผ๋ณด๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ ์‚ฌ์šฉํ•  ๋•Œ ์„ ํƒ ํ•ญ๋ชฉ์ด ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์„ ํƒํ•œ ํ•ญ๋ชฉ์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ›๊ฒŒ ๋˜๋ฏ€๋กœ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ๋ช…๋ น์— ๋Œ€ํ•ด์„œ๋„ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด CollectionView๊ฐ€ ์ „์ฒด ํ™”๋ฉด์œผ๋กœ ๋Š˜์–ด๋‚˜์ง€ ์•Š๊ณ  ํ•ญ๋ชฉ ์ˆ˜์— ๋”ฐ๋ผ ๋†’์ด๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ๋„ ์š”์ฒญํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ๋ชฉ๋ก์„ ํ‘œ์‹œํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
์ฆ‰
๊ตฌ๋งค

๊ณต์ œ

์ด
์ด
๋”ํ•˜๋‹ค

๊ทธ๋Ÿฌ๋‚˜ ํ•ญ๋ชฉ 1๊ณผ 2(CollectionView)๋Š” 3~4๊ฐœ์˜ ํ•ญ๋ชฉ๋งŒ ์žˆ๊ณ  ์•„๋ž˜์— BIIIIIIIIIIIIIIIG ๊ฐ„๊ฒฉ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ๊ณต์ œ ์„น์…˜์„ ๋ณด๊ธฐ ์ „์— ๋†’์ด๊ฐ€ ๋„ˆ๋ฌด ๋†’์•„์กŒ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฒฐ๊ตญ StackLayout์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‚ด ์ž์‹ ์˜ ItemsCollection ์ปจํŠธ๋กค์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์ด CollectionView๊ฐ€ ์ „์ฒด ํ™”๋ฉด์œผ๋กœ ๋Š˜์–ด๋‚˜์ง€ ์•Š๊ณ  ํ•ญ๋ชฉ ์ˆ˜์— ๋”ฐ๋ผ ๋†’์ด๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ๋„ ์š”์ฒญํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ๊ฒฐ๊ตญ StackLayout์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‚ด ์ž์‹ ์˜ ItemsCollection ์ปจํŠธ๋กค์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์ด ์ฐพ๊ณ ์žˆ๋Š” ๊ฒƒ์ด Bindable Layouts ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด CollectionView๊ฐ€ ์ „์ฒด ํ™”๋ฉด์œผ๋กœ ๋Š˜์–ด๋‚˜์ง€ ์•Š๊ณ  ํ•ญ๋ชฉ ์ˆ˜์— ๋”ฐ๋ผ ๋†’์ด๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ๋„ ์š”์ฒญํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ๊ฒฐ๊ตญ StackLayout์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‚ด ์ž์‹ ์˜ ItemsCollection ์ปจํŠธ๋กค์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์ด ์ฐพ๊ณ ์žˆ๋Š” ๊ฒƒ์ด Bindable Layouts ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์•ผ! ์ •ํ™•ํžˆ ๋‚ด๊ฐ€ ํ•„์š”ํ•œ ๊ฒƒ. BindableLayout์ด ์–ธ์ œ๋ถ€ํ„ฐ ์กด์žฌํ–ˆ์Šต๋‹ˆ๊นŒ?

์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ํ† ๋ก ํ•ด ์ฃผ์‹  ๋ชจ๋“  ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ์š”์ฒญ์ด๋‚˜ ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ๊ฐ์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ์—ด์–ด์ฃผ์„ธ์š”. ์ด์ œ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰