Two years ago,I wrote an article entitled "ios VoiceOver support for visually impaired users"Articles,Inside describes how iOS end of the necessary support for VoiceOver,Then I developed a macOS input terminal pocketed,But unfortunately due macOS own system bug,Third-party input method can not obtain focus VoiceOver (mainly 10.13 And below),So I will not have too much attention - even until the end of this input method throughout the life cycle failed to achieve VoiceOver support,It is regrettable。
Pocketed input macOS 2
Fortunately, however,,To macOS 10.14 Mojave,Amazing thing happened,This bug completely "reverse" the,It does not fix,But in another way presented - the system comes with Chinese input method can not obtain focus VoiceOver,Instead, third-party input method it! 😆
In short,This time I have been able to provide support for VoiceOver users :)
Until now,Pocketed input macOS 2 It has officially hit the shelves some time,The first version of the product is relatively improved many,I think it's time to write an article to roughly sum up the focus macOS platform support for VoiceOver。
Decision
To support VoiceOver,You must be able to determine whether the system is currently running VoiceOver,Different from iOS,macOS not given directly determines whether the operation of the API VoiceOver,That is,From the official attitude of,Or want to visually impaired users and sighted users to get as consistent user experience。But in short,,Make certain additional optimized for visually impaired users still necessary,We can determine whether to open VoiceOver preferences by reading system - but it also has shortcomings,For example, a user opens the VoiceOver,But not directly through System Preferences closed VoiceOver,That time we still get is "on" state (Particularly sensitive to the state of VoiceOver developers need to pay attention):
1 2 3 4 5 6 7 8 9 10 |
func NSIsVoiceOverRunning() -> Bool { if let flag = CFPreferencesCopyAppValue("voiceOverOnOffKey" as CFString, "com.apple.universalaccess" as CFString) { if let voiceOverOn = flag as? Bool { return voiceOverOn } } return false } |
Setting tools
If you use the controls provided by the system,It makes no difference and iOS settings,It is worth mentioning that the system comes with the question mark button circle,In some app that is often seen help button,It is the default name called "help",The storyboard modified in a place called "Description”,This is how many people feel a little confused,As a comparison,iOS the corresponding input box,Name called "title”。
Candidate column
For the input method for,Candidate bar is probably the most commonly used interface of a,This is also part of its main UI。In order to provide better customization and better display performance,I actually did not use macOS
InputMethodKit That comes with the candidate field,In addition to that bar candidates simply "show candidates" It's a function outside,All other customization options areinvalidof,Not to mention the addition of these options to customize the function,It is impossible。To this end I realized a candidate bar,But under VoiceOver,When this order is read:
1BACKGROUND first candidate content → → → content 2 → candidate of the second candidate. 3 → → ......
This is not a good experience,Especially in the context of election time these numbers are 123,Users can even track I do not know what screen is - in fact you do not know what input method to select。
NSAccessibilityGroup agreement
This problem is VoiceOver to give you traverse the View,It can not distinguish between what works and what does not,This time we wrapped these elements with a View (in fact you should have to do the same,After all, this is a "candidate" objects,Right? ),Then let your follow View NSAccessibilityGroup This agreement,At this time it is for VoiceOver,It is a unique element of the,VoiceOver will not continue to traverse SubView change under the View。
But,This time a new problem has arisen,The Group did not content,Because it is a custom Group,We need to manually assign this Group。
Group assignment to give,Different from iOS,Under macOS you still need to use methods to achieve rather than directly to the property assignment,such as self.setAccessibilityTitle("Candidate 1") But in fact this assignment will not take effect,I do not know if this is a special need for input method,Or actually a bug in the system,In short,I try to override these methods,The ultimate success of the:
1 2 3 4 |
override func accessibilityLabel() -> String? { return "候选1" } |
Such,When the user moves the focus to the corresponding VoiceOver candidate,VoiceOver will read out the contents of the candidate (this is the "Candidate 1")。of course,It's not enough.,You will find the box is VoiceOver visually Deviation,So you also need to set its position,Although visually impaired users might not mind these small details:
1 2 3 4 5 6 |
override func accessibilityFrame() -> NSRect { if let r = self.superview?.window?.convertToScreen(self.frame) { return r } return self.frame } |
Here we try to get the current candidate bar window,And converting the location information of a candidate into the global screen coordinates and returns (VoiceOver screen coordinates must be level),Such,VoiceOver will focus on being a box。
Finally, the Group identity,If we do not set,Even if the user moves the focus to the VoiceOver corresponding candidate,After pressing the space bar on the screen may still be the first,Because VoiceOver set its own control shortcuts,so,Here, too, support what:
1 2 3 4 5 6 7 |
override func accessibilityRole() -> NSAccessibility.Role? { return .button//设置为 button 角色,这样才能允许交互 } override func accessibilityPerformPress() -> Bool { return true//返回 true 表示接受了本次操作 } |
Such a candidate to complete some of the basic column。
Send NSAccessibility notice
The same as iOS,Sometimes we need to send a notification to trigger a refresh VoiceOver,macOS also support you to do:
1 2 3 4 5 6 7 8 |
extension NSAccessibility.Notification { …… public static let applicationHidden: NSAccessibility.Notification public static let focusedUIElementChanged: NSAccessibility.Notification …… } |
The difference is that with iOS,Desktop-level notice a lot more,Here I only used the two listed above,The former candidate for the notification bar has been hidden,The latter is used to trigger a refresh VoiceOver。
user experience
Prompted the state
Unlike the system comes with Chinese input method,Off the grid and other third-party input method input method as,Support in English mode switch,This is actually for visually impaired users no small confusion,Because they do not know what the current status is,And a small box on the visual cues are also unable to notify them,After exchanges and visually impaired users,I made a simple state tone,When switching to Chinese or English,Issue a different tone to notify。
Other,As the British and switches that prompted little box is actually a window,Then there is a problem,If you switch modes in English or function of complexity,Then this small box will appear snatch VoiceOver focus,This time you need to make it invisible to VoiceOver:
1 2 3 |
w.setAccessibilityHidden(true) w.setAccessibilityElement(false) w.setAccessibilityEnabled(false) |
Unlimited candidate field
Normal,Candidate column page is designed,For the visually impaired user (in fact, sometimes also used to give users sighted) selected word,Pocketed input macOS 2 Support Auto next page,For example, there are currently 16 Candidate,Column shows the default candidate 6 A (first page),Then you move the highlight to continue to move the sixth time,Automatically positioned on the first page and the second page。
Do not read the words to explain words
As discerning as,Visually impaired users will pursue efficiency input,VoiceOver When reading the word of the candidate will first complete read through the entire candidate,Then interpreted literally,This may be very convenient for the user input sentence,A good input words,Then listen to it again found no major problems,It sent,Simply interpreted literally not have to wait behind,Very convenient - but it has too many drawbacks is a homophone of the Chinese characters,Often leads to some typos in it,People all is inevitable,Let alone by listening to (such as:Help me make up a seat tail)。For those who prefer to play alone or play word user,In fact, only word to explain more efficient,In the empty mountains Xinyu suggestion I addedPocketed input macOS 2 Unique "only to explain words do not read the word" mode,Whether pocketed classic interpretation or explanation library library,Can directly support,Very convenient。
Known Issues
of course,Eventually missed a number of remaining issues:
Candidate can not change the name of the column,Perhaps because the input method is a background application due? No matter what name is set for the window,Under VoiceOver always read the "application"。
Another problem is the input completion will trigger the text read aloud,Although little chat speak estimate the seriousness of the problem,But if you're writing a lengthy article,Then the little people crash but unfortunately ......,There is no way I can interrupt this process,The only solution is to manually input the user finishes moving the cursor about ......
I do not remember there is a problem,On macOS,Unsolicited notification have VoiceOver read the content seems to be not in force。
Original article written by LogStudio:R0uter's Blog » Pocketed input macOS 2 How is optimized for VoiceOver
Reproduced Please keep the source and description link:https://www.logcg.com/archives/3153.html