UIBarButtonItem
不延伸UIView
,所以没有什么像框架属性。找出窗口中的UIBarButtonItem框架?
但是有没有什么办法可以得到它是什么CGRect
框架,相对于应用程序UIWindow
?
UIBarButtonItem
不延伸UIView
,所以没有什么像框架属性。找出窗口中的UIBarButtonItem框架?
但是有没有什么办法可以得到它是什么CGRect
框架,相对于应用程序UIWindow
?
你喜欢用private API吗?如果是的话,
UIView* view = thatItem.view;
return [view convertRect:view.bounds toView:nil];
当然针对AppStore的时候没有人愿意这样。 A 更不可靠方法,也使用未公开的功能,但将通过苹果的测试,是循环通过子视图来查找相应的按钮项。
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];
的index
是索引你的栏项目的.items
,数组中删除所有空白的项目后。这假设按钮排列顺序增加,这可能不是。更可靠的方法是排序buttons
数组中增加.origin.x
值。当然,这仍然假设酒吧按钮项目必须继承UIControl类,并且是工具栏/导航栏的直接子视图,它可能不是。
正如您所看到的,处理无证件功能时存在很多不确定因素。但是,你只是想在手指右下方弹出一些东西?该的UIBarButtonItem的.action
的形式可以是一个选择:
-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;
注意事件参数 - 你可以获取触摸的位置
[[event.allTouches anyObject] locationInView:theWindow]
或
[[event.allTouches anyObject] view]
的按钮来查看
因此,不需要迭代子视图或使用未记录的功能来执行您想要的操作。
您可以从UINavigationBar视图中获取它。 navigationBar是一个UIView,其中有2个或3个自定义subviews用于栏上的零件。
如果您知道UIBarButtonItem当前显示在右侧的导航栏中,则可以从导航栏的子视图数组中获取其框架。
首先您需要navigationBar,您可以从navigationController中获得这些信息,您可以从UIViewController中获取该信息。然后找到最右边的子视图:
UINavigationBar* navbar = curViewController.navigationController.navigationBar;
UIView* rightView = nil;
for (UIView* v in navbar.subviews) {
if (rightView==nil) {
rightView = v;
} else if (v.frame.origin.x > rightView.frame.origin.x) {
rightView = v; // this view is further right
}
}
// at this point rightView contains the right most subview of the navbar
我还没有编译这个代码,所以YMMV。
在iOS 3.2中,通过工具栏按钮显示一个操作页面弹出窗口有一个更简单的方法。仅仅做这样的事情:
- (IBAction)buttonClicked:(UIBarButtonItem *)sender event:(UIEvent *)event
{
UIActionSheet *popupSheet;
// Prepare your action sheet
[popupSheet showFromBarButtonItem:sender animated:YES];
}
这只适用于iPad。 – 2013-05-26 20:56:34
这是我用我的WEPopover项目实施:(https://github.com/werner77/WEPopover):
@implementation UIBarButtonItem(WEPopover)
- (CGRect)frameInView:(UIView *)v {
UIView *theView = self.customView;
if (!theView.superview && [self respondsToSelector:@selector(view)]) {
theView = [self performSelector:@selector(view)];
}
UIView *parentView = theView.superview;
NSArray *subviews = parentView.subviews;
NSUInteger indexOfView = [subviews indexOfObject:theView];
NSUInteger subviewCount = subviews.count;
if (subviewCount > 0 && indexOfView != NSNotFound) {
UIView *button = [parentView.subviews objectAtIndex:indexOfView];
return [button convertRect:button.bounds toView:v];
} else {
return CGRectZero;
}
}
@end
不幸的是,这至少有时不起作用。我有一个以编程方式创建的UIBarButtonItems,我发现当customView设置为非零然后为零时,栏按钮项消失,[parentView.subviews objectAtIndex:indexOfView]崩溃(indexOfView不小于subviews.count)。 – 18446744073709551615 2011-12-27 10:29:21
这不适用于我 – Bogdan 2012-07-16 08:45:01
我使用当前(和工作)实现编辑答案 – 2013-05-24 11:46:36
我能得到沃纳Altewischer的WEpopover通过传递了工具栏的工作随着
UIBarButton: 国防部在WEPopoverController.m
- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item toolBar:(UIToolbar *)toolBar
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections
animated:(BOOL)animated
{
self.currentUIControl = nil;
self.currentView = nil;
self.currentBarButtonItem = item;
self.currentArrowDirections = arrowDirections;
self.currentToolBar = toolBar;
UIView *v = [self keyView];
UIButton *button = nil;
for (UIView *subview in toolBar.subviews)
{
if ([[subview class].description isEqualToString:@"UIToolbarButton"])
{
for (id target in [(UIButton *)subview allTargets])
{
if (target == item)
{
button = (UIButton *)subview;
break;
}
}
if (button != nil) break;
}
}
CGRect rect = [button.superview convertRect:button.frame toView:v];
[self presentPopoverFromRect:rect inView:v permittedArrowDirections:arrowDirections animated:animated];
}
在实施此代码之前,请务必在您的Applition代理application:didFinishLaunchingWithOptions:
方法中拨打[window makeKeyAndVisible]
!
- (void) someMethod
{
CGRect rect = [barButtonItem convertRect:barButtonItem.customview.bounds toView:[self keyView]];
}
- (UIView *)keyView {
UIWindow *w = [[UIApplication sharedApplication] keyWindow];
if (w.subviews.count > 0) {
return [w.subviews objectAtIndex:0];
} else {
return w;
}
}
“UIBarButtonItem”实例没有“bounds”属性。 – 2013-05-17 17:34:21
代码不访问barButtonItem的边界。它正在访问barButtonItem中的自定义视图的边界。 – 2015-12-03 16:52:15
我处理它,如下所示:
- (IBAction)buttonClicked:(UIBarButtonItem *)sender event:(UIEvent *)event
{
UIView* view = [sender valueForKey:@"view"]; //use KVO to return the view
CGRect rect = [view convertRect:view.bounds toView:self.view];
//do stuff with the rect
}
使用私有API,因此它不是一个好的解决方案。 – 2014-11-19 20:39:13
“-valueForKey:是一种文档化的公共方法,KVC API提供了一种防止直接实例变量访问的方法,因此如果该值是可访问的,那么不会采取任何措施禁止访问,一个问题可能是未定义的值在iOS的未来版本中,为了解决这个问题,你可以将调用封装在一个try-block中,并且即使你觉得你不能在应用程序商店中使用它,这并不意味着有人针对越狱的设备在其应用中无法使用这种方法。“用户@ jeremy-w-sherman在另一篇文章中写道 – 2014-11-26 03:18:23
只要UIBarButtonItem
(和UITabBarItem
)不会从UIView
继承 - 由于历史原因UIBarItem
继承自NSObject
- 这种疯狂仍在继续(因此写作,iOS 8.2和计数...)
在这个线程中最好的答案显然是@KennyTM's。不要傻,并使用私有API来查找视图。
这里的一个ONELINE夫特溶液得到一个origin.x
排序后的数组(如Kenny's answer建议):
let buttonFrames = myToolbar.subviews.filter({
$0 is UIControl
}).sorted({
$0.frame.origin.x < $1.frame.origin.x
}).map({
$0.convertRect($0.bounds, toView:nil)
})
阵列现在origin.x
与UIBarButtonItem
帧排序。
(如果你觉得需要了解更多关于其他人的使用的UIBarButtonItem斗争,我建议Ash Furrow's博客帖子从2012年:Exploring UIBarButtonItem)
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
UIView *view = [item valueForKey:@"view"];
return [view frame];
}
这是不是最好的解决方案,从某些角度来看它不正确的解决方案,我们不能做这样的后续,因为我们访问内部UIBarBattonItem
反对含蓄,但你可以试着这样做:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[button setImage:[UIImage imageNamed:@"Menu_Icon"] forState:UIControlStateNormal];
[button addTarget:self action:@selector(didPressitem) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = item;
CGPoint point = [self.view convertPoint:button.center fromView:(UIView *)self.navigationItem.rightBarButtonItem];
//this is like view because we use UIButton like "base" obj for
//UIBarButtonItem, but u should note that UIBarButtonItem base class
//is NSObject class not UIView class, for hiding warning we implicity
//cast UIBarButtonItem created with UIButton to UIView
NSLog(@"point %@", NSStringFromCGPoint(point));
的结果,我旁边有:
点{289,22}
我忘记有关该事件的参数。这显然是最好的选择。 – progrmr 2010-06-14 16:09:52
事件参数ftw。非常感谢。 – 2010-07-29 04:49:15
不错的。谢谢! – Kalle 2011-03-30 11:18:51