게임 패드 및 리모컨 조작

keyboard and gamepad image

게임패드, 리모컨, 키보드 간에 많은 상호 작용 경험이 공유됩니다.

게임패드 및 리모컨과 같은 TV 및 Xbox 10피트 환경의 일반적인 입력 유형뿐만 아니라 기존 입력 유형의 PC, 랩톱 및 태블릿(마우스, 키보드, 터치 등)을 통해 앱을 사용하고 액세스할 수 있도록 Windows 애플리케이션에서 상호 작용 환경을 구축합니다.

10피트 환경에서 Windows 애플리케이션에 대한 일반적인 디자인 지침은 Xbox 및 TV용 디자인을 참조하세요.

개요

이 항목에서는 상호 작용 디자인에서 고려해야 할 사항(또는 플랫폼에서 관리하는 경우 고려하지 말아야 할 사항)에 대해 논의하고 디바이스, 입력 유형 또는 사용자 기능 및 기본 설정에 관계없이 사용하기 좋은 Windows 애플리케이션을 구축하기 위한 지침, 권장 사항 및 제안을 제공합니다.

결론적으로 애플리케이션은 10피트 환경에서와 마찬가지로 2피트 환경과 그 반대의 경우에도 직관적이고 사용하기 쉬어야 합니다. 사용자가 기본 설정하는 디바이스를 지원하고, UI 포커스를 명확하고 확실하게 만들고, 탐색이 일관되고 예측 가능하도록 콘텐츠를 정렬하고, 사용자에게 원하는 작업에 대한 최단 경로를 제공합니다.

참고 항목

이 항목에 있는 대부분의 코드 조각은 XAML/C#에 있습니다. 그러나 원칙과 개념은 모든 Windows 앱에 적용됩니다. Xbox용 HTML/JavaScript Windows 앱을 개발 중이라면 GitHub에서 뛰어난 TVHelpers 라이브러리를 확인합니다.

2피트 및 10피트 환경 모두에 최적화

최소한 2피트 및 10피트 시나리오 모두에서 제대로 작동하고 Xbox 게임패드 및 리모컨에서 모든 기능을 검색하고 액세스할 수 있도록 애플리케이션을 테스트하는 것이 좋습니다.

다음은 2피트 및 10피트 환경과 모든 입력 디바이스에서 사용하도록 앱을 최적화할 수 있는 몇 가지 다른 방법입니다(각각 이 항목의 해당 섹션에 대한 링크).

참고 항목

Xbox 게임패드와 리모컨은 많은 Windows 키보드 동작과 경험을 지원하므로 이러한 권장 사항은 두 입력 유형 모두에 적합합니다. 자세한 키보드 정보는 키보드 상호 작용을 참조하세요.

기능 설명
XY 포커스 탐색 및 조작 XY 포커스 탐색을 사용하면 사용자가 앱의 UI를 탐색할 수 있습니다. 그러나 이렇게 하면 사용자의 상하좌우 탐색이 제한됩니다. 이점과 그 외 고려 사항을 처리하는 권장 사항 이 섹션에 설명되어 있습니다.
마우스 모드. XY 포커스 탐색은 맵 또는 그리기 및 페인팅 앱과 같은 일부 유형의 애플리케이션에서는 실용적이지 않거나 불가능합니다. 이러한 경우 마우스 모드를 사용하면 PC의 마우스처럼 게임 패드나 리모컨으로 자유롭게 탐색할 수 있습니다.
포커스 시각적 개체 포커스 시각적 개체는 현재 포커스가 있는 UI 요소를 강조 표시하는 테두리입니다. 이를 통해 사용자는 탐색하거나 상호 작용하는 UI를 빠르게 식별할 수 있습니다.
포커스 연결 포커스 연결을 사용하려면 UI 요소에 포커스가 있을 때 게임패드나 리모컨에서 A/Select 단추를 눌러야 상호 작용할 수 있습니다.
하드웨어 단추 게임패드와 리모컨은 매우 다른 단추와 구성을 제공합니다.

게임 패드 및 원격 제어

키보드와 마우스가 PC용인 것처럼 터치는 휴대폰과 태블릿용이고, 게임 패드와 리모컨은 10피트 환경을 위한 기본 입력 장치입니다. 이 섹션에서는 하드웨어 단추와 그 기능을 소개합니다. XY 포커스 탐색 및 상호 작용마우스 모드에서는 이러한 입력 디바이스를 사용할 때 앱을 최적화하는 방법을 알아봅니다.

바로 사용할 수 있는 게임 패드 및 원격 동작의 품질은 앱에서 키보드가 얼마나 잘 지원되는지에 따라 좌우됩니다. 앱이 게임 패드/리모컨과 잘 작동하는지 확실하게 확인하는 방법은 PC에서 키보드와 잘 작동하는지 확인한 다음 게임 패드/원격으로 테스트하여 UI에서 약점을 찾는 것입니다.

하드웨어 단추

이 문서 전체에서 단추는 다음 다이어그램에 명시된 이름으로 참조됩니다.

Gamepad and remote buttons diagram

다이어그램에서 볼 수 있듯이, 리모컨에서 지원되지 않지만 게임 패드에서는 지원되는 일부 단추가 있으며 그 반대의 경우도 마찬가지입니다. 하나의 입력 디바이스에서만 지원되는 단추를 사용하여 UI를 더 빠르게 탐색할 수 있지만 중요한 상호 작용에 이러한 단추를 사용하면 사용자가 UI의 특정 부분과 상호 작용할 수 없는 상황이 발생할 수 있습니다.

