/ / Capire il frame UIBarButtonItem nella finestra? - iphone, goal-c, cacao-touch, uikit

Calcolare il frame UIBarButtonItem nella finestra? - iphone, obiettivo-c, cacao-touch, uikit

UIBarButtonItem non si estende UIView, quindi non c'è niente come una proprietà frame.

Ma c'è un modo per ottenere di cosa si tratta CGRect frame, relativo all'applicazione UIWindow?

risposte:

125 per risposta № 1

Ti piace usare API privataS? Se si,

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

Ovviamente nessuno lo vuole quando si sceglie l'App Store. UN più inaffidabile e utilizza anche funzionalità non documentate, ma supererà il test di Apple, è quello di passare in rassegna le visualizzazioni secondarie per cercare l'elemento pulsante corrispondente.

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

Il index è l'indice dell'elemento della barra nella matrice di .items, dopo aver rimosso tutti gli elementi vuoti. Questo assume i pulsanti sono disposti in ordine crescente, che potrebbe non esserlo. Un metodo più affidabile è quello di ordinare il buttons array in aumento .origin.x valore. Certamente questo ancora assume l'elemento pulsante della barra deve ereditare la classe UIControl e sono visualizzazioni secondarie dirette della barra degli strumenti / barra di navigazione, che potrebbe non esserlo.


Come puoi vedere, ci sono molte incertezze quando si tratta di funzionalità non documentate. Tuttavia, vuoi solo far apparire qualcosa sotto il dito giusto? UIBarButtonItem "s .action può essere un selettore del modulo:

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

notare la evento argomento: è possibile ottenere la posizione di contatto con

[[event.allTouches anyObject] locationInView:theWindow]

o la vista pulsante con

[[event.allTouches anyObject] view]

Pertanto, non è necessario ripetere le visualizzazioni secondarie o utilizzare funzionalità non documentate per ciò che si desidera fare.


16 per risposta № 2

Non ho visto questa opzione pubblicata (che a mio avviso è molto più semplice), quindi eccola qui:

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

8 per risposta № 3

In iOS 3.2, c'è un modo molto più semplice per mostrare un popover del foglio di azione da un pulsante della barra degli strumenti. Fai semplicemente qualcosa del genere:

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

4 per risposta № 4

Questa è l'implementazione che utilizzo per il mio progetto 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 per risposta № 5

Sono stato in grado di far funzionare WEpopover di Werner Altewischer passando la barra degli strumenti insieme al
UIBarButton: La mod è in 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 per risposta № 6

Purché UIBarButtonItem (e UITabBarItem) non eredita da UIView—Per ragioni storiche UIBarItem eredita da NSObject—Questa follia continua (al momento della stesura di questo articolo, iOS 8.2 e conteggio ...)

La migliore risposta in questa discussione è ovviamente @KennyTM "s. Non essere sciocco e usa l'API privata per trovare la vista.

Ecco una soluzione Swift online per ottenere un origin.x matrice ordinata (come La risposta di Kenny suggerisce):

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

L'array è ora origin.x ordinati con il UIBarButtonItem telai.

(Se senti il ​​bisogno di leggere di più sulle lotte degli altri con UIBarButtonItem, ti consiglio Ash Furrow "s post del blog dal 2012: Esplorazione di UIBarButtonItem)


2 per risposta № 7
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
UIView *view = [item valueForKey:@"view"];
return [view frame];
}

1 per risposta № 8

Puoi ottenerlo dalla vista UINavigationBar. La barra di navigazione è un UIView che ha 2 o 3 personalizzati subviews per le parti sulla barra.

Se sai che UIBarButtonItem è attualmente mostrato nella barra di navigazione sulla destra, puoi ottenere il suo frame dall'array di subview della barra di navigazione.

Per prima cosa hai bisogno del barra di navigazione che puoi ottenere da navigationController che puoi ottenere da UIViewController. Quindi trova la subview più giusta:

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

Non ho compilato questo codice in modo da YMMV.


0 per risposta № 9

Questa non è la soluzione migliore e da un certo punto di vista non è la soluzione giusta e non possiamo fare come seguire perché accediamo all'oggetto all'interno UIBarBattonItem implicitamente, ma puoi provare a fare qualcosa del tipo:

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

di conseguenza ho ottenuto il prossimo:

punto {289, 22}

inserisci la descrizione dell'immagine qui


-1 per risposta № 10

Prima di implementare questo codice, assicurati di chiamare [window makeKeyAndVisible] nel delegato dell'appliance application:didFinishLaunchingWithOptions: metodo!

- (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 per risposta № 11

L'ho gestito come segue:

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