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)
6
  • Intermittent. Happened after launching app from a notification and then not using it for 24 h.
    – Andreas
    Dec 29, 2016 at 0:39
  • Rating? Do you mean reputation?
    – JAL
    Dec 29, 2016 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, 2016 at 0:46
  • Yes, reputation
    – Andreas
    Dec 29, 2016 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, 2016 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, 2016 at 1:00

1 Answer 1

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
    }
}
2
  • Great insight, thanks!
    – JAL
    Jan 19, 2017 at 20:31
  • Would you mind taking a look at and verifying my answer here as well?
    – JAL
    Jan 19, 2017 at 20:32

You must log in to answer this question.

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