nek023/QBPopupMenu

Trouble with targetRect and arrow height

Closed this issue · 4 comments

I've been struggling with the location of my popup menus for a couple of hours. I want them to come up adjacent to the location of the user's finger, like in iMessages. In certain areas of my UITableView the QBPopupMenus insist on showing with the arrow facing the wrong direction, and the menu underlapping other controls. I fiddled a lot with targetRect's origin and size but couldn't figure out why things went wrong until I finally stepped through the code for showInView.

At first I thought that popupMenuInsets was responsible. With the default values of 10,10,10,10, there was a 10 px wide rectangle around my screen where the bubble would always come up wrong. But once I set the insets to 0, I STILL had a problem, and I think it is actually all due to a bug in showInView:

if (arrowDirection == QBPopupMenuArrowDirectionDefault) {
    if (targetRect.origin.y - ((self.height + self.arrowSize) - self.popupMenuInsets.top) >= 0) {
        arrowDirection = QBPopupMenuArrowDirectionDown;
    }
    else if (targetRect.origin.y + targetRect.size.height + (self.height + self.arrowSize) + self.popupMenuInsets.bottom < view.bounds.size.height) {
        arrowDirection = QBPopupMenuArrowDirectionUp;
    }
    else {
        CGFloat left = targetRect.origin.x - self.popupMenuInsets.left;
        CGFloat right = view.bounds.size.width - (targetRect.origin.x + targetRect.size.width + self.popupMenuInsets.right);

        arrowDirection = (left > right) ? QBPopupMenuArrowDirectionLeft : QBPopupMenuArrowDirectionRight;
    }
}

There are two places where (self.height + self.arrowDirection) should be (self.height + arrowSize).

But, there's still a problem with bubbles that get too close to the side of the screen, as in this screen shot. The targetRect is 300,200,1,1. Anything with an x origin greater than 292 exhibits the problem to some degree.

screen shot 2014-03-04 at 4 52 15 pm

I think the correct solution is to add two more cases to showInView that check the horizontal width of the targetRect + arrowSize.

And if you've read all the way to the end, thanks! And thanks for releasing this great component. I was in a real bind when I realized that UIMenuController's background color can't be set, and was nearly invisible on my black UITableView.

Thank you for your report.
I fixed showInView: like you said, and drawArrowAtPoint: which decides arrow rect.
I pushed this update to fix branch on this repository, so please try it out.

The drawArrowAtPoint fix works perfectly.
However, I still have a problem in a narrow band because of popupMenuInsets:
screen shot 2014-03-05 at 8 06 16 am

I think the problem is in the Down Arrow case.. it is being subtracted instead of added.

    if (targetRect.origin.y - ((self.height + self.arrowSize) - self.popupMenuInsets.top) >= 0) {
        arrowDirection = QBPopupMenuArrowDirectionDown;
    }

Maybe fixed in b03c089.
Please try it.

Works perfectly. Thanks!