티스토리 뷰

반응형

안녕하세요 :) Zedd입니다.

Accessibility Programming Guide for iOS의 두번째 챕터를 시작해봅시다.

1편은 <Accessibility Programming Guide for iOS (1)>글을 봐주세요!



Accessibility Programming Guide for iOS  (2)



Make Custom Individual Views Accessible


앱에 사용자가 상호작용해야하는 사용자 정의 individual View가 포함된 경우, View에 접근 가능하게 만들어야 합니다. individual View는 사용자가 상호 작용하는 다른 View를 포함하지 않는 View입니다. 


잘 이해가 안가시죠?

스토리보드에 새로운 View를 추가해볼게요.




이렇게 추가하고, Accessibility Inspector를 통해 우리가 추가한 저 View의 접근성을 확인해봅시다.



안잡히죠???? 활성화가 안되는 것을 볼 수 있어요. 

바로 이런것에 접근성을 추가해줘라~~가 문서가 하는 말입니다. 

그럼 접근성을 추가하려면??


  1. myView.isAccessibilityElement = true



위 코드를 넣어주시면..!!



이렇게 활성화가 되는 것을 볼 수 있습니다.

즉, 접근성이 추가된 것이죠.

우리의 individual View에요!


Make the Contents of Custom Container Views Accessible


앱이 사용자가 상호 작용하는 다른 요소가 포함된 사용자 정의 View를 표시하는 경우, 포함된 요소를 개별적으로 접근 가능하게 해야합니다.
동시에, 컨테이너 View자체에 접근 할 수 없도록 해야합니다. 그 이유는 사용자가 컨테이너 View자체가 아닌, 컨테이너 내용과 상호 작용하기 때문입니다.

이를 위해 사용자 지정 컨테이너 View는 UIAccessibilityContainer 프로토콜을 구현해야합니다. 이 프로토콜은 포함된 요소를 배열에서 사용할 수 있도록 하는 메소드를 정의합니다.

이 챕터를 보면..좀 길게 소스코드들이 있는데, 그것도 Objc로..잘 이해가 안가는데..결국 찾아서 뭔 소린지 알게되었는데 음...제가 헷갈렸던 부분들 이런저런 것들을 알려드릴게요.

먼저 "앱이 사용자가 상호 작용하는 다른 요소가 포함된 사용자 정의 View를 표시하는 경우, 포함된 요소를 개별적으로 접근 가능하게 해야합니다.
동시에, 컨테이너 View자체에 접근 할 수 없도록 해야합니다."라고 하죠? 

그래서 저는 이걸 읽고...Custom View..? 
  1. class ZeddView : UIView{

    }


ZeddView가 UIView를 상속받도록 하고, ZeddView타입의 ContainerView를 만들면 되는건가..?


근데 왜..잘 인식되지..?

"포함된 요소를 개별적으로 접근 가능하게 해야합니다."라고 했는데..그렇게 안했는데..왜 접근이 가능하지..?라는게 제 의문이었는데..

아니 기본적으로 UIKit에 있는 것들은 다 접근 가능한데..그걸 상속받으면..당연히 가능한거지..왜...

라고 해서 찾아봤는데, 접근성 자료가 은근..없더라구요.. 그래서 어케어케 찾았는데!!

이런 UIView를 상속받는 뭐 이런 View를 가지고 Custom View라고 하는게 아니었어요..ㅎ


UIAccessibilityContainer 비공식 프로토콜은 선택한 구성 요소를 개별 요소로 접근 할 수 있도록 UIView 하위 클래스에 대한 방법을 제공합니다.

예를들어, View는 아이콘 또는 그려진 텍스트(drawn text)가 포함될 수 있고, 사용자에게 별도의 아이템으로 나타나고 기능할 수 있습니다. 

하지만 이러한 구성요소는 UIView의 인스턴스로 구현되지 않으므로, 장애가 있는 사용자가 자동으로 접근 할 수 없습니다. 

따라서 이러한 Container View는 UIAccessibilityContainer 메서드를 구현하여 이러한 구성 요소에 대한 액세스 가능성 정보를 VoiceOver와 같은 보조 앱에 제공해야합니다.


라고 합니다..!!! Custom View라는 것은 뭐 그려진 텍스트 뭐 이런 걸 말하는 거였어요..!!

이런걸 추가해줄 때는 Container View의 접근을 막아야 한다는 것이죠.


class ZeddView: UIView{
 
