找出窗口中的UIBarButtonItem框架?
UIBarButtonItem
不扩展UIView
,所以没有什么像框架属性。
但是,有什么办法可以得到什么是CGRect
框架,相对于应用程序UIWindow
?
你喜欢使用私人API吗? 如是,
UIView* view = thatItem.view; return [view convertRect:view.bounds toView:nil];
定位AppStore当然没有人需要这个。 一个更不可靠的方法,也使用未公开的function,但将通过苹果的testing,是循环通过子视图来查找相应的button项目。
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
数组中的条形项目的索引。 这假定button按照递增的顺序排列,这可能不是。 更可靠的方法是按增加.origin.x
值sorting buttons
数组。 当然这仍然假设酒吧button项目必须inheritanceUIControl类,并且是工具栏/导航栏的直接子视图,也许不是。
正如你所看到的,在处理无证的特征时有很多不确定性。 但是,你只是想在手指下面popup一些东西吗? UIBarButtonItem的.action
可以是以下forms的select器:
-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;
注意事件的参数 – 你可以获得触摸的位置
[[event.allTouches anyObject] locationInView:theWindow]
或用button查看
[[event.allTouches anyObject] view]
因此,不需要迭代子视图或使用未logging的function来执行您想要的操作。
我没有看到这个选项张贴(这在我看来是更简单),所以这里是:
UIView *barButtonView = [barButtonItem valueForKey:@"view"];
在iOS 3.2中,从工具栏button显示一个操作页面popup窗口有一个更简单的方法。 只是做这样的事情:
- (IBAction)buttonClicked:(UIBarButtonItem *)sender event:(UIEvent *)event { UIActionSheet *popupSheet; // Prepare your action sheet [popupSheet showFromBarButtonItem:sender animated:YES]; }
这是我用于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
通过与工具栏一起传递工具条,我可以使Werner Altewischer的WEpopover工作
UIBarButton:Mod在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]; }
只要UIBarButtonItem
(和UITabBarItem
)不从UIView
inheritance – 由于历史原因, UIBarItem
inheritance自NSObject
– 这种疯狂仍在继续(截至本文写作,iOS 8.2和计数…)
在这个线程中最好的答案显然是@ KennyTM的 。 不要傻,使用私有API来查找视图。
这里有一个origin.x
Swift解决scheme来获得一个origin.x
sorting的数组(就像Kenny的答案所示):
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
框架sorting。
(如果您觉得需要阅读更多关于其他人与UIBarButtonItem的斗争,我推荐从2012年的Ash Furrow 的博客文章: 探索UIBarButtonItem )
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{ UIView *view = [item valueForKey:@"view"]; return [view frame]; }
你可以从UINavigationBar视图中获取它。 navigationBar是一个UIView,它有2个或3个自定义子栏的部分在栏上。
如果您知道UIBarButtonItem当前显示在右侧的导航栏中,则可以从导航栏的子视图数组中获取其框架。
首先你需要可以从UIViewController的navigationController中获得的navigationBar 。 然后find最右边的子视图:
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。
这不是最好的解决scheme, UIBarBattonItem
来看,这不是正确的解决scheme,我们不能这样做,因为我们隐式地访问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}
在实现这个代码之前,一定要在你的Applition委托application:didFinishLaunchingWithOptions:
调用[window makeKeyAndVisible]
application:didFinishLaunchingWithOptions:
方法!
- (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; } }
我处理如下:
- (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 }