/ / Zistiť UIBarButtonItem rám v okne? - iphone, objektív-c, kakao-touch, uikit

Zistiť rám UIBarButtonItem v okne? - iphone, objektív-c, kakao-dotyk, uikit

UIBarButtonItem sa nerozširuje UIView, takže neexistuje nič ako vlastnosť rámu.

Existuje však nejaký spôsob, ako zistiť, čo to je CGRect rám, relatívne k aplikácii UIWindow?

odpovede:

125 pre odpoveď č. 1

Páči sa vám používať súkromné ​​APIs? Ak áno,

UIView* view = thatItem.view;
return [view convertRect:view.bounds toView:nil];

Nikto to samozrejme nechce pri zacielení na AppStore. nespoľahlivejšie metóda, a tiež používa nezdokumentované funkcie, ale prejde Appleovým testom, je opakovať subviews a vyhľadať zodpovedajúcu položku tlačidla.

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];

Na index je index vašej položky v poli v poli .items, po odstránení všetkých prázdnych položiek, toto predpokladá, tlačidlá sú usporiadané vo vzostupnom poradí, ktoré nemusí byť. Spoľahlivejšou metódou je druh na buttons pole vo vzostupe .origin.x hodnota. Samozrejme to stále predpokladá, položka tlačidla na paneli musí zdediť triedu UIControl a sú priamymi čiastkovými zobrazeniami na paneli nástrojov / navigačnej lište, ktoré opäť nemusia byť.


Ako vidíte, pri manipulácii s nezdokumentovanými prvkami existuje veľa neistôt. Chceš však len niečo vyskočiť pod prst, nie? UIBarButtonItem "s .action môže byť selektorom formulára:

-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;

poznamenajte si udalosť argument - môžete získať pozíciu dotyku s

[[event.allTouches anyObject] locationInView:theWindow]

alebo zobrazenie tlačidiel pomocou

[[event.allTouches anyObject] view]

Preto nie je potrebné opakovať podhľady alebo používať funkcie bez dokladov pre to, čo chcete robiť.


16 pre odpoveď č. 2

Nevidel som túto možnosť zverejnenú (čo je podľa mňa oveľa jednoduchšie), takže tu je:

UIView *barButtonView = [barButtonItem valueForKey:@"view"];

8 pre odpoveď č. 3

V systéme iOS 3.2 existuje oveľa jednoduchší spôsob, ako zobraziť vyskakovacie okno Akčný list z tlačidla na paneli nástrojov. Stačí urobiť niečo také:

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

4 pre odpoveď č. 4

Toto je implementácia, ktorú používam pre svoj projekt 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

2 pre odpoveď № 5

Podarilo sa mi dostať WEpopover Wernera Altewischera do práce prechodom hore na paneli nástrojov spolu s
UIBarButton: Mod je v 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];
}

2 pre odpoveď č. 6

Tak dlho UIBarButtonItem (a UITabBarItem) nededí z UIView—Z historických dôvodov UIBarItem z dedičstva NSObject—Toto šialenstvo pokračuje (v čase písania tohto článku, iOS 8.2 a počíta sa ...)

Najlepšia odpoveď v tomto vlákne je zjavne @KennyTM. Nebu

Toto je jednoriadkové riešenie Swift na získanie origin.x zoradené pole (ako Kennyho odpoveď navrhuje):

    let buttonFrames = myToolbar.subviews.filter({
$0 is UIControl
}).sorted({
$0.frame.origin.x < $1.frame.origin.x
}).map({
$0.convertRect($0.bounds, toView:nil)
})

Pole je teraz origin.x zoradené podľa UIBarButtonItem rámy.

(Ak cítite potrebu prečítať si viac o bojoch iných ľudí s UIBarButtonItem, odporúčam Jaseňová brázda blogový príspevok z roku 2012: Preskúmanie položky UIBarButtonItem)


2 pre odpoveď č. 7
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
UIView *view = [item valueForKey:@"view"];
return [view frame];
}

1 pre odpoveď č. 8

Získate ho z pohľadu UINavigationBar. NavigationBar je UIView, ktorý má 2 alebo 3 vlastné subviews pre diely na lište.

Ak viete, že položka UIBarButtonItem sa momentálne zobrazuje v navigačnej lište vpravo, môžete získať jej rámec z poľa subviews navbar.

Najprv potrebujete navigačná lišta ktoré môžete získať z internetu navigationController ktoré môžete získať z UIViewController. Potom nájdite ten pravý subview:

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

Tento kód som ešte nezostavil, takže YMMV.


0 pre odpoveď č. 9

Toto nie je najlepšie riešenie a z nejakého hľadiska to nie je správne riešenie a nemôžeme ho nasledovať, pretože máme prístup k objektu vo vnútri. UIBarBattonItem implicitne, ale môžete skúsiť urobiť niečo ako:

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));

ako výsledok som dostal ďalšie:

bod {289, 22}

tu zadajte popis obrázku


-1 pre odpoveď č. 10

Pred implementáciou tohto kódu nezabudnite zavolať [window makeKeyAndVisible] vo vašom zástupcovi žiadosti application:didFinishLaunchingWithOptions: metóda!

- (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;
}
}

-1 pre odpoveď č. 11

Riešil som to nasledovne:

- (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
}