다음 표에는 Windows 앱에서 지원하는 모든 하드웨어 단추와 이를 지원하는 입력 디바이스가 나와 있습니다.

단추 Gamepad 원격 제어
A/선택 단추
B/뒤로 가기 단추
방향 패드(D 패드)
메뉴 단추
보기 버튼
X 및 Y 단추 아니요
왼쪽 스틱 아니요
오른쪽 스틱 아니요
왼쪽 및 오른쪽 트리거 아니요
왼쪽 및 오른쪽 범퍼 아니요
OneGuide 단추
볼륨 단추
채널 단추
미디어 컨트롤 단추
음소거 단추

기본 제공 지원

UWP는 기존의 키보드 입력 동작을 게임 패드 및 리모컨 입력에 자동으로 매핑합니다. 다음 표에는 이러한 기본 제공 매핑이 나와 있습니다.

Keyboard 게임 패드/리모컨
화살표 키 D 패드(게임 패드에서도 왼쪽 스틱)
스페이스바 A/선택 단추
Enter A/선택 단추
Esc B/뒤로 가기 단추*

*B 단추에 대한 KeyDownKeyUp 이벤트가 앱에서 처리되지 않는 경우 SystemNavigationManager.BackRequested 이벤트가 발생하여 앱 내에서 뒤로 탐색됩니다. 그러나 다음 코드 조각에서처럼 직접 구현해야 합니다.

// This code goes in the MainPage class

public MainPage()
{
    this.InitializeComponent();

    // Handling Page Back navigation behaviors
    SystemNavigationManager.GetForCurrentView().BackRequested +=
        SystemNavigationManager_BackRequested;
}

private void SystemNavigationManager_BackRequested(
    object sender,
    BackRequestedEventArgs e)
{
    if (!e.Handled)
    {
        e.Handled = this.BackRequested();
    }
}

public Frame AppFrame { get { return this.Frame; } }

private bool BackRequested()
{
    // Get a hold of the current frame so that we can inspect the app back stack
    if (this.AppFrame == null)
        return false;

    // Check to see if this is the top-most page on the app back stack
    if (this.AppFrame.CanGoBack)
    {
        // If not, set the event to handled and go back to the previous page in the
        // app.
        this.AppFrame.GoBack();
        return true;
    }
    return false;
}

참고 항목

B 단추를 뒤로 가기에 사용하는 경우에는 UI에 뒤로 단추를 표시하지 마세요. 탐색 보기를 사용하는 경우에는 뒤로 단추가 자동으로 숨겨집니다. 뒤로 탐색에 대한 자세한 내용은 Windows 앱의 탐색 기록 및 뒤로 탐색을 참조하세요.

Xbox One의 Windows 앱은 메뉴 단추를 눌러 상황에 맞는 메뉴를 여는 기능을 지원합니다. 자세한 내용은 CommandBar 및 ContextFlyout을 참조하세요.

가속기 지원

가속기 단추는 UI를 통해 탐색 속도를 높일 때 사용할 수 있는 단추입니다. 그러나 이러한 단추는 특정 입력 디바이스에 고유할 수 있으므로 모든 사용자가 이러한 함수를 사용할 수 있는 것은 아닙니다. 실제로 게임패드는 현재 Xbox One에서 Windows 앱의 가속기 기능을 지원하는 유일한 입력 디바이스입니다.

다음 표에는 UWP에 기본 제공되는 가속기 지원과 직접 구현할 수 있는 가속기가 나열되어 있습니다. 사용자 지정 UI에서 이러한 동작을 활용하여 일관되고 친숙한 사용자 환경을 제공합니다.

상호 작용 키보드/마우스 Gamepad 기본 제공: 권장 대상:
페이지 위로/아래로 페이지 위로/아래로 왼쪽/오른쪽 트리거 CalendarView, ListBox, ListViewBase, ListView, ScrollViewer, Selector, LoopingSelector, ComboBox, FlipView 세로 스크롤이 지원되는 보기
페이지 왼쪽/오른쪽 None 왼쪽/오른쪽 범퍼 ListBox, ListViewBase, ListView, ScrollViewer, Selector, LoopingSelector, FlipView 가로 스크롤이 지원되는 보기
확대/축소 Ctrl +/- 왼쪽/오른쪽 트리거 None ScrollViewer, 확대 및 축소를 지원하는 보기
탐색 창 열기/닫기 None 보기 None 탐색 패널
검색 None Y 버튼 None 앱의 기본 검색 함수에 대한 바로 가기
상황에 맞는 메뉴 열기 그런 다음 메뉴 단추 ContextFlyout 상황에 맞는 메뉴

XY 포커스 탐색 및 조작

앱에서 키보드용 적절한 포커스 탐색을 지원하는 경우에는 게임 패드 및 리모컨으로 잘 변환됩니다. 화살표 키를 사용하는 탐색은 D 패드(게임 패드의 왼쪽 스틱)에 매핑되고 UI 요소와의 상호 작용은 Enter/Select 키(게임 패드 및 원격 제어 참조)에 매핑됩니다.

많은 이벤트와 속성은 키보드와 게임 패드 둘 다에서 사용됩니다.둘 다 KeyDownKeyUp 이벤트를 발생시키며 IsTabStop="True"Visibility="Visible" 속성이 있는 컨트롤만 탐색합니다. 키보드 디자인 지침은 키보드 조작을 참조하세요.

