any way to know where a UIBarButtonItem has been drawn?

  • I have a toolbar with items on it. One of them is a trash can. When I delete something from the main screen I'd like it to 'minify' towards the trash can, well I think I would, I have to see what it looks like and see if the effect is as nice as I hope, I want to draw attention to where the 'thing' has gone and this seems like a reasonable animation to try.

    However .. I can't figure out what the frame for the UIBarButtonItem is .. it's on a bar with items which change, some flexible space etc, so it's not a fixed offset from either end of the the thing, and I can't find an API which tells me what the frame is for a given item. Is there one I've missed?
  • If your use case permits, you can figure out the frame of the bar button item in it's action selector by giving the selector the following signature:

    - (void)barButtonAction:(UIBarButtonItem *)item event:(UIEvent *)event;

    You can then use the properties of UIEvent to get the touches location, or the view that the touches belong to.

    For instance:
    - (IBAction)barButtonAction:(UIBarButtonItem *)sender event:(UIEvent *)event{
        UITouch *touch = [[event allTouches] anyObject];
        CGPoint locationInView = [[[event allTouches] anyObject] locationInView:self.view];
        NSLog(@"event touch location = %@", [NSValue valueWithCGPoint:locationInView]);
        NSLog(@"touch.view = %@", [touch view]);
    }

    On Sep 12, 2011, at 12:53 PM, Roland King wrote:

    > I have a toolbar with items on it. One of them is a trash can. When I delete something from the main screen I'd like it to 'minify' towards the trash can, well I think I would, I have to see what it looks like and see if the effect is as nice as I hope, I want to draw attention to where the 'thing' has gone and this seems like a reasonable animation to try.
    >
    > However .. I can't figure out what the frame for the UIBarButtonItem is .. it's on a bar with items which change, some flexible space etc, so it's not a fixed offset from either end of the the thing, and I can't find an API which tells me what the frame is for a given item. Is there one I've missed?
  • On 12 Sep 2011, at 11:53 AM, Roland King wrote:

    > However .. I can't figure out what the frame for the UIBarButtonItem is .. it's on a bar with items which change, some flexible space etc, so it's not a fixed offset from either end of the the thing, and I can't find an API which tells me what the frame is for a given item. Is there one I've missed?

    I can't find a frame either, but the bar will give you an array of items, and assuming all the items are UIBarButtonItem, you can iterate over the array to get their widths. From that you can get a good enough rectangle for visual purposes. Here's what I'd start with (composed in Mail, untested):

    - (CGRect) barButtonFrame: (UIBarButtonItem *) aButton
    {
        //  Assumes you are holding a UIToolbar in self.toolbar.
        //  Assumes everything in the toolbar responds to -width
        //  (i.e., UIBarButtonItem, which includes spacers).

        //  The toolbar observes an inset for the first item.
        //  Figure out the inset empirically, and adjust BAR_MARGIN accordingly:
        #define BAR_MARGIN      4.0

        BOOL        found = NO;
        CGRect      buttonFrame = self.toolbar.bounds;
        CGFloat    totalWidth = 0.0;
        for (UIBarButtonItem * item in self.toolbar.items) {
            if (item == aButton) {
                //  Found it.
                buttonFrame.origin.x = totalWidth + BAR_MARGIN;
                buttonFrame.size.width = item.width;
                found = YES;
                break;
            }
            else
                //  Still looking.
                totalWidth += item.width;
        }

        return found? buttonFrame: CGRectZero;
        //  The rect is in the coordinates of self.toolbar.
        //  Convert to self.view coordinates (or whatever) for the animation.
        //  Check for CGRectZero (button not found). There's an argument to
        //  be made that this method should raise an exception if ! found.
    }

    — F
  • On Mon, Sep 12, 2011 at 9:53 AM, Roland King <rols...> wrote:
    > I have a toolbar with items on it. One of them is a trash can. When I delete something from the main screen I'd like it to 'minify' towards the trash can, well I think I would, I have to see what it looks like and see if the effect is as nice as I hope, I want to draw attention to where the 'thing' has gone and this seems like a reasonable animation to try.

    I believe the typical approach is to use a custom view on your bar
    button item and get that view's frame.

    --Kyle Sluder
  • Thanks - that's the one which did it for me. It was a little more complicated because the hit-delete-button action sent a message to the view controller, which removed an item from an underlying model and the it was the model view, listening for updates with KVO, which then had to shuffle the display around and animate the removed one into the trash, ie there was a bit of action-at-a-distance and no way to pass the event directly. However I was able to capture the position at which delete was pressed, tell the view 'this is where the trash can is now' and it then, when it came to do the animation a while later, knew where the trashcan probably was. That worked nicely and the animation has the desired effect.

    Kyle your idea of using a UIView was nice, I had actually tried that earlier, however a custom view isn't displayed on top of the UIBarButtonItem button, it replaces it totally, and I wanted the UIBarButtonItem look, ie the actual button bit, with just my simple icon graphic on top, so I had to make a custom UIImage and set that into the UIBarButtonItem, that defeated the UIView idea, else it would have been perfect.

    I'll file a rdar asking for an API point for this, it must exist as you can display popovers from barbutton items, so the framework knows where they are and I'd like to know too!

    On Sep 13, 2011, at 2:47 AM, Jamie Pinkham wrote:

    > If your use case permits, you can figure out the frame of the bar button item in it's action selector by giving the selector the following signature:
    >
    > - (void)barButtonAction:(UIBarButtonItem *)item event:(UIEvent *)event;
    >
    > You can then use the properties of UIEvent to get the touches location, or the view that the touches belong to.
    >
    > For instance:
    > - (IBAction)barButtonAction:(UIBarButtonItem *)sender event:(UIEvent *)event{
    > UITouch *touch = [[event allTouches] anyObject];
    > CGPoint locationInView = [[[event allTouches] anyObject] locationInView:self.view];
    > NSLog(@"event touch location = %@", [NSValue valueWithCGPoint:locationInView]);
    > NSLog(@"touch.view = %@", [touch view]);
    > }
    >
    > On Sep 12, 2011, at 12:53 PM, Roland King wrote:
    >
    >> I have a toolbar with items on it. One of them is a trash can. When I delete something from the main screen I'd like it to 'minify' towards the trash can, well I think I would, I have to see what it looks like and see if the effect is as nice as I hope, I want to draw attention to where the 'thing' has gone and this seems like a reasonable animation to try.
    >>
    >> However .. I can't figure out what the frame for the UIBarButtonItem is .. it's on a bar with items which change, some flexible space etc, so it's not a fixed offset from either end of the the thing, and I can't find an API which tells me what the frame is for a given item. Is there one I've missed?

  • On Sep 12, 2011, at 11:47 , Jamie Pinkham wrote:

    > If your use case permits, you can figure out the frame of the bar button item in it's action selector by giving the selector the following signature:
    >
    > - (void)barButtonAction:(UIBarButtonItem *)item event:(UIEvent *)event;

    Where is this signature documented? I looked around a bit, but couldn't find it. I wonder what other signatures can be employed.

    --
    Rick

    >
    > You can then use the properties of UIEvent to get the touches location, or the view that the touches belong to.
    >
    > For instance:
    > - (IBAction)barButtonAction:(UIBarButtonItem *)sender event:(UIEvent *)event{
    > UITouch *touch = [[event allTouches] anyObject];
    > CGPoint locationInView = [[[event allTouches] anyObject] locationInView:self.view];
    > NSLog(@"event touch location = %@", [NSValue valueWithCGPoint:locationInView]);
    > NSLog(@"touch.view = %@", [touch view]);
    > }
    >
    > On Sep 12, 2011, at 12:53 PM, Roland King wrote:
    >
    >> I have a toolbar with items on it. One of them is a trash can. When I delete something from the main screen I'd like it to 'minify' towards the trash can, well I think I would, I have to see what it looks like and see if the effect is as nice as I hope, I want to draw attention to where the 'thing' has gone and this seems like a reasonable animation to try.
    >>
    >> However .. I can't figure out what the frame for the UIBarButtonItem is .. it's on a bar with items which change, some flexible space etc, so it's not a fixed offset from either end of the the thing, and I can't find an API which tells me what the frame is for a given item. Is there one I've missed?

  • Posting for the benefit of the list:
    http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Coco
    aFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html


    See the section on Target-Action in UIKit.

    On Sep 13, 2011, at 2:28 PM, Rick Mann wrote:

    >
    > On Sep 12, 2011, at 11:47 , Jamie Pinkham wrote:
    >
    >> If your use case permits, you can figure out the frame of the bar button item in it's action selector by giving the selector the following signature:
    >>
    >> - (void)barButtonAction:(UIBarButtonItem *)item event:(UIEvent *)event;
    >
    > Where is this signature documented? I looked around a bit, but couldn't find it. I wonder what other signatures can be employed.
    >
    > --
    > Rick
    >
    >>
    >> You can then use the properties of UIEvent to get the touches location, or the view that the touches belong to.
    >>
    >> For instance:
    >> - (IBAction)barButtonAction:(UIBarButtonItem *)sender event:(UIEvent *)event{
    >> UITouch *touch = [[event allTouches] anyObject];
    >> CGPoint locationInView = [[[event allTouches] anyObject] locationInView:self.view];
    >> NSLog(@"event touch location = %@", [NSValue valueWithCGPoint:locationInView]);
    >> NSLog(@"touch.view = %@", [touch view]);
    >> }
    >>
    >> On Sep 12, 2011, at 12:53 PM, Roland King wrote:
    >>
    >>> I have a toolbar with items on it. One of them is a trash can. When I delete something from the main screen I'd like it to 'minify' towards the trash can, well I think I would, I have to see what it looks like and see if the effect is as nice as I hope, I want to draw attention to where the 'thing' has gone and this seems like a reasonable animation to try.
    >>>
    >>> However .. I can't figure out what the frame for the UIBarButtonItem is .. it's on a bar with items which change, some flexible space etc, so it's not a fixed offset from either end of the the thing, and I can't find an API which tells me what the frame is for a given item. Is there one I've missed?

    >
previous month september 2011 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today