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