Question

I have a UIBarButtonItem *button. The idea is that the user presses the button and then a window pops out. This is declared in the target/action of the button (i.e. tapping the button calls

(void)showMyWindow:(id)sender

where the sender is the UIBarButtonItem.

In the showMyWindow: method, the drawing of the pop-up window requires the frame of the sender. Now, UIBarButtonItem doesn't typically allow you to access its frame. As a bit of a hack, I've cast the sender to a UIView and then accessed this UIView's frame. I didn't think this would work but, surprisingly, it does.

However, I also want to call the showMyWindow: method elsewhere. So I have this line of code:

[self performSelector:@selector(showMyWindow:) withObject:self.button];

Here, my app crashes. I've pinpointed the problem exactly to this:

(void)showMyWindow:(id)sender 
{
    //I should be checking before the cast here, but it helps illustrate the problem
    UIView *senderAsView = (UIView *)sender
    CGRect frame = senderAsView.frame;
    ...
}

The point is: I can somehow perform this cast+access the frame when I call the method with target-action, but not when I use performSelector:withObject:

Why is there a difference? Why can this cast be performed in one case but not the other?

Thanks.

Was it helpful?

Solution

As a bit of a hack, I've cast the sender to a UIView and then accessed this UIView's frame. I didn't think this would work but, surprisingly, it does.

UIBarButtonItem is descended from NSObject, not UIView, and does not have a frame property. The sender in this case is most likely not your bar button item, but either a private view belonging to it (if you are using a system item) or the custom view property of it.

When you call it "manually" you really are sending the UIBarButtonItem instance, which does not have a frame, and will crash when you cast it to a UIView and ask it for the frame property.

You can clarify what is really being sent by examining the sender object in the debugger. It will be a view subclass in the first instance, and a UIBarButtonItem (or subclass) in the second.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top