티스토리 뷰

🍏/Accessibility

[iOS] Large Content Viewer

eungding 2021. 5. 29. 11:23
반응형

WWDC 2019 - Large Content Viewer - Ensuring Readability for Everyone  를 본 기록 ✏️

 

[1] Large Content Viewer 란? 

 

우리의 목표는 앱의 모든 부분이 모든 사용자에게 readable한 것입니다.

Large Content Viewer은 Dynamic Type이랑 연관되어있습니다. (참고: Dynamic Type 글)

 

텍스트 사이즈를 Accessibility size 중 하나로 키워봅시다. 

하지만 탭바의 텍스트는 여전히 커지지 않은 것을 볼 수 있습니다. 

 

 

자리가 부족하기 때문에 탭바를 키우고 싶지는 않습니다.

대신 해당 버튼을 long press 하면 더 큰 버전을 볼 수 있습니다.

 

 

탭바 안에서 손가락을 Drag하면 각 탭의 큰 버전이 보여지고

내가 누르고 싶은 탭에 손가락을 drag한 후, 손가락을 떼면 애플이 당신의 버튼을 눌러줍니다 (??)

 

이 기능을 Large Content Viewer 라고 합니다. 

 

설정 > 손쉬운 사용 > 디스플레이 및 텍스트 크기 > 더 큰 텍스트 에서 

글자크기를 크게 선택한 후,

앱스토어로 와서 탭을 꾹 눌러보고 탭바 위에서 손가락을 드래그 해보시면 

Large Content Viewer 를 경험해보실 수 있어요! 

 

 

 

정리해보자면... 

Lager Content Viewer

 

1. 시력이 낮은 (low vision) 사용자를 위한 것으로 
   (그래서 Lager Accessibility Size로 바꿔 줄 때만 나옵니다.) 

2. 위에서 말한 탭바 뿐만아니라 작은 크기를 유지해야하는 다른 UI들에게도 보여집니다. 

 

 

예를 들어 여기 눌러도 나오더라구요! 

 

 

 

Standard UIKit bar를 사용한다면 Accessibility Text Size일 때 Large Content Viewer가 알아서 표시됩니다. 

 

하지만 custom UI를 사용하고 있다면 API를 구현해서 Lager Content Viewer를 표시할 수 있습니다.

하지만 이는 custom UI가 커질 수 없는 경우에만 해당되는 것을 기억하세요. 

LagerContentViewer를 보여주는 것보다 Scaling with dynamic type가 더 좋은 방법이기 때문입니다. 

 

 

 

[2] Standard UIKit Bar를 쓸 때 고려할 점 

 

위에서 Standard UIKit Bar를 쓰면 Lagre Content Viewer가 자동으로 보여진다고 했습니다. 

하지만 그것이 좋아보이게 하기 위해 해줘야하는 것이 있습니다.

Bar Item에 PDF 이미지를 쓰고 있다면 

asset catalog에서 Preserve Vector 체크박스를 체크해주세요! 

이렇게 하면 이미지가 smoothly하게 잘 커질 것입니다. 

 

 

여기를 체크하라는 뜻! 

 

 

 

만약 image button에 vector data를 안쓰고 있는 경우, (예를들어 png를 사용하고 있는 경우) 

Large Contet Viewer에 이미지가 표시될 때, 흐릿하게 표시될 것입니다. 

이를 해결하기 위해 larger version의 이미지도 제공해주세요 

 

UIBarItem의 largeContentSizeImage 로 제공해주면 됩니다. 

그리고 이미지의 position을 조정해야한다면 largeContentSizeImageInsets를 이용해줄 수 있습니다. 

 

 

 

 

[3] Custom Bar 를 쓸 때 고려해야할 점 

 

 

1)  custom tab bar안에 있는 버튼 중, Large Content Viewer에 보여져야하는 것을 표시해줘야합니다.

 

2) 1번에서 표시한 버튼에 대해서 Large Content Viewer에게 title과 image를 알려줘야합니다.

 

(참고로) standard UIKit을 쓴다면 1,2 번에서 직접 제공해주는 values들이 알아서 제공되고 있는 셈인 것이죠

 

3) custom tab bar 에게 gesture interaction 을 setup 해줘야합니다. 

 

 

1, 2번 구현은 UILargeContentViewerItem protocol 을 이용해서 하면 됩니다 

이 프로토콜은 Lager Content Viewer가 콘텐츠를 표시하기 위해 필요로 하는 정보들을 들고 있습니다. 

 

 

1번 내용을 showsLargeContentViewer를 true로 해줘서 구현해주고 

2번 내용을 나머지 프로퍼티들을 넘기주며 구현해주면 되겠습니다. 

 

small button의 PDF Image를 재사용하려고 하는 경우, 

scalesLargeContentImage를 true로 해주고 largeContentImage에 원래 쓰고 있던 small image를 넘겨주면 됩니다.  

(위에서 말한 preserve the vector data 체크해주는 것을 잊지 마세요!) 

 

UIView는 이미 프로토콜을 채택해서 구현해주고 있기 때문에 

오바리이딩해서 구현해주면 되겠습니다. 

 

 

 

3번 내용은 addInteraction을 통해서 해주면 됩니다.  (drag and drop support할 때도 사용되는 메소드라고 합니다) 

 

 

 

