0

我有一个 UIBarButtonItem *按钮。这个想法是用户按下按钮,然后弹出一个窗口。这是在按钮的目标/动作中声明的(即点击按钮调用

(void)showMyWindow:(id)sender

其中发送者是 UIBarButtonItem。

在showMyWindow:方法中,弹窗的绘制需要发送者的框架。现在, UIBarButtonItem 通常不允许您访问它的框架。作为一个 hack,我将发送者转换为 UIView,然后访问这个 UIView 的框架。我不认为这会起作用,但令人惊讶的是,它会起作用。

但是,我也想在别处调用 showMyWindow: 方法。所以我有这行代码:

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

在这里,我的应用程序崩溃了。我已经准确地指出了这个问题:

(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;
    ...
}

关键是:当我使用 target-action 调用该方法时,我可以以某种方式执行此强制转换+访问框架,但当我使用 performSelector:withObject 时不能:

为什么有区别?为什么这种演员可以在一种情况下进行,而不能在另一种情况下进行?

谢谢。

4

1 回答 1

1

作为一个 hack,我将发送者转换为 UIView,然后访问这个 UIView 的框架。我不认为这会起作用,但令人惊讶的是,它会起作用。

UIBarButtonItem 继承自 NSObject,而不是 UIView,并且没有 frame 属性。在这种情况下,发送者很可能不是您的条形按钮项,而是属于它的私有视图(如果您使用的是系统项)或它的自定义视图属性。

当您“手动”调用它时,您实际上是在发送 UIBarButtonItem 实例,该实例没有框架,并且当您将其转换为 UIView 并要求它提供 frame 属性时会崩溃。

sender您可以通过检查调试器中的对象来阐明真正发送的内容。在第一个实例中它将是一个视图子类,在第二个实例中将是一个 UIBarButtonItem(或子类)。

于 2012-07-25T09:06:10.877 回答