    let element1 = UIAccessibilityElement(accessibilityContainer: self)
    let element2 = UIAccessibilityElement(accessibilityContainer: self)
    
    override func accessibilityElementCount() -> Int {
        return 2
    }
    
    func setupZeddView(){
        self.isAccessibilityElement = false
        self.accessibilityElements = [element1,element2]
    }
}
cs


내 자체, 즉 Container View는 접근 불가능하게 하고, 안에 있는 접근 가능해야만 하는 요소들을 "개별적으로" accessibilityElements로 넣어줘야 하는것이죠.

이유는 위에서 말했죠?

"앱이 사용자가 상호 작용하는 다른 요소가 포함된 사용자 정의 View를 표시하는 경우, 포함된 요소를 개별적으로 접근 가능하게 해야합니다.

동시에, 컨테이너 View자체에 접근 할 수 없도록 해야합니다. 그 이유는 사용자가 컨테이너 View자체가 아닌, 컨테이너 내용과 상호 작용하기 때문입니다."


Supply Accurate and Helpful Attribute Information(정확하고 유용한 속성 정보를 제공하십시오.)
접근 가능한 요소에 대한 속성 정보를 제공하는 과정에는 두 부분이 있습니다. 
● 간결하고 정확하며 유용한 정보 제작
앱의 접근 가능한 요소가 해당 내용을 올바르게 보고 하는지 확인
사용자 정의 View를 사용하는 경우, 해당 속성 정보를 모두 제공해야합니다. (그 방법들은 및에 나올거임)

Enhancing Default Attribute Information(기본 특성 정보 향상)

iOS는 표준 UIKit컨트롤 및 View의 기본 제공 접근성의 일부로, 이러한 요소를 VoiceOver사용자에게 설명하는 기본 속성 정보도 제공합니다. 대부분의 경우, 이 정보는 표준 컨트롤 및 View를 사용하는 앱에 적합합니다. 그러나 사용자 정의 속성 정보를 제공하면, VoiceOver 사용자의 앱 사용경험이 향상 될 수 있습니다.

● 시스템 제공 icon 또는 제목을 표시하는 표준 UIKit컨트롤 또는 View를 사용하는 경우, 먼저 용도에 맞게 사용하고 있는지 확인하십시오 (자세한 내용은iOS Human Interface Guidelines참고)
그런 다음, 기본 Label 특성이 앱에서 해당 컨트롤이나 View를 사용한 결과를 정확하게 "전달"하는지 여부를 결정합니다. 그렇지 않은 경우, Hint속성을 제공하는 것을 고려하십시오. 
예를들어, UIBarButtonItem개체의 시스템 제공 추가(+)아이콘을 사용하여 우리의 Navigation bar에 배치하면, 기본 Label특성인 [자동 추가]가 자동으로 표시됩니다. 


자 지금은 Label에 그냥 item이라고만 나오죠? 여기에 그냥 시스템에서 제공하는 아이콘만 줘볼게요.




이렇게만 해줘도



Label에 Add가 추가되는 것을 볼 수 있습니다.


계속할게요. 

이 Button을 활성화 할 때, 사용자가 추가하는 아이템에 항상 명확한 경우, Hint를 제공할 필요가 없지만, "계정 추가" 또는 "주석 추가"와 같이 혼란이 있을 경우, 앱에서 해당 컨트롤을 사용한 결과를 설명하는 사용자 지정 Hint를 제공하는 것이 좋습니다.



● UIButton객체와 같은 표준 UIKit View에 사용자 정의 아이콘이나 이미지를 표시하는 경우, 이를 설명하는 사용자 정의 Label속성을 제공해야합니다.



기본 버튼에 image를 추가하면, Label에는 해당 이미지 이름으로 나오게 됩니다. 하지만, 뭐 이렇게하면 heart가 왜;;이게 뭔데;;라고 생각 할 수 있겠죠?

그래서

myButton.accessibilityLabel = "zedd heart button"
cs


이렇게 제가 Label을 지정해줘야한답니다.



이렇게!


Crafting Useful Labels and Hints(유용한 레이블 및 힌트 제작)

VoiceOver사용자가 앱을 실행하면, VoiceOver에서 말하는 설명에 의존하여 앱의 기능과 사용방법을 이해합니다.
이 설명은 당신의 앱에 대한 VoiceOver사용자의 경험을 대변하므로, 가능한 한 정확하고 유용해야합니다.
이 섹션의 지침은 장애인이 사용하기에 쉽고 즐거운 앱을 만들 수 있는 Label 및 Hint를 만드는데 도움이 됩니다. 

