How to determine position of UIBarButtonItem in UIToolbar?
Asked Answered
N

7

13

What's the easiest way to determine the x,y location of a UIBarButtonItem in a UIToolbar?

The only answer I found is in any way to know where uibarbuttonitem has been drawn.

All proposed answers seem too complicated. There ought to be a simpler way to get the position of the damn UIBarButtonItem isn't there?

Nb answered 22/11, 2011 at 18:21 Comment(0)
S
19

I used this which seems to be the most elegant way

- (CGRect)frameForBarButtonItem:(UIBarButtonItem *)buttonItem
{
    UIView *view = [buttonItem valueForKey:@"view"];
    return  view ? view.frame : CGRectZero;
}
Specious answered 2/5, 2013 at 22:58 Comment(0)
S
13

Unfortunately, there is no easy way of determining the position of a UIBarButtonItem. A UIBarButtonItem is essentially a NSObject that does just two things: describe the look and feel of a toolbar button, and forward events to the designated target/action selector.

Now, given that all buttons are subviews of UIToolbar, and all button events are routed through their respective UIBarButtonItems, it's quite trivial to loop through all subviews of your UIToolbar and when you find a button whose target is that of your UIBarButtonItem, just get the frame of that button. Some code:

UIToolbar *toolbar = <your toolbar>;
UIBarButtonItem *barButtonItem = <your item>;
UIButton *button = nil;
for (UIView *subview in toolbar.subviews) {
    if ([subview isKindOfClass:[UIButton class]]) {
        for (id target in [(UIButton *)subview allTargets]) {
            if (target == barButtonItem) {
                button = (UIButton *)subview;
                break;
            }
        }
        if (button != nil) break;
    }
}
CGRect frame = button.frame;
Strictly answered 25/11, 2011 at 21:36 Comment(1)
Edited answer to change UIButton to UIControl.Coloratura
M
6

This works for me when using popovers from UIBarButtonItems.

- (void)buttonClicked:(id)sender{
{
  CGRect buttonRect = [[sender view] frame];
}
Masterstroke answered 9/5, 2013 at 18:52 Comment(0)
S
5

For iOS 11 (and maybe above) the call:

if let view = barButtonItemView.value(forKey: "view") as? UIView {
        let viewFrame = view.frame    
}

will return a zero point origin for the view. To counter this, ask for the window coordinates of the view, by using:

let actualPointOnWindow = view.convert(view.frame.origin, to: nil)

If your toolbar has any translations subtract them from the calculated point to find its position on the toolbar.

Complete Code:

if let view = barButtonItemView.value(forKey: "view") as? UIView {
     let viewFrame = view.frame    
     let actualPointOnWindow = view.convert(view.frame.origin, to: nil)
}
Shanonshanta answered 8/2, 2019 at 10:4 Comment(0)
W
3

A more 'swifty' SWIFT way:

func userAction(sender: AnyObject) {
    if let originView = sender.valueForKey("view") {
        let frame = originView.frame  //it's a UIBarButtonItem
    } else {
        let frame = sender.frame //it's a regular UIButton
    }
}

UIBarButtonItem is NOT a subclass of UIView even though it's essentially a button. Go figure.

Wilona answered 11/2, 2016 at 17:18 Comment(0)
Y
2

I used johosher's approach to get the position of a UIBarButtonItem using Swift.

Since I needed the position as sourceRect for a popoverPresentationController I had to convert it to self.view. I am not sure, whether this is a good solution but it works very well and the popover shows off right of the UIBarButtonItem.

let senderRect = sender.view!!.convertRect(sender.view!!.bounds, toView: self.view)

// additional code for the popover controller
alertController.modalPresentationStyle = UIModalPresentationStyle.Popover
alertController.popoverPresentationController?.sourceRect = senderRect
alertController.popoverPresentationController?.sourceView = self.view
Year answered 14/6, 2015 at 22:16 Comment(0)
S
0
UIToolbar *toolbar;

for (UIView *v in [toolbar items]) 
{
    if ([v isKindOfClass:[UIBarButtonItem class]])
    {
        UIBarButtonItem *b = (UIBarButtonItem*)v;
        //do something with b..
    }
}
Sorrel answered 30/11, 2012 at 0:12 Comment(2)
Does this answer the question of determining the position? It doesn't seem to offhand.Vanderhoek
Not yet.. But you can access to the UIBarButtonItem //toolbar.subviews not works //try to improve the answerSorrel

© 2022 - 2024 — McMap. All rights reserved.