2012-02-29 18 views

Odpowiedz

9

Jeżeli ustawiłeś UIButton jako customView z UIBarButtonItem lub dziecka widoku niestandardowego, możesz przejdź do hierarchii widoków od przycisku, aż znajdziesz UIToolbar lub UINavigationBar zawierający przycisk, a następnie wyszukaj elementy paska dla tego, którego niestandardowym widokiem jest przycisk (lub przodek przycisku).

Oto mój całkowicie nietestowany kod do robienia tego. Zadzwoniłbyś pod numer [[self class] barButtonItemForView:myButton], aby uzyskać element zawierający twój przycisk.

+ (BOOL)ifBarButtonItem:(UIBarButtonItem *)item containsView:(UIView *)view storeItem:(UIBarButtonItem **)outItem { 
    UIView *customView = item.customView; 
    if (customView && [view isDescendantOfView:customView]) { 
     *outItem = item; 
     return YES; 
    } else { 
     return NO; 
    } 
} 

+ (BOOL)searchBarButtonItems:(NSArray *)items forView:(UIView *)view storeItem:(UIBarButtonItem **)outItem { 
    for (UIBarButtonItem *item in items) { 
     if ([self ifBarButtonItem:item containsView:view storeItem:outItem]) 
      return YES; 
    } 
    return NO; 
} 

+ (UIBarButtonItem *)barButtonItemForView:(UIView *)view { 
    id bar = view; 
    while (bar && !([bar isKindOfClass:[UIToolbar class]] || [bar isKindOfClass:[UINavigationBar class]])) { 
     bar = [bar superview]; 
    } 
    if (!bar) 
     return nil; 

    UIBarButtonItem *item = nil; 

    if ([bar isKindOfClass:[UIToolbar class]]) { 
     [self searchBarButtonItems:[bar items] forView:view storeItem:&item]; 
    } 

    else { 
     UINavigationItem *navItem = [bar topItem]; 
     if (!navItem) 
      return nil; 
     [self ifBarButtonItem:navItem.backBarButtonItem containsView:view storeItem:&item] 
     || [self ifBarButtonItem:navItem.leftBarButtonItem containsView:view storeItem:&item] 
     || [self ifBarButtonItem:navItem.rightBarButtonItem containsView:view storeItem:&item] 
     || ([navItem respondsToSelector:@selector(leftBarButtonItems)] 
      && [self searchBarButtonItems:[(id)navItem leftBarButtonItems] forView:view storeItem:&item]) 
     || ([navItem respondsToSelector:@selector(rightBarButtonItems)] 
      && [self searchBarButtonItems:[(id)navItem rightBarButtonItems] forView:view storeItem:&item]); 
    } 

    return item; 
} 
+0

Ty człowiek! Nie byłem w stanie przetestować NavigationItems, ponieważ używam UIToolBar. Działa to bardzo dobrze! Dziękuję Ci! – scooter133

6

Po pierwsze, dlaczego potrzebujesz dostępu do UIBarButtonItem?

Następnie, aby utworzyć UIBarButtonItem z niestandardowym widokiem, sugeruję utworzenie rozszerzenia kategorii podobnego do poniższego (w tym przypadku niestandardowy widok to UIButton).

//UIBarButtonItem+Extension.h  
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action; 

//UIBarButtonItem+Extension.m  
+ (UIBarButtonItem*)barItemWithImage:(UIImage*)image title:(NSString*)title target:(id)target action:(SEL)action 
{ 
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
    button.frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height); 
    button.titleLabel.textAlignment = UITextAlignmentCenter; 

    [button setBackgroundImage:image forState:UIControlStateNormal]; 
    [button setTitle:title forState:UIControlStateNormal]; 
    [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 

    UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; 

    return [barButtonItem autorelease];  
} 

i używać go tak (najpierw zaimportować UIBarButtonItem+Extension.h):

UIBarButtonItem* backBarButtonItem = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"YoutImageName"] title:@"YourTitle" target:self action:@selector(doSomething:)]; 

gdzie selektor to metoda, która jest realizowana wewnątrz klasy (celu), który używa tego elementu przycisku bar.

Teraz wewnątrz selektora doSomething: można następujące:

- (void)doSomething:(id)sender 

    UIButton* senderButton = (UIButton*)sender;  
    [popover presentPopoverFromRect:senderButton.bounds inView:senderButton...]; 
} 

kategorii w tym przypadku jest to przydatna nie powielać kodu. Mam nadzieję, że to pomoże.

P.S. Nie używam ARC, ale można też zastosować te same rozważania.

Edit:

Proste rozwiązanie, aby wybrać pozycję przycisk Pasek może być następująca:

  1. Podklasa UIButton
  2. wywołują w niej właściwość typu UIBarButtonItem (słaba w celu uniknięcia retaincingu)
  3. Wstawić element przycisku paska w UIButton podczas tworzenia.

Może to zadziała, ale wolę pierwszy.

+0

mam coś Podobny do twojego kodu, chociaż zrobiłem Subclass UIBarButtonItem, ponieważ Wygląd i styl przycisku jest całkiem niestandardowy. Problem polega na tym, że '[popover presentPopoverFromRect: senderButton.bounds inView: senderButton ...]; ' Wymaga to sporego wysiłku, aby ponownie umieścić popover na rotacji, klawiaturze itp. Popover pokazany z UIBarButtonItem eliminuje to wszystko i zawsze zakotwicza do UIBarButtonItem. – scooter133