키보드 지원이 제대로 구현되면 앱이 제대로 작동하지만 모든 시나리오를 지원하는 데 몇 가지 작업이 더 필요할 수 있습니다. 가능한 최상의 사용자 환경을 제공해야 하는 앱의 특정 요구 사항을 생각해 보세요.

Important

마우스 모드는 Xbox One에서 실행되는 Windows 앱에 대해 기본적으로 사용하도록 설정되어 있습니다. 마우스 모드를 사용하지 않도록 설정하고 XY 포커스 탐색을 사용하도록 설정하려면 Application.RequiresPointerMode=WhenRequested를 설정합니다.

포커스 문제 디버깅

FocusManager.GetFocusedElement 메서드는 현재 포커스가 있는 요소를 알려줍니다. 이것은 포커스 시각적 개체의 위치가 명확하지 않을 수 있는 경우에 유용합니다. 다음과 같이 Visual Studio 출력 창에 이 정보를 기록할 수 있습니다.

page.GotFocus += (object sender, RoutedEventArgs e) =>
{
    FrameworkElement focus = FocusManager.GetFocusedElement() as FrameworkElement;
    if (focus != null)
    {
        Debug.WriteLine("got focus: " + focus.Name + " (" +
            focus.GetType().ToString() + ")");
    }
};

XY 탐색이 예상대로 작동하지 않는 세 가지 공통된 이유가 있습니다.

  • IsTabStop 또는 Visibility 속성이 잘못 설정되었습니다.
  • 포커스를 받는 컨트롤이 실제로 예상보다 더 큽니다. XY 탐색은 흥미로운 사항을 렌더링하는 컨트롤의 일부만이 아니라 컨트롤의 총 크기(ActualWidthActualHeight)를 확인합니다.
  • 포커스 가능한 컨트롤이 다른 컨트롤 위에 있습니다. XY 탐색은 겹치는 컨트롤을 지원하지 않습니다.

이러한 문제를 해결한 후에도 XY 탐색이 예상대로 작동하지 않는 경우 기본 탐색 재정의에 설명된 메서드를 사용하여 포커스를 가져올 요소를 수동으로 가리킬 수 있습니다.

XY 탐색이 의도한 대로 작동하지만 포커스 시각적 개체가 표시되지 않는 경우 다음 문제 중 하나가 원인일 수 있습니다.

  • 컨트롤을 다시 템플릿으로 작성했으며 포커스 시각적 개체를 포함하지 않았습니다. UseSystemFocusVisuals="True"를 설정하거나 포커스 시각적 개체를 수동으로 추가합니다.
  • Focus(FocusState.Pointer)를 호출하여 포커스를 이동했습니다. FocusState 매개 변수는 포커스 시각적 개체에 발생하는 작업을 제어합니다. 일반적으로 이것을 FocusState.Programmatic로 설정해야 하는데, 포커스 시각적 개체가 이전에 표시되었으면 계속 표시되고, 이전에 숨겨진 경우에는 계속 숨겨집니다.

이 섹션의 나머지 부분에서는 XY 탐색을 사용할 때 발생하는 일반적인 디자인 문제에 대해 자세히 설명하고 이를 해결하는 여러 가지 방법을 제공합니다.

액세스할 수 없는 UI

XY 포커스 탐색은 사용자가 상하좌우로 이동하는 것을 제한하므로 UI의 일부에 액세스할 수 없는 시나리오가 발생할 수 있습니다. 다음 다이어그램은 XY 포커스 탐색에서 지원하지 않는 UI 레이아웃의 예를 보여줍니다. 세로 및 가로 탐색의 우선 순위가 지정되고 가운데 요소가 포커스를 얻기에 충분히 높지 않으므로 중간에 있는 요소는 게임 패드/리모컨을 사용하여 액세스할 수 없습니다.

Elements in four corners with inaccessible element in middle

어떤 이유로 UI를 다시 정렬할 수 없는 경우 다음 섹션에서 다루는 기술 중 하나를 사용하여 기본 포커스 동작을 재정의합니다.

기본 탐색 재정의

유니버설 Windows 플랫폼 D 패드/왼쪽 스틱 탐색이 사용자에게 적합한지 확인하려고 하지만 앱의 의도에 최적화된 동작을 보장할 수는 없습니다. 탐색이 앱에 최적화되도록 하는 가장 좋은 방법은 게임 패드를 사용하여 테스트하고 앱 시나리오에 적합한 방식으로 사용자가 모든 UI 요소에 액세스할 수 있는지 확인하는 것입니다. 앱의 시나리오에서 제공된 XY 포커스 탐색을 통해 달성되지 않는 동작을 요구하는 경우 다음 섹션의 권장 사항을 따르거나 동작을 재정의하여 논리 항목에 포커스를 배치하는 것이 좋습니다.

다음 코드 조각은 XY 포커스 탐색 동작을 재정의할 수 있는 방법을 보여줍니다.

<StackPanel>
    <Button x:Name="MyBtnLeft"
            Content="Search" />
    <Button x:Name="MyBtnRight"
            Content="Delete"/>
    <Button x:Name="MyBtnTop"
            Content="Update" />
    <Button x:Name="MyBtnDown"
            Content="Undo" />
    <Button Content="Home"  
            XYFocusLeft="{x:Bind MyBtnLeft}"
            XYFocusRight="{x:Bind MyBtnRight}"
            XYFocusDown="{x:Bind MyBtnDown}"
            XYFocusUp="{x:Bind MyBtnTop}" />
