ios - UIBarButtonItem:针对目标操作调用与 PerformSelector:withObject 的帧处理方式不同:

标签 ios uibarbuttonitem performselector

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

(void)showMyWindow:(id)sender

其中发送者是 UIBarButtonItem。

在showMyWindow:方法中,弹出窗口的绘制需要发送者的框架。现在,UIBarButtonItem 通常不允许您访问其框架。作为一个黑客,我将发送者转换为 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: 时则不行:

为什么会有差异?为什么这种转换在一种情况下可以执行,而在另一种情况下则不能?

谢谢。

最佳答案

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 是 NSObject 的后代,而不是 UIView,并且没有框架属性。在这种情况下,发送者很可能不是您的栏按钮项目,而是属于它的私有(private) View (如果您使用的是系统项目)或其自定义 View 属性。

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

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

关于ios - UIBarButtonItem:针对目标操作调用与 PerformSelector:withObject 的帧处理方式不同:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11645895/

相关文章:

ios - 主动选择器 CSS 在 iOS 8.2、8.3、8.1.3 和 iOS 8.4.1 中无法正常工作

ios - 在所需的初始化中从 NSCoder 获取属性(编码器 aDecoder : NSCoder)

ios - 如何在调用 UIImagePickerController 后隐藏状态栏?

iOS:将多个操作发送到条形按钮

ios - 如何用数据填充选择器 View 并同时运行事件指示器?

objective-c - 在未知类型的类中调用静态方法

ios - NSDateFormatter 和默认语言环境导致错误

ios - 自定义后退按钮标题并保持滑动后退手势

iOS:如何为条形按钮项目设置适当的图像比例

ios - 为什么我在执行 selector :withObject:@YES in iOS, 时总是得到 NO,这在 macOS 中是不同的?