在窗口中找出UIBarButtonItem框架?

leo*_*ato 64 iphone cocoa-touch objective-c uikit

UIBarButtonItem没有扩展UIView,所以没有像框架属性.

但是CGRect,相对于应用程序,我有什么方法可以得到它的框架UIWindow

ken*_*ytm 126

你喜欢使用私有API吗?如是,

UIView* view = thatItem.view;
return [view convertRect:view.bounds toView:nil];
Run Code Online (Sandbox Code Playgroud)

当然,在定位AppStore时没有人想要这个.一个更不可靠的方法,并且还使用未记录的功能,但将通过Apple的测试,是循环遍历子视图以查找相应的按钮项.

NSMutableArray* buttons = [[NSMutableArray alloc] init];
for (UIControl* btn in theToolbarOrNavbar.subviews)
  if ([btn isKindOfClass:[UIControl class]])
    [buttons addObject:btn];
UIView* view = [buttons objectAtIndex:index];
[buttons release];
return [view convertRect:view.bounds toView:nil];
Run Code Online (Sandbox Code Playgroud)

index是索引的数组中的栏项.items,删除所有空白的项目之后.这假定按钮按递增顺序排列,这可能不是.更可靠的方法是以增加的值对数组进行排序.当然,这仍然假设条形按钮项必须继承UIControl类,并且是工具栏/导航栏的直接子视图,这也可能不是.buttons.origin.x


如您所见,处理未记录的功能时存在很多不确定性.但是,你只想在手指下弹出一些东西吗?UIBarButtonItem .action可以是以下形式的选择器:

-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;
Run Code Online (Sandbox Code Playgroud)

注意事件参数 - 你可以获得触摸的位置

[[event.allTouches anyObject] locationInView:theWindow]
Run Code Online (Sandbox Code Playgroud)

或按钮视图

[[event.allTouches anyObject] view]
Run Code Online (Sandbox Code Playgroud)

因此,无需迭代子视图或使用未记录的功能来执行您想要执行的操作.

  • 我忘记了事件参数.这显然是最好的选择. (5认同)
  • 请注意,如果用户同时点击多个位置,`[[event.allTouches anyObject]`将无法正常工作.相反,你想获得对应于UITouchPhaseEnded状态的触摸,如:`for(UITouch*touch in [event allTouches]){if([touch phase] == UITouchPhaseEnded){view = [touch view]; } (3认同)
  • convertRect:不再是私人的了 (2认同)

Car*_*man 17

我没有看到这个选项发布(在我看来更简单),所以这里是:

UIView *barButtonView = [barButtonItem valueForKey:@"view"];
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好的解决方案,因为它使用Apple私有API. (2认同)
  • @Gerard "view" 是这里的私有 API。 (2认同)

Jer*_*ler 8

在iOS 3.2中,有一种更简单的方法可以从工具栏按钮显示动作表弹出窗口.仅仅做这样的事情:

- (IBAction)buttonClicked:(UIBarButtonItem *)sender event:(UIEvent *)event
{
 UIActionSheet *popupSheet;
 // Prepare your action sheet
 [popupSheet showFromBarButtonItem:sender animated:YES];
}
Run Code Online (Sandbox Code Playgroud)