Я создал пустой проект, чтобы воспроизвести проблему следующим образом: ![enter image description here](https://i.stack.imgur.com/jxEjl.png)
Решением является с использованием selectedIndex
для отображения выбранного сегмента и предоставление соответствующего объекта сегмента для уведомления VoiceOver : легко, не правда ли?
Я наивно полагал, что получение подпредставления в массиве сегментированных контрольных подпредставлений с помощью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]!) }
}
Окончательный результат выглядит следующим образом:
![enter image description here](https://i.stack.imgur.com/sCHr3.png)
- Дважды нажмите, чтобы перейти кследующий экран.
- Выберите следующий элемент, чтобы сфокусировать второй сегмент.
- Дважды нажмите, чтобы выбрать сфокусированный элемент.
- Вернитесь на предыдущий экран благодаря
Z gesture
изначально известен iOS с контроллером навигации.Делегат передает индекс и фрейм выбранного сегмента. - Дважды нажмите, чтобы перейти к следующему экрану.
- Сегмент, который был ранее выбран, считывается VoiceOver и остается выбранным.
Теперь вы можете Доступность фокуса на определенном сегменте в UISegmentedControl в соответствии с этим обоснованием.
Я стараюсь избегать "хакерских" решений (таких какодин, на который я только что ссылался), но я готов рассмотреть что угодно.
К сожалению, это решение является хакерским ... извините.Тем не менее, это работает, и я не мог найти другого в другом месте: рассматривать это как личное исправление, если у вас нет более чистого, чтобы поделиться?; o)
ОБНОВЛЕНИЕ ... Вероятно, это тема для второго вопроса.
Я не могу воспроизвести поведение вашего обновления: если вы создаете отдельную тему для этой проблемы, добавьте наиболее подробный код и контекст, чтобы обеспечить наиболее точное решение.