</StackPanel>

이 경우 포커스가 Home 단추에 있고 사용자가 왼쪽으로 이동하면 포커스가 MyBtnLeft 단추로 이동합니다. 사용자가 오른쪽으로 이동하면 포커스가 MyBtnRight 단추로 이동됩니다.

포커스가 특정 방향으로 컨트롤에서 이동하지 않도록 하려면 XYFocus* 속성을 사용하여 동일한 컨트롤을 가리킵니다.

<Button Name="HomeButton"  
        Content="Home"  
        XYFocusLeft ="{x:Bind HomeButton}" />

이러한 XYFocus 속성을 사용하면 포커스가 있는 자식이 동일한 XYFocus 속성을 사용하지 않는 한 다음 포커스 후보가 시각적 트리에서 벗어날 때 컨트롤 부모가 자식 탐색을 강제로 수행할 수도 있습니다.

<StackPanel Orientation="Horizontal" Margin="300,300">
    <UserControl XYFocusRight="{x:Bind ButtonThree}">
        <StackPanel>
            <Button Content="One"/>
            <Button Content="Two"/>
        </StackPanel>
    </UserControl>
    <StackPanel>
        <Button x:Name="ButtonThree" Content="Three"/>
        <Button Content="Four"/>
    </StackPanel>
</StackPanel>

위의 샘플에서 포커스가 Button Two에 있고 사용자가 오른쪽으로 이동하는 경우 가장 적합한 포커스 후보는 Button Four입니다. 그러나 포커스는 시각적 트리에서 벗어날 때 부모가 UserControl강제로 탐색하도록 하기 때문에 Button Three로 이동됩니다.

최소 클릭 경로

사용자가 최소 클릭 수로 가장 일반적인 작업을 수행할 수 있도록 해봅니다. 다음 예제에서 TextBlock은 우선 순위 작업 사이에 불필요한 요소가 배치되도록 재생 단추(처음에는 포커스를 가져오는)와 일반적으로 사용되는 요소 사이에 배치됩니다.

Navigation best practices provide path with least clicks

다음 예제에서는 TextBlock이 대신 재생 단추 위에 배치됩니다. 우선 순위 작업 사이에 불필요한 요소가 배치되지 않도록 UI를 다시 배열하면 앱의 유용성이 크게 향상됩니다.

TextBlock moved above Play button so that it is no longer between priority tasks

CommandBar 및 ContextFlyout

CommandBar사용하는 경우 문제: 긴 스크롤 목록/그리드 후에 있는 UI 요소에 언급된 목록을 스크롤하는 문제를 명심해야 합니다. 다음 이미지는 목록/그리드의 맨 아래에 CommandBar가 있는 UI 레이아웃을 보여줍니다. 사용자는 목록/그리드를 통해 아래로 끝까지 스크롤하여 CommandBar에 도달해야 합니다.

CommandBar at bottom of list/grid

CommandBar를 목록/그리드 위에 배치하면 어떻게 될까요? 목록/그리드 아래로 스크롤한 사용자는 다시 위로 스크롤하여 CommandBar에 도달해야 하지만 이전 구성보다 탐색이 약간 적습니다. 이는 앱의 초기 포커스가 CommandBar 옆이나 위에 배치된 것으로 가정하는데, 초기 포커스가 목록/그리드 밑에 있으면 이 방식이 잘 작동하지 않습니다. 이러한 CommandBar 항목이 자주 액세스할 필요가 없는 전역 작업 항목인 경우(예: 동기화 단추), 목록/그리드 위에 해당 항목을 두는 것이 허용될 수 있습니다.

CommandBar의 항목을 세로로 쌓을 수는 없지만 스크롤 방향(예: 세로 스크롤 목록의 왼쪽 또는 오른쪽 또는 가로 스크롤 목록의 위쪽 또는 아래쪽)에 배치하는 것은 UI 레이아웃에 적합한지 고려할 수 있는 또 다른 옵션입니다.

앱에 사용자가 항목에 쉽게 액세스할 수 있어야 하는 CommandBar이 있는 경우 이러한 항목을 ContextFlyout 내에 배치하고 해당 항목을 CommandBar에서 제거하는 것이 좋습니다. ContextFlyoutUIElement의 속성이며 해당 요소와 관련된 상황에 맞는 메뉴입니다. PC에서 ContextFlyout가 있는 요소를 마우스 오른쪽 단추로 클릭하면 컨텍스트 메뉴가 나타납니다. Xbox One에서는 포커스가 이러한 요소에 있는 동안 메뉴 단추를 누를 때 발생합니다.

UI 레이아웃 문제

일부 UI 레이아웃은 XY 포커스 탐색의 특성으로 인해 더 어려우며 사례별로 평가해야 합니다. 하나의 "올바른" 방법은 없으며 선택하는 솔루션이 앱의 특정 요구 사항에 부합하지만 훌륭한 TV 환경을 만들기 위해 사용할 수 있는 몇 가지 기술이 있습니다.

이를 더 잘 이해하기 위해 이러한 문제 및 이를 극복하기 위한 몇 가지 기술을 설명하는 가상 앱을 살펴보겠습니다.

참고 항목

