ios – Including subview to UICollectionView breaks VoiceOver and Voice Management


I’ve obtained a ViewController with a UICollectionView utilizing an edge offset to decrease its content material on the display, and a search bar that’s added as a subview, whose body has a unfavourable y worth in order that it seems within the assortment view above the content material.

However because the search bar’s body’s y worth goes past a sure worth (on this instance, -45.0, but it surely will depend on the dimensions of the search bar), accessibility breaks: voice management will utterly ignore it, and VoiceOver will ignore the search bar on the best way down (it jumps instantly from the ‘finished’ button to the primary assortment view cell), though it should deal with the search bar on the best way up.

If the body’s y > -45.0, accessibility features as anticipated.

This isn’t attributable to the search bar per se, as any UIView will trigger the identical difficulty

Is that this a bug in UIAccessibility? Or is there one thing happening right here that may clarify this behaviour?

enter image description here

class ViewController: UIViewController {
    var myCollectionView: UICollectionView?
    var searchBar = UISearchBar()
    let searchBarHeight: CGFloat = 56
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        let view = UIView()
        view.backgroundColor = .white
        setupCollectionView()
        addNavbar()
        addSearchBar()
        
    }
    
    func setupCollectionView() {
        let format: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        format.itemSize = CGSize(width: 80, top: 80)
        
        myCollectionView = UICollectionView(body: self.view.body, collectionViewLayout: format)
        myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
        myCollectionView?.backgroundColor = .crimson
        myCollectionView?.contentInset = UIEdgeInsets(high: 200,
                                                      left: 0,
                                                      backside: 0,
                                                      proper: 0)
        
        myCollectionView?.delegate = self
        myCollectionView?.dataSource = self
        
        view.addSubview(myCollectionView ?? UICollectionView())
        
        self.view = view
    }
    
    func addNavbar() {
        let navBar = UINavigationBar(body: CGRect(x: 0, y: 44, width: view.body.measurement.width, top: 44))
        view.addSubview(navBar)

        let navItem = UINavigationItem()
        let doneItem = UIBarButtonItem(barButtonSystemItem: .finished, goal: nil, motion: nil)
        navItem.rightBarButtonItem = doneItem

        navBar.setItems([navItem], animated: false)
    }
    
    func addSearchBar() {
        searchBar.backgroundColor = .brown
        searchBar.body = CGRect(x: 0,
                                 y: -searchBarHeight * 2,
                                 width: view.body.width,
                                 top: searchBarHeight)
        myCollectionView?.addSubview(searchBar)
    }

}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection part: Int) -> Int {
        return 8
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
        cell.backgroundColor = .cyan
        cell.isAccessibilityElement = true
        cell.accessibilityLabel = "cell (indexPath.row)"
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath)
        cell?.backgroundColor = .darkGray
    }
}

Leave a Reply