○ Guidelines for Creating Labels

label속성은 사용자 인터페이스 요소를 식별합니다. 모든 접근 가능한 사용자 인터페이스 요소(표준 및 사용자 정의)는 Label 속성에 대한 내용을  반드시 제공해야합니다.


Note : Table 행에는 Label속성이 있을 수도 있습니다. 그러나 Table 행 Label을 만들기 위한 지침은 다른 타입의 컨트롤 및 View를 만들기 위한 지침과 다릅니다. 


Label에서 무엇을 전달해야 하는지 결정하는 좋은 방법은, 시력이 정상인 사용자가 앱을 보면서 앱에 대해 어떤 생각을 했는지 보는 것입니다. 좋은 사용자 인터페이스를 설계했다면, 시력이 정사인 사용자는 제목을 읽거나 아이콘을 이해함으로써 현재 앱 컨텍스트에서 컨트롤이나 View가 하는 일을 알아야합니다. 이 정보는 VoiceOver사용자가 Label속성에서 사용 할 수 있도록 해야합니다. 


사용자 지정 컨트롤이나 View를 제공하거나, 표준 컨트롤이나 View에 사용자 지정 아이콘을 표시하는 경우, 다음과 같은 Label을 제공해야합니다.


● 매우 간단하게(Very briefly) 요소를 설명합니다. 이상적으로, Label은 추가, 재생, 삭제, 검색, 즐겨찾기 또는 볼륨과 같은 단일 단어로 구성됩니다. 

단일단어가 요소를 식별하고, 현재 컨텍스트에서 그 사용법을 분명하게 보이도록 앱을 설계하려고 노력하십시오. 그러나 때로는 요소를 적절하게 식별하기 위해, 간단한 구를 사용해야 할 수도 있습니다. 이 경우, "음악 재생", "이름 추가" 또는"이벤트에 추가"와 같은 매우 짧은 구를 만듭니다.


컨트롤 또는 View의 타입을 포함하지 않습니다. 타입 정보는 요소의 traits 속성에 포함되어 있으므로, Label에서 반복해서는 안됩니다. 

예를들어, 추가 버튼 Label에 컨트롤 타입을 포함하면, VoiceOver사용자는 해당 컨트롤에 접근 할 때마다 "버튼 추가 버튼"을 듣게됩니다. 이 경험은 빨리 성가시게 되고, 사용자가 앱 사용을 중단하도록 유도할 수 있습니다. 

허거걱..



헉.. 아까 제가 이 버튼에 이렇게 넣었었잖아요? 이러면 안된다는거죠. 왜냐? traits에 "버튼"이라는 정보가 있기 때문이죠.



대문자로 시작합니다. 이를 통해 VoiceOver는 적절한 굴절을 사용하여 Label을 읽을 수 있습니다. (오..........)


마침표로 끝나지 않습니다. Label은 문장이 아니므로 마침표로 끝나지 않아야 합니다.


로컬라이징 되어 있습니다. 접근성 속성 문자열을 포함하여 모든 문자열을 로컬라이징 하여 최대한 많은 잠재고객에게 앱을 제공 할 수 있게하십시오. 일반적으로 VoiceOver는 사용자가 국가 별 설정에서 지정한 언어로 말합니다.


○ Guidelines for Creating Hints


자..이때까지 Label에 관한 것을 말했다면 이번에는 Hint에 관한것을 말해봅시다.

Hint가 뭔지 <Accessibility Programming Guide for iOS (1)>글에서 설명했죠? 까먹으셨다면...다시 보고 오셔도 되지만..한번 더 설명드리자면,

Hint 속성은 컨트롤이나 View에서 작업을 수행 한 결과를 설명합니다. 요소의 Label에서 action결과가 명확하지 않은 경우에만 Hint를 제공해야합니다.

예를들어, 앱에 재생 버튼을 제공하면, 버튼이 표시된 컨텍스트를 통해 사용자가 탭을 클릭 할 때 발생하는 상황을 쉽게 이해 할 수 있습니다.(재생 버튼을 클릭하면 음악이든 동영상이든 미디어가 재생된다는거는 명확하죠?)