이 가짜 앱은 UI 문제 및 잠재적 해결 방법을 설명하기 위한 것이지 특정 앱에 가장 적합한 사용자 환경을 표시하기 위한 것이 아닙니다.

다음은 판매 가능한 주택 목록, 지도, 부동산 설명 및 기타 정보를 보여주는 가상의 부동산 앱입니다. 이 앱은 다음 기술을 사용하여 해결할 수 있는 세 가지 문제를 제기합니다.

Fake real estate app

문제: 긴 스크롤 목록/그리드 후에 있는 UI 요소

다음 이미지에 표시된 속성의 ListView는 매우 긴 스크롤 목록입니다. 사용자가 목록으로 이동할 때 ListView연결이 필요하지 않은 경우 목록의 첫 항목에 포커스가 배치됩니다. 사용자가 이전 또는 다음 단추에 도달하려면 목록의 모든 항목을 통과해야 합니다. 이처럼 사용자가 전체 목록을 트래버스하는 것이 힘든 경우, 즉, 이러한 경험이 허용될 만큼 목록이 짧지 않은 경우에는 다른 옵션을 고려하는 것이 좋습니다.

Real estate app: list with 50 items takes 51 clicks to reach buttons below

해결 방법

UI 다시 정렬

페이지 맨 아래에 초기 포커스가 배치되지 않는 한 긴 스크롤 목록 위에 배치된 UI 요소는 일반적으로 아래에 배치된 경우보다 액세스하기가 더 쉽습니다. 이 새로운 레이아웃이 다른 장치에서 작동하는 경우 Xbox One만 특별한 UI 변경을 수행하지 않고 모든 디바이스 패밀리의 레이아웃을 변경하는 것이 비용이 적게 드는 방법일 수 있습니다. 그리고 스크롤 방향(즉, 세로 스크롤 목록은 가로로, 가로 스크롤 목록은 세로로)에 UI 요소를 배치하면 접근성이 훨씬 향상됩니다.

Real estate app: place buttons above long scrolling list

포커스 연결

연결이 필요한 경우 전체 ListView가 단일 포커스 대상이 됩니다. 사용자는 목록의 내용을 바이패스하여 포커스 가능한 그 다음 요소로 갈 수 있습니다. 연결을 지원하는 컨트롤과 포커스 연결에서 이를 사용하는 방법에 대해 자세히 알아보세요.

Real estate app: set engagement to required so that it only takes 1 click to reach Previous/Next buttons

문제: 포커스 가능한 요소가 없는 ScrollViewer

XY 포커스 탐색은 한 번에 하나의 포커스 가능한 UI 요소로 이동하는 데 의존하기 때문에 포커스 가능한 요소가 없는 ScrollViewer(예: 이 예제와 같이 텍스트만 있는 요소)는 ScrollViewer에서 사용자가 모든 콘텐츠를 볼 수 없는 시나리오를 일으킬 수 있습니다. 이 시나리오 및 기타 관련 시나리오에 대한 해결 방법은 포커스 연결을 참조하세요.

Real estate app: ScrollViewer with only text

문제: 자유 스크롤 UI

앱에 드로잉 화면과 같은 자유롭게 스크롤되는 UI가 필요한 경우 또는 이 예제처럼 맵에서는 XY 포커스 탐색이 작동하지 않습니다. 이 경우 마우스 모드를 설정하여 사용자가 UI 요소 내에서 자유롭게 탐색할 수 있도록 할 수 있습니다.

Map UI element using mouse mode

마우스 모드.

XY 포커스 탐색 및 상호 작용에 설명된 대로 Xbox One에서는 XY 탐색 시스템을 사용하여 포커스가 이동되므로 사용자가 위쪽, 아래쪽, 왼쪽 및 오른쪽으로 이동하여 컨트롤에서 컨트롤로 포커스를 이동할 수 있습니다. 그러나 WebViewMapControl과 같은 일부 컨트롤에는 사용자가 컨트롤 경계 내에서 포인터를 자유롭게 이동할 수 있는 마우스와 유사한 상호 작용이 필요합니다. 또한 사용자가 마우스를 사용하여 PC에서 찾을 수 있는 것과 유사한 게임 패드/리모컨을 통해 포인터를 전체 페이지로 이동할 수 있는 것이 적합한 앱도 있습니다.

이러한 시나리오는 전체 페이지 또는 페이지 내의 컨트롤에 대한 포인터(마우스 모드)를 요청해야 합니다. 예를 들어, 앱에 컨트롤 내부에 있는 동안에만 마우스 모드를 사용하는 WebView 컨트롤이 있는 페이지가 있고 다른 곳에서는 XY 포커스 탐색이 있을 수 있습니다. 포인터를 요청하려면 컨트롤 또는 페이지가 연결될 때 또는 페이지에 포커스가 있을 때 이것이 필요한지 여부를 지정할 수 있습니다.

참고 항목

컨트롤이 포커스를 받을 때 포인터를 요청하는 것은 지원되지 않습니다.

Xbox One에서 실행되는 XAML 및 호스트된 웹앱 모두 전체 앱에 대해 기본적으로 마우스 모드가 설정됩니다. 이를 해제하고 XY 탐색용으로 앱을 최적화하는 것이 좋습니다. 이렇게 하려면 컨트롤 또는 페이지가 호출할 때만 마우스 모드를 사용하도록 Application.RequiresPointerMode 속성을 WhenRequested로 설정합니다.

XAML 앱에서 이 작업을 수행하려면 App 클래스에서 다음 코드를 사용합니다.

