So I have a UICollectionView in a UIViewController which is one of the root view controllers in the tab bar. I set a contentInset for the UICollectionView so I can Add a Label to the top of the collectionView, at which point it would mean that the UILabel is part of the collectionView but is not part of the headerView of the collectionView. To achieve the addition of the UILabel to the UICollectionView, I use
collectionView.addSubview(theLabel)
and I turn voice over on and run the application. what happens is that the voiceover goes through all the UICollectionViewCells in the correct order all the way to the last CollectionViewCell to begin, then goes to the Label which is at the top of the collectionView and then goes to the tabBar. I tried the answer in this Change order of read items with VoiceOver, but had no luck, this solution did change the order of
self.accessibilityElements
to the way I want, except the voice over doesn't really follow the order in self.accsibilityElements and I am not really sure what is going on, has anyone come across the same trouble with the accessibility order being screwed up because "addsubView" was used on the UICollectionView. IF (and I say IF, because I don't think anyone would have added a subView to a collectionView this way) anyone has any thoughts please help me out here, been stuck with this bug the longest time.
Edit
class CollectionViewSubViewsAddedByTags: UICollectionView {
override func awakeFromNib() {
super.awakeFromNib()
}
var accessibilityElementsArray = [AnyObject]()
override var accessibilityElements: [AnyObject]?{
get{
return accessibilityElementsArray
}
set(newValue) {
super.accessibilityElements = newValue
}
}
override func accessibilityElementCount() -> Int {
return accessibilityElementsArray.count
}
override func accessibilityElementAtIndex(index: Int) -> AnyObject? {
return self.accessibilityElementsArray[index]
}
override func indexOfAccessibilityElement(element: AnyObject) -> Int {
return (accessibilityElementsArray.indexOf({ (element) -> Bool in
return true
}))!
}
override func didAddSubview(subview: UIView) {
super.didAddSubview(subview)
accessibilityElementsArray.append(subview)
accessibilityElementsArray.sortInPlace { $0.tag<($1.tag)}
}
override func willRemoveSubview(subview: UIView) {
super.willRemoveSubview(subview)
if let index = (accessibilityElementsArray.indexOf({ (element) -> Bool in
return true
})) {
accessibilityElementsArray.removeAtIndex(index)
}
}
}
Thanks, Shabri