그러나 사용자가 리스트에서 노래 제목을 눌러 노래를 재생하도록 허용한 경우, 이 결과를 설명하는 Hint를 제공 할 수 있습니다. 그 이유는 리스트 항목의 Label이 항목 자체(이 경우 노래 제목)를 설명하기 때문에 사용자가 이를 탭할 때 어떤 일이 발생하지 않기때문입니다. (사용자는 이게 그냥 노래 제목을 나타낸것으로만 알지, 이걸 누르면 노래가 재생될 거라고 모르기 때문이다..뭐 이런말입니다.)


Note: VoiceOver사용자는 장치의 VoiceOver설정에서 옵션을 선택하여 사용 가능한 Hint를 들을지 여부를 선택 할 수 있습니다. Hint는 기본적으로 사용하도록 설정되어 있습니다.


컨트롤이나 View에 대한 사용자의 작업 결과가 Label에 명확하게 암시되지 않은 경우, 다음과 같은 Hint를 작성하십시오.


결과에 대해 간단히 설명합니다. Hint가 필요한 컨트롤과 View는 거의 없지만, 가능한 한 간단하게 Hint를 제공하기 위해 노력하십시오.

이렇게 하면, 요소를 사용하기 전에 사용자가 청취해야하는 시간이 줄어듭니다. 

그러나 간결함을 위해 명확성과 문법을 희생하지 마십시오. 예를들어, "Adds a city"를  “Adds city”로 변경해도 Hint의 길이는 크게 줄어들지 않지만, 어색하고 약간 덜 명확하게 들립니다.



동사로 시작하고 제목을 생략합니다. 

"Plays"와 같은 동사의 3인칭 단수 선언 형식을 사용하고 "Play"와 같은 명령형을 사용하지 마십시오.

(이렇게 명령형(imperative)으로 하며, Hint가 자칫하면 명령(Command)로 들릴 수 있기 때문.)

예를들어, 사용자에게 "Play the song(노래 재생)"이라고 해서 사용자에게 알려주기 보다는 "Plays the song" 이라는 요소를 Tap하고 있다는 것을 알려야 합니다.

올바른 단어를 찾을 수 있도록 하려면, 친구에게 컨트롤을 사용하는 방법을 설명하고 있다고 상상해보십시오. "이 컨트롤을 탭하면 노래가 재생됩니다"와 같은 말을 들을 수도 있습니다. 그런 문장의 두번째 구(이 경우,"Plays the song(노래 재생)")를 Hint로 사용 할 수 있는 경우가 많습니다.

오......이건 꿀팁?이네요. "두번째 구"라니..

이 컨트롤을 탭하면, ~~이 됩니다.에서 ~~를 Hint로 하라는 말 같죠?


대문자로 시작하고 마침표로 끝납니다. Hint는 문장이 아닌 구문이지만, Hint를 마침표로 끝내면, VoiceOver가 적절한 굴절으로 설명 할 수 있습니다.


행동이나 제스쳐의 이름은 포함하지 않습니다. Hint는 사용자에게 동작을 수행하는 "방법"을 알려주지 않으며, 동작을 했을 때 어떤 일이 발생할지를 사용자에게 알려줍니다. 따라서 "노래를 재생하려면 Tap", "항목을 삭제하려면 스와이프"같은 Hint를 만들지 마십시오. VoiceOver사용자는 VoiceOver관련 제스쳐를 사용하여 앱의 요소와 상호작용 할 수 있으므로 특히 중요합니다. 만약 당신이 Hint에 다른 제스쳐를 지명하면, VoiceOver사용자에겐 그게 굉장히 혼란스러울 것입니다.