public App()
{
    this.InitializeComponent();
    this.RequiresPointerMode =
        Windows.UI.Xaml.ApplicationRequiresPointerMode.WhenRequested;
    this.Suspending += OnSuspending;
}

HTML/JavaScript용 샘플 코드를 비롯한 자세한 내용은 마우스 모드를 사용하지 않도록 설정하는 방법을 참조하세요.

다음 다이어그램은 마우스 모드에서 게임 패드/리모컨에 대한 단추 매핑을 보여줍니다.

Button mappings for gamepad/remote in mouse mode

참고 항목

마우스 모드는 게임 패드/리모컨이 있는 Xbox One에서만 지원됩니다. 다른 디바이스 패밀리 및 입력 형식에서는 자동으로 무시됩니다.

컨트롤 또는 페이지의 RequiresPointer 속성을 사용하여 마우스 모드를 활성화합니다. 이 속성에 사용 가능한 세 가지 값은 Never(기본값), WhenEngagedWhenFocused입니다.

컨트롤에서 마우스 모드 활성화

사용자가 컨트롤을 RequiresPointer="WhenEngaged"에 연결하면 사용자가 컨트롤을 해제할 때까지 컨트롤에서 마우스 모드가 활성화됩니다. 다음 코드 조각은 연결 시 마우스 모드를 활성화하는 간단한 MapControl를 보여줍니다.

<Page>
    <Grid>
        <MapControl IsEngagementRequired="true"
                    RequiresPointer="WhenEngaged"/>
    </Grid>
</Page>

참고 항목

컨트롤이 연결될 때 마우스 모드를 활성화하는 경우 IsEngagementRequired="true"와 연결이 필요해야 합니다. 그렇지 않으면 마우스 모드가 활성화되지 않습니다.

컨트롤이 마우스 모드인 경우 중첩된 컨트롤도 마우스 모드에 있게 됩니다. 요청된 자식 모드는 무시됩니다. 부모가 마우스 모드인데, 자식이 마우스 모드가 아닌 경우는 불가능합니다.

또한 컨트롤의 요청된 모드는 포커스를 받을 때만 검사되므로 포커스가 있는 동안에는 모드가 동적으로 변경되지 않습니다.

페이지에서 마우스 모드 활성화

페이지에 RequiresPointer="WhenFocused"속성이 있으면 포커스를 받을 때 전체 페이지에 대해 마우스 모드가 활성화됩니다. 다음 코드 조각은 이 속성을 페이지에 제공하는 방법을 보여줍니다.

<Page RequiresPointer="WhenFocused">
    ...
</Page>

참고 항목

WhenFocused 값은 Page 개체에서만 지원됩니다. 컨트롤에서 이 값을 설정하려고 하면 예외가 throw됩니다.

전체 화면 콘텐츠에 마우스 모드를 사용하지 않도록 설정

일반적으로 비디오 또는 다른 형식의 콘텐츠를 전체 화면에 표시할 때 커서를 숨겨야 하는데 사용자에게 방해가 될 수 있기 때문입니다. 이 시나리오는 나머지 앱에서 마우스 모드를 사용할 때 발생하지만 전체 화면 콘텐츠를 표시할 때는 해제해야 합니다. 이렇게 하려면 전체 화면 콘텐츠를 자체 Page로 배치하고 아래 단계를 수행합니다.

  1. App 개체에서 RequiresPointerMode="WhenRequested"를 설정합니다.
  2. 모든 Page 개체에서(전체 화면의 제외) PageRequiresPointer="WhenFocused"을 설정합니다.
  3. 전체 화면 Page의 경우 RequiresPointer="Never"을 설정합니다.

이렇게 하면 전체 화면 콘텐츠를 표시할 때 커서가 나타나지 않습니다.

포커스 시각적 개체

포커스 시각적 개체는 현재 포커스가 있는 UI 요소 주위의 테두리입니다. 이것은 사용자가 길을 잃지 않고 UI를 쉽게 탐색할 수 있도록 방향을 잡는 데 도움이 됩니다.

시각적 업데이트와 포커스 시각적 개체에 추가된 수많은 사용자 지정 옵션을 통해 개발자는 단일 포커스 시각적 개체가 PC 및 Xbox One뿐만 아니라 키보드 및/또는 게임 패드/원격을 지원하는 다른 Windows 장치에서도 잘 작동한다고 신뢰할 수 있습니다.

동일한 포커스 시각적 개체를 여러 플랫폼에서 사용할 수 있지만 사용자가 마주치는 컨텍스트는 10피트 환경과 약간 다릅니다. 사용자가 전체 TV 화면에 완전히 집중하지 않는다고 가정해야 하므로 시각적 개체를 검색할 때의 답답함을 피하기 위해 현재 포커스가 있는 요소가 사용자에게 명확하게 표시되는 것이 중요합니다.

또한 키보드가 아닌 게임 패드 또는 리모컨을 사용할 때는 포커스 시각적 개체가 기본적으로 표시됩니다. 따라서 이를 구현하지 않더라도 Xbox One에서 앱을 실행할 때 표시됩니다.

초기 포커스 시각적 개체 배치

앱을 시작하거나 페이지로 이동할 때 사용자가 조치를 취할 첫 번째 요소로 적합한 UI 요소에 포커스를 놓습니다. 예를 들어, 사진 앱은 갤러리의 첫 번째 항목에 포커스를 배치할 수 있으며, 노래의 상세 보기로 이동한 음악 앱은 음악 재생의 용이성을 위해 재생 단추에 포커스를 배치할 수 있습니다.

