스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
오른쪽에서 왼쪽으로
Game Center 활동 대시보드가 게임에 새로운 플레이어를 유치하는 데 어떻게 도움이 될 수 있는지 확인하세요. 대시보드 및 프로필에 대해 소개하고 이를 통해 게임에서 플레이어 업적, 고득점, 리더보드 변경을 추적하는 방법에 대해 살펴보겠습니다. 또한 Game Center 플러그인을 사용하여 Unity 게임 프로젝트에 Game Center를 추가하는 방법을 보여드립니다.
리소스
관련 비디오
WWDC22
WWDC21
-
다운로드
안녕하세요, Rich입니다 오른쪽에서 왼쪽 언어 지원을 도와드리겠습니다 이미 여러 언어로 애플리케이션을 현지화하셨을 텐데, 가장 일반적인 유럽 언어와 아시아 언어가 사용되죠 이제 아랍어와 히브리어 현지화도 필요합니다 좋은 선택입니다 아랍어는 Apple 플랫폼에서 가장 흔한 10가지 언어 중 하나인데 다른 언어를 개발할 때와는 다른 몇 가지 문제가 있습니다 아랍어와 히브리어 같은 언어로 현지화하도록 애플리케이션을 개발하는 방법에 대한 문제입니다 아랍어와 히브리어는 가장 일반적으로 사용되는 ‘오른쪽에서 왼쪽으로 쓰는’ 문자입니다 왜 그렇게 부를까요? 영어, 프랑스어, 중국어, 태국어 등 대부분의 언어는 이렇게 왼쪽에서 오른쪽으로 쓰는 문자입니다 히브리어 문자는 오른쪽에서 왼쪽으로 씁니다 아랍어도 마찬가지로 문자가 필기체로 결합됩니다 ‘살람’의 네 글자는 각각 쓰면 이렇게 보입니다
아랍어와 히브리어만 그런 것은 아닙니다 Apple은 실제로 오른쪽에서 왼쪽 언어 글꼴과 키보드를 15개 지원합니다 히브리어 텍스트 문단입니다 히브리어 버전의 Numbers용 ‘공식 및 함수 도움말’ 페이지를 가져왔습니다 텍스트가 오른쪽은 정렬되어 있고 왼쪽은 고르지 못한데 마지막 한 줄을 포함한 여러 행에 왼쪽에 구두점이 있습니다 숫자도 있죠 숫자도 왼쪽에서 오른쪽입니다 Numbers가 250개 이상의 기능을 지원한다는 것을 알 수 있습니다 시야를 넓혀서 다른 문단까지 보면 여기에 영어 단어와 iWork의 이름, 구성 애플리케이션 Pages, Numbers Keynote까지 확인할 수 있죠 왼쪽에서 오른쪽으로 쓰여 있고 히브리어 단락에서도 그렇습니다 대부분의 텍스트는 양방향인데 아랍어와 히브리어의 고유한 특성입니다 그래서 ’비디(bidi)’언어라고도 합니다
시야를 더 넓혀 보면 전체 페이지가 오른쪽에서 왼쪽으로 배치되어 있습니다 이 테이블의 텍스트는 이미지의 왼쪽이 아니라 오른쪽에 있습니다
더 넓혀서 Safari의 창 프레임을 보면 콘텐츠로 끝나지 않습니다 아랍어와 히브리어 텍스트의 줄이 오른쪽에서 왼쪽으로 진행되어 다른 UI 요소도 비슷할 것으로 예상됩니다 사용자가 왼쪽에서 오른쪽으로 진행되기를 예상하는 것처럼 아랍어와 히브리어 사용자는 반대를 예상합니다 여기에서 Safari의 도구 모음은 오른쪽 상단 모서리에 신호등 버튼이 있고 버튼은 왼쪽으로 향합니다 전체 화면을 보기 위해 시야를 넓히면 모든 방향으로 확장됩니다 Numbers의 도움말 화면인데 Numbers의 요소가 반대입니다 사이드바도 왼쪽에 있죠 탭 바도 오른쪽에서 왼쪽입니다 문서 자체도 반대입니다 Mac 메뉴 바와 Dock도 오른쪽에서 왼쪽으로 실행됩니다 이렇게 하는 작업은 복잡할 수 있는데 다행히 Apple이 대부분 대신 해드립니다 오른쪽에서 왼쪽 언어 지원은 무료로 제공됩니다 하지만 주의사항이 있습니다 지금부터 말씀드릴 시스템이 지원하는 기능과 옵트인이나 옵트아웃을 할 경우 그리고 오른쪽에서 왼쪽 지원을 구현할 때 고려해야 할 사항입니다 텍스트, 이미지, 제어 방향 UI 레이아웃을 살펴보겠습니다 아랍어 숫자 표시도 살펴보겠습니다 마지막으로 앱이 오른쪽에서 왼쪽으로 올바르게 처리되는지 테스트하는 방법도 살펴봅니다 시작하겠습니다 먼저 텍스트의 방식을 조금 더 살펴보고 용어를 소개하겠습니다 글쓰기 방향의 개념부터 시작하겠습니다 이미 보신 것처럼 영어는 왼쪽에서 오른쪽이고 히브리어는 오른쪽에서 왼쪽입니다 하지만 섞으면 어떻게 될까요?
이런 다국어 문장이 있으면 개별 구성요소가 여전히 각 글쓰기 방향을 유지합니다 즉, 각 문장의 구성요소가 세 가지라는 의미입니다 하나의 스니펫을 다른 언어로 끼워넣는 국가 언어에 두 개의 개별 텍스트 스니펫이 있습니다 문단의 글쓰기 방향의 경우 개별 스니펫의 순서를 살펴봐야 합니다 영어 문장을 왼쪽에서 오른쪽으로 쓴다면 세 개의 상자가 왼쪽에서 오른쪽으로 진행됩니다 히브리어 문장을 오른쪽에서 왼쪽으로 쓴다면 세 개의 상자가 오른쪽에서 왼쪽으로 진행되죠
조금 다르지만 관련된 개념이 텍스트 정렬입니다 왼쪽에서 오른쪽으로 읽는다면 눈이 페이지의 왼쪽으로 먼저 가고 오른쪽으로 진행됩니다 오른쪽에서 왼쪽 언어라면 반대입니다 따라서 텍스트는 오른쪽에서 왼쪽 언어로 정렬됩니다 다행히 대부분의 경우 이런 일에 대해 걱정할 필요가 없습니다 CoreText는 텍스트의 한 줄이나 단락에 있는 모든 문자와 여러 방향의 텍스트가 한 줄에 섞여 있는 텍스트도 적절하게 배열하는데 모든 UI 프레임워크가 자동으로 글쓰기 방향과 정렬을 설정합니다 모든 UI 위젯은 기본적으로 ‘자연 글쓰기 방향’과 ‘자연 정렬’입니다 텍스트 위젯의 글쓰기 방향은 기본적으로 사용자의 UI 언어에 대한 일반적인 글쓰기 방향과 같습니다 즉, UI가 히브리어나 아랍어인 경우 텍스트 위젯의 글쓰기 방향 설정은 기본적으로 오른쪽에서 왼쪽입니다 자연 정렬은 글쓰기 방향을 따릅니다 텍스트 위젯의 글쓰기 방향이 오른쪽에서 왼쪽이라면 오른쪽 정렬입니다 대부분의 경우 이렇게 하지만 기본값을 재정의할 수도 있죠 제어 방향 섹션에서 더 자세히 설명하겠습니다 이제 용어 차트를 살펴볼 차례인 것 같습니다 정리하자면 자연 정렬은 왼쪽에서 오른쪽 언어를 위한 왼쪽 정렬과 오른쪽에서 왼쪽 언어를 위한 오른쪽 정렬입니다 진행하면서 차트에 추가하겠습니다 하지만 물론, 텍스트 외에도 중요한 것이 있습니다 반대 방향으로 읽히는 텍스트는 텍스트 외의 애플리케이션 요소에 큰 영향을 미칩니다 아이콘과 그림 요소 등에 미칠 영향을 알아보겠습니다 영어와 아랍어로 된 페이지 도구 모음입니다 도구 모음의 몇 가지 아이콘을 살펴보겠습니다 ‘페이지 추가’와 ‘미디어’ 버튼 같은 많은 항목이 두 언어에서 동일하게 보입니다 대칭이거나 방향이 언어와 무관하기 때문에 두 언어에서 모두 제대로 보입니다 ‘보기’와 ‘문서’ 버튼 같은 다른 버튼을 보면 아랍어에서 반대로 보입니다 보기 버튼을 누르면 페이지 사이드바가 나타나는데 아랍어에서는 창 반대편에 표시되기 때문에 아이콘이 바뀌어야 합니다 ‘문서’ 버튼은 사용자가 아랍어로 쓰면 페이지가 반대 방향으로 바뀝니다 아이콘이 완전히 바뀔 수도 있습니다 ‘텍스트 상자 삽입’ 버튼의 문자는 사용자의 언어를 반영하기 위해 다른 문자로 바뀝니다
이번에도 다행히 자동으로 처리됩니다 텍스트 쓰기 방향보다 이미지 방향이 조금 더 복잡한데 방법은 의외로 간단합니다 Mac Pages의 영어와 아랍어 보기 메뉴입니다 ‘눈금자 표시’ 아이콘이 자동으로 반전됩니다 왼쪽에서 오른쪽 언어의 경우 수직 눈금자가 오른쪽에 있죠 눈금자 아이콘 같은 사용자 지정 이미지의 경우 오른쪽에서 왼쪽 동작은 Xcode 이미지 세트 편집기로 제어합니다 이미지가 왼쪽에서 오른쪽 방향과 오른쪽에서 왼쪽 방향이 같다면 특별한 작업이 필요하지 않습니다 그리고 개발 언어와 글쓰기 방향이 반대인 언어로 앱이 실행 중인 경우 시스템이 알고리즘적으로 이미지를 미러링할 수 있습니다 Xcode 이미지 세트 편집기에서 이 기능을 사용할 수 있습니다 사이드바에는 ‘방향’이라는 제어 버튼이 있습니다 클릭하면 메뉴에 4가지 선택지가 있습니다 UI 언어와 상관없이 이미지가 같으면 ‘고정’을 선택합니다 알고리즘 미러링을 원하면 ‘미러’ 옵션 중 하나를 선택합니다 개발 언어의 글쓰기 방향에 따라 달라집니다 알고리즘적으로 미러링할 수 없는 이미지가 있으면 UI가 방향을 변경할 때 여러 요소가 다르게 작동하거나 움직이고 싶지 않은 음영이 있을 때 ‘모두’를 선택합니다 세 개의 새로운 웰이 이미지 세트 편집기에 추가되어 왼쪽에서 오른쪽과 오른쪽에서 왼쪽 컨텍스트에 사용할 별도 이미지를 만들 수 있습니다 그러나 Pages 도구 모음처럼 SF Symbols의 이미지를 사용하면 훨씬 더 쉽습니다 거의 모든 작업이 자동으로 완료됩니다 오른쪽에서 왼쪽 언어로 변경하는 기호가 자동으로 바뀌죠 이 글머리 기호 목록 아이콘을 예로 들어보겠습니다 대부분의 이미지는 SF Symbols 사이드바에 선택한 이미지의 현지화 버전을 보여주는 ‘현지화’ 섹션이 있습니다 이 경우에는 글머리 기호 목록 아이콘의 버전이 왼쪽에서 오른쪽과 오른쪽에서 왼쪽이 다릅니다 자동으로 미러링됩니다
현지화 기능은 오른쪽에서 왼쪽 언어 미러링 이상을 지원합니다 ‘텍스트 상자 삽입’ 아이콘의 현지화 탭입니다 현지화 버전은 라틴어와 아랍어 스크립트 외에 다른 언어도 지원합니다
아랍어 지원에 특히 중요한 한 가지는 물음표인데 ‘도움말’ 아이콘으로 자주 사용됩니다 아랍어에서 물음표는 라틴어 물음표의 반대입니다 도움말 아이콘에 SF Symbols 아이콘을 사용하면 별도의 작업 없이 이 버전을 사용할 수 있죠 이미지에서 중요한 고려사항 중 한 가지는 화살표와 다른 방향 표시기입니다 원 안에 화살표가 있는 아이콘이 4개 있습니다 보시다시피 두 쌍입니다 두 개는 왼쪽 방향이고 두 개는 오른쪽 방향입니다 왼쪽을 가리키는 두 개를 살펴보면 한 화살표는 ‘arrow.backward.circle.’입니다 오른쪽에서 왼쪽 지원에서 오른쪽으로 플립됩니다 다른 하나는 ‘arrow.left..circle’로 오른쪽에서 왼쪽 지원에서 뒤집히지 않습니다 SF Symbols는 오른쪽에서 왼쪽으로 뒤집히거나 뒤집히지 않는 아이콘과 함께 이 명명 규칙을 따릅니다 ‘앞’과 ‘뒤’는 뒤집고 ‘왼쪽’과 ‘오른쪽’은 뒤집히지 않죠 화살표나 다른 모양을 사용해 ‘앞’이나 ‘뒤’를 전달하려면 뒤집힌 버전을 사용해야 하고 절대적인 방향을 전달하기 위해 화살표를 사용하려면 뒤집히지 않는 버전을 사용해야 합니다
이제 ‘용어’ 차트에 행을 추가합니다 SF Symbols에서 이미지를 선택할 때는 ‘왼쪽’과 ‘오른쪽’이 항상 이 방향을 가리키고 ‘앞’과 ‘뒤는 UI 언어에 따라 다른 방향을 가리킵니다’ 이제 오른쪽에서 왼쪽 지원에서 제어와 다른 UI 위젯이 처리되는 방식을 살펴보겠습니다 영어와 아랍어로 된 Mac Keynote 사이드바로 모양에 대한 형식 검사기를 보여줍니다 모든 것이 오른쪽에서 왼쪽으로 뒤집혀 있습니다 오른쪽에서 왼쪽 지원에서 메뉴 표시기가 왼쪽으로 진행되는 팝업 메뉴 버튼이 많습니다 체크박스 여러 개가 있는데 아랍어에서는 체크박스가 라벨 오른쪽에 있습니다 아랍어의 불투명도 슬라이더는 최소값이 오른쪽 최대값이 왼쪽으로 변경되었습니다 검사기의 다른 제어에서도 모두 마찬가지입니다 다행히 이런 동작이 모두 무료입니다 모든 UI 프레임워크에 있는 모든 표준 UI 제어가 오른쪽에서 왼쪽 언어에서는 자동으로 모양이 바뀝니다 하지만 이런 경우를 원하지 않을 수도 있고 이렇게 바뀌는 방식을 제어해야 할 수도 있습니다 재미있는 사례 몇 가지를 살펴보겠습니다 텍스트 라벨과 아이콘이 모두 있는 버튼을 살펴보겠습니다 이 Keynote 애니메이션 검사기는 ‘무브인’ 애니메이션의 제어를 보여줍니다 이 검사기의 버튼 두 개는 라벨과 아이콘이 모두 있습니다 미리 보기 버튼의 화살표는 UI 방향 변화에 따라 뒤집히는데 애니메이션 방향 메뉴의 화살표는 그렇지 않습니다 양쪽이 UI 방향으로 플립됩니다 방향 제어가 메뉴 대신 버튼 그룹인 경우 방향을 바꿀 필요가 없을 수도 있죠
제어 방식을 보여드리기 위해 작은 애플리케이션으로 두 가지 예를 분리했습니다
SwiftUI에서 이 UI를 구축하는 코드입니다 주목할 만한 점이 몇 가지 있습니다 하나씩 살펴보겠습니다 이미지 이름부터 보겠습니다 앞에서 본 것처럼 SF Symbols의 이미지의 경우 반전되거나 반전되지 않는 아이콘을 선택합니다 ‘arrowtriangle.forward.fill’을 미리보기 버튼에 사용했습니다 이름에 ‘앞’이 있기 때문에 오른쪽에서 왼쪽 뒤집힘을 말합니다 방향 버튼에는 ‘arrow.left’와 ‘arrow.right’를 사용했습니다 이름에 ‘왼쪽’과 ‘오른쪽’이 있으면 뒤집히지 않는다는 뜻입니다
AppKit 또는 UIKit에서도 동일한 방식으로 작동합니다 Xcode 스토리보드 편집기에서 ‘미리보기’ 버튼이 앱에 선택되어 있습니다 버튼의 아이콘은 속성 검사기의 ‘이미지’ 제어로 제어합니다 이 코드에서 버튼의 ‘이미지’ 속성으로 설정하면 AppKit과 UIKit에서 기본적으로 동일한 방식으로 작동합니다 SwiftUI 예시로 돌아와서 살펴볼 다음 질문은 아이콘이 표시되는 라벨 측면을 제어하는 방법입니다 라벨 스타일을 설정합니다 기본 TitleAndIconLabelStyle은 사용자의 읽기 방향에서 라벨 앞에 아이콘을 배치합니다 ‘왼쪽’ 버튼에 사용할 수 있습니다 나머지 버튼 두 개는 아이콘이 사용자의 읽기 방향에서 라벨 다음에 배치해야 합니다 사용자 정의 라벨 스타일이 필요한데 어렵지 않습니다 라벨 스타일의 makeBody() 메서드로 HStack을 만들고 제목과 아이콘을 추가합니다 다른 HStack처럼 추가 순서에 따라 표시 순서가 결정되고 UI 방향에 따라 순서가 자동으로 반전됩니다 이 방법은 버튼뿐만 아니라 라벨을 사용할 수 있는 모든 보기에 적용됩니다 물론 아이콘 때문에 ‘오른쪽’ 버튼의 방향이 바뀌면 안 되겠죠 UI 방향과 상관없이 항상 오른쪽에 있어야 합니다 여기서 코드 스니펫의 마지막 흥미로운 점이 보입니다 SwiftUI의 보기에 적용되는 SwiftUI 환경의 방향성은 수정할 수 있습니다 보기에 ‘환경’ 수정자를 추가하고 변경할 속성의 키와 새 값을 지정하면 됩니다 환경의 layoutDirection 속성을 상위 항목에서 관계없이 항상 왼쪽에서 오른쪽으로 재정의합니다 이러한 방식으로 변경한 환경은 사용자의 UI 방향에 반응하는 모든 SwiftUI 보기에 적용됩니다 ‘왼쪽’과 ‘오른쪽’ 버튼이 포함된 HStack에 수정자가 적용되었습니다 보기 환경의 변경 사항은 하위 보기에 상속되고 따라서 여기에 놓으면 HStack이 버튼의 순서를 반전시키지 못하고 두 버튼 모두 라벨의 레이아웃을 반전시키지 못합니다 그리고 물론 상위 체인이나 ‘미리보기’ 버튼에는 환경 수정자를 적용하지 않고도 원하는 대로 적절한 시기에 반전시킬 수 있습니다
요약하면 ‘왼쪽’ 버튼 아이콘은 기본 TitleAndIconLabelStyle을 사용했기 때문에 왼쪽에 있고 ‘미리보기’와 ‘오른쪽’ 버튼은 아이콘이 오른쪽에 있습니다 IconOnRightLabelStyle이라는 사용자 정의 라벨 스타일 때문이죠 ‘왼쪽’과 ‘오른쪽’ 버튼은 순서나 라벨의 내부 배열을 변경하지 않습니다 이런 요소가 포함된 환경 수정자를 HStack에 추가하여 레이아웃 방향을 왼쪽에서 오른쪽으로 설정했기 때문이죠 미리보기 버튼은 수정자가 없기 때문에 라벨의 내부 배열을 반전시킵니다 AppKit와 UIKit에서는 다르게 작동합니다 이 두 프레임워크에서는 라벨에 상대적인 아이콘의 위치가 Xcode의 속성 검사기의 ‘위치’ 제어로 제어됩니다 이 제어를 클릭하면 메뉴에 라벨과 아이콘을 수평으로 정렬하는 두 쌍의 옵션이 있는 것을 볼 수 있습니다 ‘선행’과 ‘왼쪽’이 있고 ‘후행’과 ‘오른쪽’이 있습니다 ‘선행’과 ‘후행’은 UI 방향에 따라 의미가 바뀌지만 ‘왼쪽’과 ‘오른쪽’은 아닙니다 AppKit에서는 버튼의 imagePosition 속성으로 이 기능을 제어할 수 있습니다 UIKit에서는 버튼 구성의 imagePlacement 속성을 사용하는데 버튼 구성을 먼저 설정해야 합니다 미리보기 버튼은 위치를 ‘후행’으로 설정했기 때문에 아이콘이 바뀌고 ‘오른쪽’ 버튼의 아이콘은 위치를 ‘오른쪽’으로 설정했기 때문에 바뀌지 않습니다 이렇게 또 ‘용어’ 차트의 마지막 행을 채웁니다 UI 레이아웃을 살펴볼 때 ‘선행’과 ‘후행’이라는 용어가 많이 나옵니다 ‘앞’과 ‘뒤’처럼 ‘왼쪽’, ‘오른쪽’과 대조하여 사용되기도 합니다 ‘선행’ 가장자리는 줄의 시작이나 사용자가 읽기 시작하는 화면이나 창의 측면에 가장 가까운 가장자리로 왼쪽에서 오른쪽 언어는 왼쪽 오른쪽에서 왼쪽 언어는 오른쪽이죠 후행 가장자리는 반대편으로 줄의 끝에 가장 가깝고 오른쪽에서 왼쪽 언어는 오른쪽 왼쪽에서 오른쪽 언어는 왼쪽입니다 대부분의 경우 ’왼쪽’과 ‘오른쪽’ 대신 사용하는데 ‘왼쪽’과 ‘오른쪽’을 절대 방향으로만 저장할 수 있습니다
다른 흥미로운 사례를 보겠습니다 iPhone Keynote의 텍스트 형식 검사기 일부로 영어와 아랍어 버전입니다 이 스크린샷에는 네 개의 세그먼트 제어가 있습니다 위의 두 개 검사기의 페이지 선택기와 표준 ‘굵은 글씨 이탤릭체,밑줄’ 스타일 버튼은 UI 언어에 따라 세그먼트 순서를 반전시킵니다 아랍어를 모른다면 페이지 선택기에 관해서는 저를 믿으세요 다른 제어와 마찬가지로 이 동작은 기본값으로 무료입니다 다른 두 개의 세그먼트 제어 정렬 제어는 세그먼트 순서를 반전시키지 않습니다 절대 방향으로 이동시키기 때문입니다 왼쪽 정렬은 줄의 시작과 끝에 관계없이 왼쪽 정렬입니다 이제 제어의 반전을 방지하는 방법을 살펴보겠습니다 SwiftUI에 대한 방법은 이미 알고 있습니다 ‘환경’ 수정자를 적용해서 환경의 layoutDirection 속성을 왼쪽에서 오른쪽으로 변경하면 되죠 이 기술을 사용해서 선형 제어가 반전되지 않도록 하면서 스타일 제어가 정상적으로 반전되도록 합니다 UIKit에서는 다릅니다 Xcode의 이 토이 애플리케이션이 분할된 제어 동작 시뮬레이션하죠 두 개의 분할된 제어가 있는데 하나는 굵은 글씨 이탤릭체, 밑줄 동작을 모방하고 두 번째는 정렬 제어를 모방합니다 정렬 제어가 선택되었습니다 속성 검사기에 ‘시맨틱’이라는 메뉴가 있습니다 메뉴를 클릭하면 5개의 선택지가 있습니다 시맨틱 콘텐츠 속성을 이 메뉴가 제어합니다 어떤 제어인지 명령하면 시스템이 이를 사용해서 UI 방향을 기준으로 모양의 반전 여부를 결정합니다 기본값은 ‘미지정’인데 제어의 모양이 반전됩니다 ‘재생’을 보면 제어가 미디어 재생 제어나 재생 제어 그룹의 일부입니다 ‘공간’을 보면 제어는 공간 제어나 그룹의 일부입니다 공간 제어는 공간 안의 개체를 절대 방향으로 움직입니다 마지막으로, 제어는 항상 왼쪽에서 오른쪽이나 반대로 배치되도록 할 수 있습니다 굵은 글씨, 이탤릭체 밑줄 제어는 오른쪽에서 왼쪽 언어에서 세그먼트를 반대로 바꾸는데 시맨틱 콘텐츠 속성이 ‘미지정’이기 때문이죠 정렬 제어는 시맨틱 콘텐츠 속성이 ‘공간’으로 설정되어 있기 때문에 세그먼트를 반전시키지 않습니다 이 기능의 좋은 점은 UISegmentedControl에만 적용되는 것이 아니라는 점입니다 모든 UIViews에는 시맨틱 콘텐츠 속성이 있어서 오른쪽에서 왼쪽 동작을 모두 제어합니다 하위 구성요소가 있는 모든 표준 UIKit 보기의 경우 시맨틱 콘텐츠 속성이 UI 언어에 따라 보기 하위 구성요소 위치의 반전 여부를 결정합니다
AppKit에서는 반대입니다 모든 NSControls에서는 Xcode 속성 검사기에 ‘레이아웃’과 ‘미러’로 표시된 두 가지 메뉴가 있습니다 ‘레이아웃’ 메뉴는 제어의 userInterfaceLayoutDirection 속성에 해당하는데 제어가 왼쪽에서 오른쪽이나 그 반대를 사용할지 나타냅니다 일반적으로 Interface Builder에서는 이 값을 변경하지 않습니다 대신 ‘미러’ 메뉴를 사용하죠 이 값을 ‘항상’으로 설정하면 userInterfaceLayoutDirection을 통해 제어의 레이아웃이 UI 언어가 오른쪽에서 왼쪽일 때 니브가 로드되면 뒤집히고 ‘사용 안 함’으로 설정하면 동작이 취소되어 레이아웃이 동일하게 유지됩니다 이 값을 ‘사용 안 함’으로 설정하면 선형 제어의 레이아웃이 동일하게 유지됩니다 Interface Builder에서 작업하지 않는다면 코드에서 동일한 작업을 하기 위해 제어의 userInterfaceLayoutDirection를 설정해서 다시 왼쪽에서 오른쪽으로 직접 되돌립니다 userInterfaceLayoutDirection은 NSView의 속성이지만 Interface Builder에는 NSControl의 인스턴스에만 표시되기 때문에 NSControl이 아닌 것을 반전시키고 싶다면 이런 코드가 필요합니다
다음으로 넘어가기 전에 텍스트를 조금 더 살펴보겠습니다 Mac용 iWork의 ‘문서 암호 설정’ 대화 상자입니다 아랍어 버전에서는 모든 것이 반전됩니다 하지만 라벨을 보세요 영어에서는 편집 텍스트 필드에 가깝게 오른쪽 정렬이 적용되었습니다 아랍어에서는 왼쪽 정렬입니다 다시 말해, 자연 정렬의 반대인 후행 가장자리 정렬입니다 Mac에서 SwiftUI에 이 레이아웃을 가져오는 건 쉽습니다 양식을 사용해서 텍스트 필드를 함께 가져옵니다 그러나 이 예처럼 라벨 중 하나가 여러 줄이면 달라질 수 있습니다 마지막 라벨을 두 줄로 확장하면 이렇게 됩니다 한 줄 라벨 두 개는 올바르게 정렬되었는데 두 줄 라벨은 아닙니다 중요한 것은 아래의 라벨이 제대로 정렬되었다는 것이죠 경계 상자가 오른쪽으로 정렬되었을 뿐 경계 상자 내의 텍스트 줄이 오른쪽으로 정렬된 것은 아닙니다 multilineTextAlignment 수정자를 마지막 라벨에 추가해서 해결할 수 있죠 SwiftUI의 텍스트 정렬은 두 줄 이상의 텍스트 개체에서만 적용됩니다 단일 줄 텍스트 개체의 경우 경계 상자가 텍스트 자체를 단단히 묶고 있기 때문에 전체 텍스트 개체를 정렬해야 합니다 또한 텍스트 경계 상자를 정렬하거나 경계 상자 텍스트의 여러 줄을 정렬하는 경우에도 선행과 후행 정렬을 선택할 수 있기 때문에 사용자의 UI 방향에 따라 달라집니다 UI 방향에 관계없이 정렬을 동일하게 유지하려면 앞에서 보신 것처럼 환경 수정자를 사용해서 환경의 레이아웃 방향을 변경합니다 UIKit에서는 텍스트가 기본적으로 자연 정렬되는데 필요한 경우에는 절대 방향으로 변경할 수 있습니다 Interface Builder에서 제어는 이렇게 표시되고 UILabel과 UITextView의 textAlignment 속성에 해당합니다 오른쪽 끝에 있는 점 버튼을 사용하면 자연 정렬이나 선행 가장자리 정렬이 가능합니다 라벨 정렬은 라벨의 시맨틱 콘텐츠 속성을 따릅니다 다른 버튼은 UI 방향이나 라벨의 시맨틱 콘텐츠 속성에 관계없이 왼쪽, 오른쪽 또는 가운데 맞춤 정렬을 수행합니다 후행 가장자리 정렬에 대한 기본 설정은 없습니다 코드로 해야 합니다 AppKit에서는 조금 다릅니다 정렬 제어는 그대로이기 때문에 UIKit에서와 기본적으로 동일하게 작동하는데 userInterfaceLayoutDirection과의 상호작용 방식이 다릅니다 ‘미러’를 ‘자동’으로 설정하면 시스템이 userInterfaceLayoutDirection을 오른쪽에서 왼쪽으로 설정하고 모든 정렬 설정의 의미가 반대로 표시됩니다 따라서 ‘미러’를 ‘자동’으로 설정하면 왼쪽 정렬이 선행 가장자리 정렬이고 오른쪽 정렬은 후행 가장자리 정렬입니다 지금까지 모든 표준 UI 위젯으로 사용자의 글쓰기 방향에 따라 레이아웃의 자동 반전 방법을 살펴봤는데 필요할 때 중단하는 방법은 어렵지 않습니다 화면에 개별 UI 위젯을 정렬하는 것으로 확장됩니다 하위 보기의 위치 지정을 처리하는 표준 보기나 보기 제어기 중 하나를 사용하는 경우 필요한 경우에는 모든 레이아웃을 자동으로 반전시킬 수 있습니다 테이블 보기와 컬렉션 보기는 오른쪽에서 왼쪽 언어에서 스크롤 작업도 처리합니다 UINavigationController는 Segue 애니메이션의 방향을 자동으로 변경해 사용자의 글쓰기 방향을 반영하고 ’뒤로’ 버튼도 이에 따라 변경합니다 UIPageViewController는 자동으로 페이징 방향과 쓸어넘기기 동작의 의미를 반전시킵니다 일반적으로 스택 보기를 사용해 하위 보기를 배치하는 경우를 제외하고는 이런 항목을 재정의하지 않는 것이 좋지만 모든 보기는 semanticContentAttribute를 적용하고 하위 보기를 배치하는 방법을 알려줍니다 표준 AppKit 보기에서도 마찬가지이고 테이블과 컬렉션 보기에서도 오른쪽에서 왼쪽으로 스크롤을 처리합니다 모든 보기는 userInterfaceLayoutDirection 속성을 적용해서 하위 보기의 배치 방식을 결정하지만 Interface Builder에서는 설정할 수 없습니다 코드로 해야 합니다 표준 SwiftUI 보기는 환경의 layoutDirection 속성도 반영합니다
스택과 그리드 보기 대신 자동 레이아웃을 사용해 보기를 배치하는 경우 Auto Layout이 UI 방향을 고려해서 자동으로 항목을 반전시킵니다 수평적 제약이 있는 경우 선행과 후행 가장자리에 자동으로 연결되며 앞서 살펴본 것처럼 ‘선행’과 ‘후행’은 UI 방향에 따라 의미가 달라집니다 하지만 필요한 경우 자동 레이아웃 제약 조건을 절대적인 왼쪽과 오른쪽으로 설정할 수 있습니다 제약 조건의 한쪽에 대한 방향을 클릭해서 팝업 메뉴에서 ‘언어 방향 존중’을 해제합니다 그렇게 하면 제약 조건의 양쪽 끝이 ‘선행’과 ‘후행’에서 ‘왼쪽’과 ‘오른쪽’으로 바뀝니다 코드에서 자동 레이아웃 제약 조건을 설정하는 방법은 다양합니다 그중 하나입니다 어떤 방법을 사용하든 기억해야 할 것은 ‘왼쪽’과 ‘오른쪽’ 대신에 ‘선행’과 ‘후행’을 사용하는 것인데 레이이아웃 방향이 UI 언어의 글쓰기 방향과 관계없이 동일해야 할 경우는 드물지만 예외입니다 많은 내용을 살펴봤으니 한숨 돌리겠습니다 가장 중요한 것은 오른쪽에서 왼쪽 언어 지원이 자동으로 처리되고 재정의하는 방법이 다양하다는 것입니다 용어 슬라이드를 한 번 더 살펴보겠습니다 ‘왼쪽’과 ‘오른쪽’은 항상 왼쪽과 오른쪽이고 다른 용어는 전체 UI 방향에 따라 의미가 반전됩니다
마지막으로 살펴볼 중요한 문제는 숫자 표시 방법입니다 오른쪽에서 왼쪽 지원은 아니지만 많은 개발자에게 있어 아랍어는 영어와는 다른 숫자 문자를 사용하는 언어입니다 숫자는 이렇게 보입니다 숫자에는 여러 명명 규칙이 있는데 대부분 유럽 언어에서는 라틴 숫자를 사용하고 아랍어에서 사용하는 규칙은 아랍어-인도어 숫자입니다 다른 언어에도 각기 다른 숫자가 있죠 힌디어와 함께 사용되는 데바나가리 숫자입니다 힌디어는 다른 숫자를 사용하는 공통 언어입니다 한 가지 중요한 점은 아랍어나 힌디어 모두 항상 고유 숫자를 사용하지는 않는다는 것입니다 아랍어는 국가에 따라 다르고 사우디아라비아 등의 국가에서는 고유 숫자를 사용하며 아랍에미리트 등의 국가에서는 라틴 숫자를 사용합니다 각 사용자는 원하는 숫자를 선택할 수도 있습니다 힌디어의 경우 기본적으로 라틴 숫자를 사용하지만 사용자는 국가별 숫자를 사용할 수 있습니다
UI 문자열을 구성하는 것은 별로 좋은 생각이 아니죠 문자열이 하드 코딩되어 있어 번역할 수 없고 메시지가 복수를 처리하도록 변경되지 않습니다 또 다른 이유는 ‘peopleInChat’의 값이 항상 라틴 숫자로 표현되기 때문입니다 아시다시피 이를 해결하기 위해 ‘localized’ init 메서드를 문자열에 사용하는데 애플리케이션 번들에서 실제 문자열을 검색해서 stringsdict 파일이 있으면 복수를 적절하게 처리합니다 다행히 숫자도 올바르게 처리합니다 ‘peopleInChat’ 보간 값은 사용자의 로케일과 환경 설정에 따라 현지화된 숫자로 렌더링됩니다 SwiftUI의 텍스트 보기에서도 제대로 작동합니다 텍스트 보기 이니셜라이저가 적절하게 현지화된 숫자로 모든 문자열 보간을 렌더링하죠 사용자가 볼 수 있는 문자열을 구성하려면 항상 String(localized:)을 사용합니다 +stringWithFormat: 등 숫자 형식을 지정할 수 있는 문자열의 API과 숫자를 사용하는 String init 함수는 항상 라틴 숫자를 사용합니다 한 가지 주의할 점은 이런 숫자를 포함하는 정적 문자열입니다 왜 그럴까요? 번역가에게 보내서 번역하면 이렇게 됩니다 대부분 국가의 경우 맞지만 사우디아라비아 같은 일부 국가에서는 그렇지 않습니다 3에 사용된 문자를 제외하고 텍스트는 동일합니다 물론 아랍어를 사용하는 로케일과 라틴 숫자를 사용하는 로케일을 따로 지정할 수도 있지만 아무도 그렇게 하지 않습니다 시간 낭비라고 생각하죠 아랍어와 힌디어는 더 안 좋습니다 사용자가 사용할 숫자를 선택하면 사용자의 로케일뿐만 아니라 사용자의 기본 설정에 따라 현지화도 선택해야 합니다 이를 해결하려면 아랍어나 힌디어 현지화가 필요한데 컴파일 할 때 값을 알더라도 런타임에서 숫자를 대체해야 합니다 Swift에서는 문자열 보간을 통해 이를 수행할 수 있습니다
숫자와 함께 이동하는 다른 요소가 있으면 숫자와 관련된 배치가 어려울 수 있습니다 모든 오른쪽에서 왼쪽 언어에서 동일하지도 않습니다 아랍어와 히브리어 숫자에서는 마이너스 부호와 퍼센트 부호가 다른 곳에 있습니다 꼭 오른쪽에서 왼쪽 언어일 필요는 없습니다 터키어는 왼쪽에서 오른쪽 언어인데 퍼센트 기호도 왼쪽입니다 물론 아랍어 국가 숫자를 사용하면 전혀 다른 퍼센트 기호를 사용합니다 즉, 이렇게 퍼센트 기호와 통화 기호, 단위 약어 등을 추가해야 하는 작업은 정말 피하고 싶은 작업입니다 대신 숫자 형식을 사용해서 퍼센트 기호나 통화 기호 등을 추가하죠 Swift에서는 모든 숫자에 formatted() 메서드를 사용하면 쉽게 작업할 수 있습니다 이 예처럼 더 큰 문자열이라면 String(localized:)이 다른 문자열을 포함해 형식화된 번호나 런타임에 문자열로 대체된 다른 모든 번호를 확인하고 형식화된 숫자와 주변 메시지의 글쓰기 방향이 서로 뒤섞이지 않도록 표시하여 처리합니다 마지막으로 말씀드릴 내용은 오른쪽에서 왼쪽 지원이 올바르게 처리되는지 확인하는 앱 테스트를 위한 한 가지 팁입니다 앱의 오른쪽에서 왼쪽 지원을 테스트하기 위해 실행 파일에 아랍어나 히브리어 현지화가 필요하지는 않습니다 개발 언어로 오른쪽에서 왼쪽 동작을 테스트할 수 있습니다 그렇게 하려면 Xcode에 스키마 편집기를 가져옵니다 옵션 탭으로 이동해서 ‘앱 언어’ 메뉴를 찾습니다 이 메뉴의 맨 아래를 보면 다양한 ‘가상 언어’ 옵션이 있죠 이 가짜 언어를 사용하면 실제 현지화 없이도 현지화 문제를 확인하기 위해 UI를 다양한 방식으로 변환할 수 있습니다 ‘오른쪽에서 왼쪽 가상 언어’ 옵션을 선택하고 실행하면 앱이 영어이든 어떤 개발 언어를 사용하든 UI가 모두 오른쪽에서 왼쪽으로 뒤집힙니다 여기까지입니다 오른쪽에서 왼쪽 언어를 현지화하려면 글쓰기 방향 변경과 관련된 몇 가지 문제에 주의해야 하는데 시스템이 대부분의 작업을 자동으로 처리합니다 보통 절대 방향의 경우에서는 이런 동작을 선택하고자 하는데 언제든지 가능합니다 모든 언어가 숫자를 렌더링할 때 라틴 숫자를 사용하지는 않습니다 기억하세요 오른쪽에서 왼쪽 언어 지원은 어렵지 않습니다
-
-
12:55 - Control orientation example
struct ContentView: View { var body: some View { VStack(alignment: .leading) { Button(action: {}) { Label("Preview", systemImage: "arrowtriangle.forward.fill") }.labelStyle(IconOnRightLabelStyle()) HStack() { Button(action: {}) { Label("Left", systemImage: "arrow.left") }.labelStyle(TitleAndIconLabelStyle()) Button(action: {}) { Label("Right", systemImage: "arrow.right") }.labelStyle(IconOnRightLabelStyle()) }.environment(\.layoutDirection, .leftToRight) }.padding() } }
-
14:22 - Control orientation custom label style example
struct IconOnRightLabelStyle : LabelStyle { func makeBody(configuration: Configuration) -> some View { HStack { configuration.title configuration.icon } } }
-
14:43 - Control orientation example
struct ContentView: View { var body: some View { VStack(alignment: .leading) { Button(action: {}) { Label("Preview", systemImage: "arrowtriangle.forward.fill") }.labelStyle(IconOnRightLabelStyle()) HStack() { Button(action: {}) { Label("Left", systemImage: "arrow.left") }.labelStyle(TitleAndIconLabelStyle()) Button(action: {}) { Label("Right", systemImage: "arrow.right") }.labelStyle(IconOnRightLabelStyle()) }.environment(\.layoutDirection, .leftToRight) }.padding() } }
-
18:58 - Control orientation example—keeping controls from reversing
struct ContentView: View { var body: some View { VStack(alignment: .leading) { Picker(selection: $textStyle, label: Text("Text Style")) { Text("B").tag(TextStyle.bold) Text("I").tag(TextStyle.italic) Text("U").tag(TextStyle.underline) Text("S").tag(TextStyle.strikethrough) }.pickerStyle(.segmented) Picker(selection: $alignment, label: Text("Alignment")) { Image(systemName: "text.alignleft").tag(TextAlignment.left) Image(systemName: "text.aligncenter").tag(TextAlignment.center) Image(systemName: "text.alignright").tag(TextAlignment.right) }.pickerStyle(.segmented) .environment(\.layoutDirection, .leftToRight) } } }
-
22:38 - Control orientation example—form with multiline text alignment modifier
var body: some View { Form { TextField("Password:", text: $password) TextField("Verify:", text: $verifyPassword) TextField("Password Hint:\n(Recommended)", text: $passwordHint) .multilineTextAlignment(.trailing) }.padding() }
-
27:14 - Set up Auto Layout in code
myView.leadingAnchor.constraint(equalTo: mySuperView.leadingAnchor, constant:16)
-
29:05 - Digits in Arabic
myLabel.string = String(localized: "There are \(peopleInChat) people in this chat.", comment: "Label indicating number of chat participants") Text("There are \(peopleInChat) people in this chat.", comment: "Label indicating number of chat participants")
-
30:12 - Digits in Arabic
myLabel.string = String(localized: "This application supports \(3) file formats.", comment: "Label showing number of supported file formats (number is always 3)")
-
31:41 - Numbers in RTL text
myLabel.stringValue = String(localized: "\(percentComplete.formatted(.percent)) complete")
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.