컨트롤 또는 View의 이름은 포함하지 않습니다. 사용자는 Label속성에서 이 정보를 얻으므로, Hint에서 반복해서는 안됩니다. 따라서 "Save saves your edits(이걸 어떻게 해석해야하지... 저장하여 편집 내용 저장..), "Back returns to the previous screen(이전 화면으로 돌아가기"와 같은 Hint를 만들지 마십시오.


컨트롤 또는 View의 타입을 포함하지 않습니다. 예를 들어, 컨트롤이나 View가 버튼이나 검색 필드 처럼 작동하는지 여부는 사용자가 이미 알고있습니다. 이 정보는 요소의 traits속성에서 사용할 수 있기 때문입니다. 따라서, "이름을 추가 하는 버튼", "눈금을 제어하는 슬라이더"와 같은 Hint를 만들지 마십시오.


로컬라이징 되어 있습니다. 접근성 Label과 마찬가지로, Hint는 사용자가 선호하는 언어로 제공되어야 합니다.



Identifying Appropriate Traits


아 이거 무슨 글을 언제 끊어야 할지 모르겠네요.. 상당히 글이 길어지는데......ㅎㅎㅎ...딱 이까지만 하고 다음글로 써야겠습니다...
앞에서 Label과 Hint를 다뤘으니, 이제 Traits를 다뤄봅시다.
Traits속성은 접근 가능한 사용자 인터페이스 요소의 동작을 함께 나타내는 하나 이상의 개별 traits을 포함합니다. 단일 traits을 설명하기 위해 몇몇의 일부 traits을 결합할 수 있기 때문에 요소의 동작을 정확하게 특성화 할 수 있습니다.

Note : 각각의 traits은 OR연산자를 사용하여 결합됩니다. 코드 예제 이외의 문서에서는 조합 방법을 지정하지 않고, 결합(combine) 및 조합(combination)이라는 더 짧은 용어를 사용합니다. 

Button 또는 TextField와 같은 표준 UIKit컨트롤은 traits특성의 기본 콘텐츠를 제공합니다. 앱에서 표준 UIKit컨트롤만 사용하고 어떤 방식으로든 컨트롤을 사용자 지정하지 않으면, 이러한 컨트롤의 traits속성을 변경 할 필요가 없습니다.

표준 컨트롤의 동작을 사용자 지정하는 경우, 새 traits을 컨트롤의 기본 traits과 결합해야 할 수 있습니다. 사용자 정의 컨트롤 또는 View를 만드는 경우, traits속성에 대한 내용을 제공해야합니다. 

UI접근성 프로그래밍 인터페이스는 12개의 개별 traits을 정의하며, 그 중 일부는 결합될 수 있습니다. 일부 특성은 특정 컨트롤 타입(예 : Button)또는 개체 타입(예 : 이미지)의 동작과 해당 동작을 식별하여 요소의 traits을 지정합니다. 다른 traits은 요소가 표시 할 수 있는 특정 동작(예 : 사운드 재생 기능)을 설명하여 요소의 traits을 지정합니다.
  • Button

  • Link

  • Search Field

  • Keyboard Key

  • Static Text

  • Image

  • Plays Sound

  • Selected

  • Summary Element

  • Updates Frequently

  • Not Enabled

  • None

일반적으로 컨트롤에 해당하는 형질은 행동을 묘사하는 형질과 성공적으로 결합될 수 있습니다. 

예를들어, Button traits을 Plays Sound traits과 결합하여 Button처럼 동작하는 사용자 정의 컨트롤의 traits을 파악하고 태핑될 때 사운드를 재생 할 수 있습니다.

대부분의 경우, 특정 컨트롤에 해당하는 traits, 특히 버튼, 링크, 검색 필드 및 키보드 키 traits을 상호배타적으로 간주해야합니다. 즉, 앱의 요소를 특성화하기 위해, 이러한 특성 중 둘 이상을 사용해서는 안됩니다. 대신 네가지 특성 중 어느것이 앱의 요소와 가장 밀접하게 관련되는지 생각해보십시오. 그런 다음 요소에 추가 동작이 있는 경우, 첫번째 traits을 동작 traits중 하나와 결합 할 수 있습니다. 

예를들어, iPhone에서 Safari의 링크를 열어 사용자의 탭에 응답하는 이미지를 앱에 표시한다고 가정합니다.

  • Button

  • Link

  • Search Field

  • Keyboard Key

  • Static Text

  • Image

  • Plays Sound

  • Selected

  • Summary Element

  • Updates Frequently

  • Not Enabled

  • None

이미지와 링크 traits을 결합하여 이 요소를 특성화 할 수 있습니다. 또 다른 예는, 탭 되었을 때 다른 키보드 키를 수정하는 키보드 키입니다. 키보드 키와 Selected traits을 결합하여 이 요소를 특성화 할 수 있습니다. 

traits으로 컨트롤을 특징 짓는 방벙에 대한 몇가지 예를 보려면, Accessibility Inspector를 사용하여 표준 컨트롤에 설정된 기본 traits을 확인하십시오.



자..오늘은 이까지만 할게요..!!!! 넘나 긴것...3편이 마지막이 될 듯하네요 :) 접근성을 이해하시는데 도움이 되었길 바래요 XD

반응형