HsoiEnterprises / HELargeCenterTabBarController

A Swift UITabBarController with a larger center tab.
Other
45 stars 7 forks source link

Middle tab not hidden from accessibility #13

Closed hipwelljo closed 7 years ago

hipwelljo commented 7 years ago

If you add a large center button, VoiceOver still allows the user to highlight the middle tab, saying aloud "tab, 2 of 3". Activating it doesn't do anything - you have to select the actual center button. How can we hide the second tab from VoiceOver, and update it so the third tab is actually the second tab for example? Or, could we hide the center button from VoiceOver and trigger its action upon activating the second tab?

hsoi commented 7 years ago

Hrm. Good question. It's something I'd have to think about. Full disclosure, I'm not sure when I'll be able to look at this.

If you're able to come up with a solution, please submit a pull-request with your changes.

hipwelljo commented 7 years ago

Okay thanks! I've tried settings isAccessibilityElement to false on the middle vc's tabBarItem but that didn't hide it. I'll try thinking more as well.

hipwelljo commented 7 years ago

Dropbox has the same kind of tab bar and they allow the user to select the middle tab so it says "add file tab, 3 of 5" but double pressing activates the button's action. They also allow the user to highlight the button itself and activate it that way. I like Dropbox's solution.

So, to achieve that you can provide a tabBarItem for your placeholder middle view controller with nil images to give that tab a title and set the titlePositionAdjustment to position if off screen so it's not visible.

Now we just need to trigger the button's selector upon activating that second tab, but how? hm

Note that in some cases it would make sense to not allow highlighting the button, only the tab item. For example in my app the image fits entirely within the tab bar item so there's no need to have two elements activating the same thing. Just need to hide the button via button.isAccessibilityElement = false.

hsoi commented 7 years ago

Question: is Dropbox's tabbar a UITabBarController? or their own homebrew?

hipwelljo commented 7 years ago

It seems very likely it's a tab bar controller. In fact I wondered if they're using HELargeCenterTabBarController, it behaves like it.

hipwelljo commented 7 years ago

I found a solution that works! I added a variable to keep track of the previously selected tab index, then tweaked the delegate methods to always allow selecting the middle tab. Then when it is selected if allowSwitch is false then I force switch back to the previously selected tab. It's not a noticeable switch, it works great!

    public func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        if tabBarController === self {
            if viewController === centerViewController {
                if !allowSwitch {
                    tabBarController.selectedIndex = previouslySelectedTabIndex
                }
                if let centerButton = centerButton {
                    centerButtonAction(centerButton)
                }
            }
            else {
                updateCenterButton()
            }
        }
    }

    public func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        previouslySelectedTabIndex = tabBarController.selectedIndex
        return true
    }
hsoi commented 7 years ago

Cool!

If you find this works out well AND is something that could then be integrated back into the code, open a pull request and I'll get it merged in.

And since it sounds like you have a solution, I'm going to close this. It can be reopened if needed. Thanx!