0

Nie jesteś pewien, czy potrzebujesz Uibutton. Jeśli to, co robisz, wywołuje akcję, a nawet dostosowujesz przycisk do obrazu, to powinno wystarczyć ustawienie UIBarButtonItem.

Jeśli chcesz uzyskać klocek z UIButton, aby uzyskać prezentację, prawdopodobnie lepiej będzie ci po prostu oszacować pozycję UIBarButtonItem. Nie powinno to być zbyt trudne, szczególnie jeśli jest to jedna z tych wartości: UINavigationItemleftBarButtonItem lub leftBarButtonItem.

Generalnie używam zasady KISS (Keep It Simple, Stupid!). Nawet Apple robi to ... kiedy uruchamiasz aplikację z Springboard, aplikacja zawsze rozwija się ze środka ekranu, a nie z ikony aplikacji.

Tylko sugestia.

EDIT

OK, po prostu przeczytać UIPopoverController reference (nigdy nie używałem jeden). Myślę, że to, czego chcesz, to presentPopoverFromBarButtonItem:permittedArrowDirections:animated: i przekazanie BBI jako pierwszego parametru. Powodem istnienia tej metody jest rozwiązanie twojego problemu - BBI nie mają ram, ponieważ nie są podklasami NSView. Apple wie, że chcesz robić tego rodzaju rzeczy i zapewnia tę metodę. Myślę też, że jeśli użyjesz tej metody, to Twoja autorotacja również będzie działać. Mogę się mylić, dać temu szansę.

Jeśli chodzi o twój własny układ, myślę, że jeśli skopiujesz go w UIView i sprawisz, że będzie to zgodne z BBI, zrobisz to lepiej. To oczywiście zależy od Ciebie.

Tak czy inaczej, uzyskuje się odniesienie do BBI przez połączenie go jako IBOutlet z NIB lub poprzez zapisanie odniesienia do niego podczas tworzenia go w kodzie. Po prostu przekaż to odwołanie do metody popover, którą opisałem powyżej. Myślę, że to może ci pomóc.

moar

BBI jest tylko członkiem swojej klasie - W Ivar z silnym własności odniesienia na nim, być może wiąże się jako IBOutlet do Twojego NIB. Następnie możesz uzyskać do niego dostęp z dowolnej metody w klasie.

Przykład: (nie wiem, że mam popover kontrolera zarządzania pamięcią prawo)

@interface MyViewController : UIViewController { 
    UIBarButtonItem *item; 
} 

@property (nonatomic, retain) UIBarButtonItem *item; 

@end 



@implementation MyViewController 

@synthesize item; 

-(void)viewDidLoad { 
    // assuming item isn't in your NIB 
    item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlus target:self action:@selector(doit)]; 
    self.navigationItem.rightBarButtonItem = item; 
} 

-(void)doit { 
    UIPopoverController *popover = [[[UIPopoverController alloc] initWithContentViewController:yourViewController] autorelease]; 
    [popover presentPopoverFromBarButtonItem:self.item permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
    // or in the line above, replace self.item with self.navigationItem.rightBarButtonItem 
} 

@end 
+0

Prawdziwym problemem jest mój Popover przedstawiony z działania UIButton. Kiedy obracam ekran, popover nie jest zakotwiczony do UIBarButtonItem, jego zakotwiczony do ramki nadawcy akcji, która jest Uibuttonem. Potrzebowałem UIButton jako mojego UIToolBar jest Custom, przyciski są 84 x 48 na dole, 3 przyciski, flex przestrzeń, 4 przyciski.Uibutton pozwala mi mieć BartButtonItem mieć niestandardową grafikę i etykietę w określonych pozycjach w 84x48. – scooter133

+0

Ponieważ Popover, które są przedstawione z BarButtonItems nie mają problemu z pozycjonowaniem, myślałem, że mogę zrobić sender.superView na UIButton i uzyskać UIBarButtonItem. zamiast tego dostaję UIToolBar. Mam pozycję przycisku jako znacznika, czy mogę po prostu przemieścić UIToolBar dla UIBarButtonItem? – scooter133

+0

hrms .... powiesić jeden – QED

0

Powiedzmy dodaniu UIButton aButton do UIBarButtonItem info_Button następująco:

//Add a button on top of the UIBarButtonItem info_button 
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; 
[aButton addTarget:self action:@selector(showInfo:) forControlEvents:UIControlEventTouchUpInside]; 
info_Button.customView = aButton; 

Teraz w showinfo, presentPopoverFromBarButtonItem: info_Button (zamiast presentPopoverFromBarButtonItem: nadawcy), to zdać info_button UIBarButtonItem aby pop ponad prac:

- (IBAction)showInfo:(id)sender 
{ 
    [self.flipsidePopoverController presentPopoverFromBarButtonItem:info_Button permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

} 
0
// get the UIBarButtonItem from the UIButton that is passed in sender 
UIToolbar *toolbar = (id)[sender superview]; 
UIBarButtonItem *ourButtonItem = [toolbar items][2];//pick the right index 
[parkingPopOver_ presentPopoverFromBarButtonItem:ourButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 
Powiązane problemy