앱의 왼쪽 상단 영역(또는 오른쪽에서 왼쪽 흐름의 경우 오른쪽 상단)에 초기 포커스를 배치해봅니다. 대부분의 사용자는 앱 콘텐츠 흐름이 일반적으로 시작되는 위치이기 때문에 먼저 해당 코너에 집중하는 경향이 있습니다.

포커스를 명확하게 표시

사용자가 포커스를 검색하지 않고 중단한 위치를 선택할 수 있도록 화면에 항상 하나의 포커스 시각적 개체가 표시되어야 합니다. 마찬가지로, 항상 화면에 포커스 가능 항목이 있어야 합니다. 예를 들어 텍스트만 있고 포커스 가능 요소가 없는 팝업은 사용하지 마세요.

이 규칙의 예외는 비디오 시청 또는 이미지 보기와 같은 전체 화면 환경에 대한 것이며, 이 경우 포커스 시각적 개체를 표시하는 것이 적절하지 않습니다.

포커스 표시

포커스 표시는 사용자가 게임 패드 또는 키보드 포커스를 이동하면 단추 같이 포커스를 맞출 수 있는 요소의 테두리를 애니메이션화하는 조명 효과입니다. 포커스 표시에서 포커스를 맞춘 요소의 경계 주위로 빛 애니메이션을 적용하면 포커스가 어디에 있는지, 그리고 포커스가 어디로 이동하는지 쉽게 알아볼 수 있습니다.

