4

The navbar button for the rep/activity log can't be tapped when displaying a rating change (+5).

Image

Persists between app runs.

  • App Version: 1.6.2.5
  • Device: iPhone 5 (Global)
  • OS Version: Version 10.2 (Build 14C92)
  • Intermittent. Happened after launching app from a notification and then not using it for 24 h. – Andreas Dec 29 '16 at 0:39
  • Rating? Do you mean reputation? – JAL Dec 29 '16 at 0:46
  • 1
    I've noticed this as well. I think the touch area on the nav bar button has decreased. – JAL Dec 29 '16 at 0:46
  • Yes, reputation – Andreas Dec 29 '16 at 0:47
  • 1
    I think JAL is right and the touch area is just smaller (I've noticed it too, it's not completely un-touchable though). Probably related to this (and the bug that caused that...) – Cai Dec 29 '16 at 0:56
  • 1
    That's probably it. Seems the regular button is just extremely hard to hit now that I try it on my small screen. – Andreas Dec 29 '16 at 1:00
1

This will be fixed in 1.6.3.3, shipping this month.

Before 1.6.2, we were serving a UIButton as the bar button item's custom view when we showed a reputation change. This was causing bugs so we used a UIView as the custom view and put both button modes in it. I'm guessing the internal logic of the navigation bar is such that buttons and button custom views are given a large hit radius, but contents of custom views aren't.

I've overridden point(inside:with:) for both the buttons and the custom view so any tap in the navigation bar to the right of the button's left edge is a hit:

Before

Screenshot with button hit areas overlaid.  The achievement button's hit area is flush with it.

After

Screenshot with button hit areas overlaid.  This time, the achievement button has the same vertical hit area as other buttons and a horizontal hit area that extends to the right edge of the screen.

Code

private class AchievementButton: UIButton {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        guard let navigationBar: UINavigationBar = nextOfReturnedType() else {
            return super.point(inside: point, with: event)
        }

        // The achievement button is always the last one.  We check that the point is at least the left edge and inside the navigation bar.
        return point.x >= bounds.minX && convert(navigationBar.bounds, from: navigationBar).contains(point)
    }
}

private class AchievementCustomView: UIView {

    // Defer to the button.
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        for view in subviews {
            if view.point(inside: view.convert(point, from: self), with: event) {
                return true
            }
        }
        return false
    }
}
|improve this answer|||||
  • Great insight, thanks! – JAL Jan 19 '17 at 20:31
  • Would you mind taking a look at and verifying my answer here as well? – JAL Jan 19 '17 at 20:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .