好。 This answer很有帮助。显示屏幕时,我可以选择一个可访问性项目。我只是添加
UIAccessibility.post(notification: .layoutChanged, argument: <a reference to the UI item to receive focus>)
到viewWillAppear()方法的末尾,项目将获得焦点。
但是,在我的一个屏幕中,我要获得焦点的项目是一个UISegmentedControl,并且在聚焦后,无论选择哪个项目,它始终会选择第一个项目。由于我遵循了极好的建议here,因此我为控件中的每个项目都设置了一个可访问性标签,并且我希望我的重点从所选的任何细分开始。
有没有办法做到这一点?通常,我会尽量避免使用“棘手的”解决方案(就像我刚才提到的那样),但是我愿意考虑任何事情。
谢谢!
更新: 只是为了增加侮辱性伤害,我还想选择我要选择的项目,然后再过一秒钟,屏幕将选择内容跳到第一项。这可能是第二个问题的主题。
答案 0 :(得分:1)
解决方案是使用selectedIndex
显示所选的细分,并为VoiceOver notification 提供适当的细分对象:容易,是吗?是吗?
我天真地以为,使用selectedIndex
在分段控件子视图数组中获取子视图将可以完成这项工作,但这绝对不可能,因为子视图可以在该数组内移动,如下所示:快照突出显示(例如,红色边框的第一个元素):
标识唯一段的唯一方法是它的框架,因此我选择了分段的控制索引和所选段的框架,以将它们传递给先前的视图控制器。
当转换后出现此屏幕时,将允许显示(索引)和读出(标识用于通知的对象的框架)适当的选定段
以下是包含“下一个屏幕”按钮的视图控制器的代码片段:
class SOFSegmentedControl: UIViewController, UpdateSegmentedIndexDelegate {
var segmentIndex = 0
var segmentFrame = CGRect.zero
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let segueName = segue.identifier {
if (segueName == "SegmentSegue") {
if let destVC = segue.destination as? SOFSegmentedControlBis {
destVC.delegate = self
destVC.segmentIndex = segmentIndex
destVC.segmentFrame = segmentFrame
}
}
}
}
@IBAction func buttonAction(_ sender: UIButton) { self.performSegue(withIdentifier: "SegmentSegue", sender: sender) }
func updateSegmentIndex(_ index: Int, withFrame frame: CGRect) {
segmentIndex = index
segmentFrame = frame
}
}
...,对于显示分段控件的视图控制器:
protocol UpdateSegmentedIndexDelegate: class {
func updateSegmentIndex(_ index: Int, withFrame frame: CGRect)
}
class SOFSegmentedControlBis: UIViewController {
@IBOutlet weak var mySegmentedControl: UISegmentedControl!
var delegate: UpdateSegmentedIndexDelegate?
var segmentFrame = CGRect.zero
var segmentIndex = 0
var segmentFrames = [Int:CGRect]()
override func viewDidLoad() {
super.viewDidLoad()
mySegmentedControl.addTarget(self,
action: #selector(segmentedControlValueChanged(_:)),
for: .valueChanged)
mySegmentedControl.selectedSegmentIndex = segmentIndex
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print(mySegmentedControl.subviews)
let sortedFrames = mySegmentedControl.subviews.sorted(by: { $0.frame.origin.x < $1.frame.origin.x})
for (index, segment) in sortedFrames.enumerated() { segmentFrames[index] = segment.frame }
if (self.segmentFrame == CGRect.zero) {
UIAccessibility.post(notification: .screenChanged,
argument: mySegmentedControl)
} else {
mySegmentedControl.subviews.forEach({
if ($0.frame == self.segmentFrame) {
UIAccessibility.post(notification: .screenChanged,
argument: $0)
}
})
}
}
@objc func segmentedControlValueChanged(_ notif: NSNotification) {
delegate?.updateSegmentIndex(mySegmentedControl.selectedSegmentIndex,
withFrame: segmentFrames[mySegmentedControl.selectedSegmentIndex]!) }
}
Z gesture
是iOS固有的导航控制器,因此可以返回上一屏幕。委托传递索引和所选段的框架。您现在可以按照此原理在UISegmentedControl中的特定细分上关注可访问性。
我尝试避免使用“ hacky”解决方案(就像我刚才提到的那样),但是我愿意考虑任何事情。
不幸的是,该解决方案是一个棘手的问题……抱歉。但是,它可以正常工作,我在其他任何地方都找不到:将其视为个人修复,除非您可以与他人共享干净的工具? ; o)
更新 ...这可能是第二个问题。
我无法重现您的更新行为:如果您为此问题创建专门的主题,请添加最详细的代码和上下文,以提供最准确的解决方案。