포커스 표시는 기본적으로 꺼져 있습니다. 10피트 환경에서는 앱 생성자에서 Application.FocusVisualKind 속성을 설정하여 포커스를 표시하도록 선택해야 합니다.

    if(AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Xbox")
    {
        this.FocusVisualKind = FocusVisualKind.Reveal;
    }

자세한 내용은 포커스 표시 지침을 참조하세요.

포커스 시각적 개체 사용자 지정

포커스 시각적 개체를 사용자 지정하려면 각 컨트롤의 포커스 시각적 개체와 관련된 속성을 수정하여 이 작업을 수행하면 됩니다. 앱을 개인 설정하기 위해 활용할 수 있는 몇 가지 속성이 있습니다.

시각적 상태를 사용하여 직접 그려 시스템 제공 포커스 시각적 개체를 옵트아웃할 수도 있습니다. 자세한 내용은 VisualState를 참조하세요.

라이트 해제 오버레이

사용자가 현재 게임 컨트롤러 또는 리모컨으로 조작하는 UI 요소에 집중하도록 UWP는 Xbox One에서 앱을 실행할 경우 팝업 UI 외부 영역을 덮는 "연기" 계층을 자동으로 추가합니다. 이 경우 추가 작업은 필요하지 않지만 UI를 디자인할 때 유의해야 할 사항입니다. 모든 FlyoutBase에서 LightDismissOverlayMode 속성을 설정하여 스모크 계층을 사용하도록 설정하거나 사용하지 않도록 설정할 수 있습니다. 이것은 기본적으로 Auto로 설정되어 Xbox에서 사용하도록 설정되고 그 외에서는 사용하지 않도록 설정됩니다. 자세한 내용은 모달 및 라이트 해제를 참조하세요.

포커스 연결

포커스 연결은 게임 패드 또는 원격을 더 쉽게 사용하여 앱과 상호 작용할 수 있도록 하기 위한 것입니다.

참고 항목

포커스 연결을 설정해도 키보드 또는 다른 입력 장치에는 영향을 주지 않습니다.

FrameworkElement 개체의 IsFocusEngagementEnabled 속성이 True로 설정된 경우 컨트롤을 포커스 연결이 필요한 것으로 표시합니다. 즉, 사용자가 A/선택 단추를 눌러 컨트롤을 "연결"하고 상호 작용해야 합니다. 작업이 완료되면 B/뒤로 단추를 눌러 컨트롤을 해제하고 밖으로 이동할 수 있습니다.

참고 항목

IsFocusEngagementEnabled는 새로운 API로, 아직 문서화되지 않았습니다.

포커스 트래핑

포커스 트래핑은 사용자가 앱의 UI를 탐색하려고 하지만 컨트롤 내에서 "트래핑"되어 해당 컨트롤 외부로 이동하기 어렵거나 불가능할 때 발생합니다.

다음 예제는 포커스 트래핑을 만드는 UI를 보여줍니다.

Buttons to the left and right of a horizontal slider

사용자가 왼쪽 단추에서 오른쪽 단추로 이동하려는 경우 D 패드/왼쪽 스틱을 두 번 누르기만 하면 된다고 가정하는 것이 논리적일 것입니다. 그러나 슬라이더에 연결이 필요하지 않은 경우 다음과 같은 동작이 발생합니다. 사용자가 처음 누르면 포커스가 Slider로 이동하고 다시 오른쪽을 누르면 Slider의 핸들이 오른쪽으로 이동합니다. 사용자는 핸들을 오른쪽으로 계속 이동해도 단추에 닿을 수 없게 될 것입니다.

이 문제를 해결하는 방법에는 여러 가지가 있습니다. 하나는 XY 포커스 탐색 및 상호 작용의 부동산 앱 예제와 유사하게 다른 레이아웃을 디자인하는 것입니다. 여기서 이전다음 단추를 ListView 위의 위치로 이동했습니다. 다음 이미지와 같이 컨트롤을 가로가 아닌 세로로 쌓으면 문제가 해결됩니다.

Buttons above and below a horizontal slider

이제 사용자는 D 패드/왼쪽 스틱에서 위아래로 눌러 각 컨트롤로 이동할 수 있으며 Slider에 포커스가 있는 경우 왼쪽과 오른쪽을 눌러 예상대로 Slider 핸들을 이동할 수 있습니다.

이 문제를 해결하는 또 다른 방법은 Slider에 대한 연결을 요구하는 것입니다. IsFocusEngagementEnabled="True"를 설정하는 경우 다음과 같은 동작이 발생합니다.

Requiring focus engagement on slider so user can navigate to button on the right

Slider에 포커스 연결이 필요한 경우 사용자는 D 패드/왼쪽 스틱에서 오른쪽을 두 번 눌러 오른쪽의 단추에 도착할 수 있습니다. 이 해법은 UI 조정이 필요하지 않고 예상 동작을 생성하기 때문에 유용합니다.

항목 컨트롤

슬라이더 컨트롤 외에도 다음과 같이 연결을 요구할 수 있는 다른 컨트롤이 있습니다.

Slider 컨트롤과 달리 이러한 컨트롤은 자체 내에서 포커스를 트래핑하지 않지만 많은 양의 데이터를 포함할 때 유용성 문제를 일으킬 수 있습니다. 다음은 많은 양의 데이터를 포함하는 ListView의 예제입니다.

ListView with large amount of data and buttons above and below

Slider 예제와 마찬가지로 맨 위에 있는 단추에서 게임 패드/리모컨을 사용하여 맨 아래의 단추로 이동해 보겠습니다. 위쪽 단추의 포커스부터 D 패드/스틱을 누르면 포커스가 ListView의 첫 번째 항목("항목 1")에 배치합니다. 사용자가 다시 누르면 하단 단추가 아니라 목록의 그 다음 항목이 포커스를 받습니다. 단추로 이동하려면 사용자가 먼저 ListView의 모든 항목을 탐색해야 합니다. ListView에 많은 양의 데이터가 포함된 경우 이는 불편할 수 있으며 최적의 사용자 환경이 아닐 수 있습니다.

이 문제를 해결하려면 이에 대한 연결을 요구하도록 ListView에서 IsFocusEngagementEnabled="True" 속성을 설정합니다. 이렇게 하면 사용자가 간단히 눌러 빠르게 ListView를 건너뛸 수 있습니다. 그러나 포커스가 있을 때 A/Select 단추를 누른 다음 B/뒤로 단추를 눌러 연결을 해제하지 않으면 목록을 스크롤하거나 항목을 선택할 수 없습니다.

ListView with engagement required

ScrollViewer

고려해야 할 고유한 단점이 있는 ScrollViewer은 이러한 컨트롤과 약간 다릅니다. 포커스 가능한 콘텐츠가 있는 ScrollViewer가 있는 경우 기본적으로 ScrollViewer로 이동하면 포커스 가능한 요소를 이동할 수 있습니다. ListView와 같이 각 항목을 스크롤하여 ScrollViewer의 바깥쪽을 탐색해야 합니다.

ScrollViewer에 포커스 가능한 콘텐츠가 없는 경우(예: 텍스트만 포함된 경우) 사용자가 A/선택 단추를 사용하여 ScrollViewer를 사용할 수 있도록 IsFocusEngagementEnabled="True"를 설정할 수 있습니다. 작업이 완료되면 D 패드/왼쪽 스틱을 사용하여 텍스트를 스크롤한 다음 B/뒤로 단추를 눌러 작업이 완료되면 해제할 수 있습니다.

또 다른 방법은 사용자가 컨트롤을 연결할 필요가 없도록 ScrollViewerIsTabStop="True"를 설정하는 것입니다. 사용자는 포커스를 배치한 다음 ScrollViewer 내에 포커스 가능 요소가 있을 경우 D-패드/왼쪽 스틱을 사용하여 스크롤하면 됩니다.

포커스 연결 기본값

일부 컨트롤은 포커스 트래핑을 발생시켜 포커스 연결을 요구하는 기본 설정을 보증하는 반면, 다른 컨트롤은 기본적으로 포커스 참여를 해제하지만 켜는 것이 도움이 될 수 있습니다. 다음 표에는 이러한 컨트롤과 기본 포커스 연결 동작이 나열되어 있습니다.

제어 포커스 연결 기본값
CalendarDatePicker 설정
FlipView 끄기
GridView 끄기
ListBox 끄기
ListView 끄기
ScrollViewer 끄기
SemanticZoom 끄기
슬라이더 설정

다른 모든 Windows 컨트롤은 IsFocusEngagementEnabled="True"일 때 동작 또는 시각적 변경이 없습니다.

요약

특정 디바이스 또는 환경에 최적화된 Windows 애플리케이션을 빌드할 수 있지만, 유니버설 Windows 플랫폼을 사용하면 2피트 및 10피트 환경 모두에서 입력 디바이스나 사용자 기능에 관계없이 여러 디바이스에서 성공적으로 사용할 수 있는 앱을 빌드할 수도 있습니다. 이 문서의 권장 사항을 사용하면 앱이 TV와 PC 모두에서 최상의 상태로 유지되도록 할 수 있습니다.