위의 메소드의 파라미터로 넘겨 줄 UILargeContentViewerInteraction를 살펴봅니다. 

간단한 경우, UILargeContentViewerInteraction의 인스턴스를 argument 없이 만들면 끝입니다. 

아래처럼 하라는 뜻! (밑에서 나오는 Example1에 해당) 

customBar.addInteraction(UILargeContentViewerInteraction())

 

 

하지만 이미 다른 제스쳐가 있는 경우 

여기 안에 있는 것들을 건들여서 행동을 커스터마이징 해야할 수 있습니다.  (밑에서 나오는 Example2에 해당) 

 

 

위의 UILargeContentViewerInteractionDelegate안의 메소드를 살펴봅시다. 

 

1)  largeContentViewerInteraction(_:didEndOn:at:)

 

이 메소드를 통해서 사용자가 특정 custom view위에서 손가락을 뗄 때 동작을 지정할 수 있습니다. 

사용자가 손가락을 뗄 때, 해당 항목을 누른 것 처럼 동작해야합니다.  (이게 Large Content Viewer 의 기본 동작이니까)

 

이 메소드를 구현하지 않으면 UIButton 같은 standard UI Control을 사용하고 있는 경우,

기본적으로 touchup inside event를 보내게 되기 때문입니다. 

 

 

2) largeContentViewerInteraction(_:itemAt:)

 

특정 포인트에 해당하는 아이템을 제공하는 메소드 입니다. 

디폴트로 특정 포인트에 해당하는 아이템이 알아서 찾아지지만, 예를 들어 너가 view를 사용하고 있지 않다면 작동하지 않습니다.

이 메소드로 특정 포인트에서 Large Content Viewer에 보여져야하는 아이템을 반환할 수 있습니다.  

 

 

3) viewController(for:)

 

디폴트로 UIKit은 interaction을 추가한 뷰가 속해있는 뷰컨트롤러를 pick하려고 시도합니다.

근데 잘 작동하지 않는 경우가 있는데, 이 메소드를 통해서 뷰컨트롤러를 명시할 수 있습니다.

(잘 작동하지 않는 케이스가 뭔지는 말씀 안해주심,,) 

 

 

이제 예제로 살펴봅시다. 

 

# Example 1. Custom Bar With Standard Views

 

custom bar이지만  그 안에는 standard view로 이루어진 경우입니다. (UIButton과 UILabel)

 

 

우리가 해야할 일은 button과 image에 showsLargeContentViewer를 true로 해주는 것입니다.

(title과 image를 제공해야할 필요는 없습니다. 왜냐면 뷰의 속성에 의해 유추될 수 있으므로)

 

그리고 custom bar에 gesture interaction을 추가해줍니다. 

이게 끝! 

 

 

 

# Example 2. Custom Bar With Custom Views

 

custom bar안에 custom view가 있는 경우입니다. 

 

 

MyCustomButton에서 아래와 같이 오버라이딩 해줍니다. 

 

 

vector data를 사용하기 때문에 largeContentImage에 기존 이미지를 넘겨주고

scalesLargeContentImage를 true로 해줬습니다. 

 

 

이제 interaction을 설정해주겠습니다.

우선 사파리 앱을 먼저 살펴봅시다. 

사파리 앱의 경우 뒤로가기 버튼을  탭하면 뒤로 가고, 롱프레스하면 이전 히스토리를 보여줍니다. 

근데 Large Content Viewer도 롱프로세스를 사용하고 있습니다. 

 

Large Contet Viewer를 보여주는 LongPress랑 (왼쪽)

히스토리를 보여주는 LongPress랑 (오른쪽)

같이 잘 사용되고 있는 것을 볼 수 있습니다.  

 

 

 

 

사파리 앱처럼  이미 Long Press Action이 있는 버튼의 경우 Lager Content Viewer를 보여주게 해봅시다!! 

우선 이미 존재하는 longPressRecognizer의 duration을 늘려줍니다. 

이렇게 하면 사용자가 다른 action을 하기 전에 Large Content Viewer를 먼저 볼 수 있는 extra time을 제공해줄 수 있기 때문입니다. 

 

 

그리고 사용자 설정이 변경되는 경우도 옵져빙해서 duration을 바꿔줘야합니다. 

이렇게 하면 설정에서 Accessibility text Size를 선택하거나 선택을 취소하면 duration도 잘 바뀌게 됩니다. 

 

 

그 다음, longPressRecognizer에 delegate를 설정해주고 

 

 

delegate callback에서 

현재 존재하는 longPressRecognizer랑

Large Content Viewer의 gestureRecognizer랑

동시에 인식되도록 해줍니다. 

 

이렇게 하면 둘다 서로 일하는 것을 막지 못할 것입니다.

 

 

 

반응형

'🍏 > Accessibility' 카테고리의 다른 글

[iOS] Accessibility in SwiftUI  (0) 2021.06.06
[iOS] UIAccessibilityCustomAction  (0) 2021.06.01
[iOS] Reading Content Accessibility  (0) 2021.05.27
[iOS] Visual Accessibility  (3) 2021.05.27
[iOS] Switch Control Accessibility  (0) 2021.05.26
댓글