2012-02-29 18 views
6

मेरे पास है UIButton के साथ कस्टम व्यू के रूप में।UIButButtonItem UIVutton के साथ कस्टम व्यू के रूप में - UIButton से, UIBarButtonItem को कैसे एक्सेस करें?

UIButton पर addTarget:action: है। कार्रवाई में मैं एक पॉपओवर प्रस्तुत करता हूं। मैं वर्तमान में sender.frame (UIButton फ़्रेम) से प्रस्तुत कर रहा हूं) मैं इसके बजाय UIBarButtonItem से प्रस्तुत करना चाहता हूं।

मैं UIButton से UIBarButtonItem तक कैसे पहुंच सकता हूं?

उत्तर

9

आप निर्धारित किया है, तो आपके UIButton एक UIBarButtonItem की customView, या कस्टम दृश्य का एक बच्चा है, तो आप कर सकते हैं के रूप में जब तक आप UIToolbar या UINavigationBar नहीं पाते हैं, तब तक अपने बटन से दृश्य पदानुक्रम देखें, फिर उस बटन के लिए बार के आइटम खोजें, जिसका कस्टम दृश्य बटन (या बटन का पूर्वज) है।

ऐसा करने के लिए मेरा पूरी तरह से अनचाहे कोड यहां दिया गया है। आपके बटन वाले आइटम को प्राप्त करने के लिए आप [[self class] barButtonItemForView:myButton] पर कॉल करेंगे।

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

अब, ShowInfo, presentPopoverFromBarButtonItem में: info_Button (presentPopoverFromBarButtonItem के बजाय: इस)

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

आप आदमी! मैं नेविगेशन इटम्स का परीक्षण करने में सक्षम नहीं हूं क्योंकि मैं यूआईटीयूएलबार का उपयोग कर रहा हूं। यह बहुत अच्छा काम करता है! धन्यवाद! – scooter133

6

सबसे पहले, आपको UIBarButtonItem तक पहुंचने की आवश्यकता क्यों है?

फिर, एक कस्टम दृश्य के साथ UIBarButtonItem बनाने के लिए, मैं आपको निम्नलिखित श्रेणी श्रेणी बनाने का सुझाव देता हूं (इस मामले में कस्टम व्यू 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];  
} 

और (पहले आयात UIBarButtonItem+Extension.h) इस तरह उपयोग यह:

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

जहां चयनकर्ता यह एक तरीका है कि वर्ग (लक्ष्य) है कि बार बटन आइटम का उपयोग करता है के अंदर कार्यान्वित किया जाता है है।

अब doSomething: चयनकर्ता के अंदर आप निम्नलिखित हो सकते हैं:

- (void)doSomething:(id)sender 

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

एक वर्ग इस मामले यह उपयोगी है करने के लिए कोड नहीं नकल में। आशा करता हूँ की ये काम करेगा।

पीएस मैं एआरसी का उपयोग नहीं कर रहा हूं लेकिन एक ही विचार भी लागू किया जा सकता है।

संपादित करें:

बार बटन आइटम पहुंचने के लिए नीचे हो सकता है एक आसान समाधान:

  1. उपवर्ग एक UIButton
  2. यह भीतर प्रकार UIBarButtonItem के एक प्रॉपर्टी बनानी होगी (एक कमजोर एक retaincycle से बचने के लिए)
  3. जब आप इसे बनाते हैं तो UIButton में बार बटन आइटम इंजेक्ट करें।

शायद यह काम कर सकता है, लेकिन मैं पहले व्यक्ति को पसंद करूंगा।

+0

मैं कुछ है आपके कोड के समान, हालांकि मैंने UIBarButtonItem का उप-वर्ग किया था क्योंकि बटन की लुक और महसूस बहुत ही कस्टम है। समस्या यह है कि '[popover presentPopoverFromRect: प्रेषक बटन। ध्वनि देखें: प्रेषक बटन ...];' इसे रोटेशन, कीबोर्ड इत्यादि पर पॉपओवर को फिर से स्थापित करने के लिए काफी काम की आवश्यकता होती है। पॉपबार को UIBarButtonItem से प्रस्तुत करने के बाद उन सभी को हटा दिया जाता है और हमेशा UIBarButtonItem को एंकर करता है। – scooter133

0

सुनिश्चित नहीं है कि आपको UIButton की आवश्यकता है। यदि आप जो कर रहे हैं वह किसी क्रिया को प्रेषित कर रहा है, या किसी छवि के साथ बटन को कस्टमाइज़ करना भी है, तो UIBarButtonItem पर्याप्त होना चाहिए।

यदि प्रस्तुति प्राप्त करने के लिए UIButton से फ्रेम को पकड़ने के लिए आप क्या कर रहे हैं, तो मुझे लगता है कि UIBarButtonItem की स्थिति का अनुमान लगाने के लिए आपको बेहतर सेवा दी जा सकती है। यह बहुत मुश्किल नहीं होना चाहिए, खासकर अगर यह आपके UINavigationItem के leftBarButtonItem या rightBarButtonItem में से एक है।

मैं आमतौर पर केआईएसएस (इसे सरल रखें, बेवकूफ!) अंगूठे के नियम के लिए हूं। यहां तक ​​कि ऐप्पल यह करता है ... जब आप स्प्रिंगबोर्ड से ऐप लॉन्च करते हैं, तो ऐप हमेशा ऐप के आइकन से नहीं, स्क्रीन के केंद्र से फैलता है।

बस एक सुझाव।

संपादित

ठीक है, मैं अभी-अभी पढ़ा UIPopoverController reference (मैं एक उपयोग नहीं किया है)। मुझे लगता है कि आप क्या चाहते हैं presentPopoverFromBarButtonItem:permittedArrowDirections:animated: और अपने बीबीआई में पहले पैरामीटर के रूप में पास करने के लिए। आपकी समस्या का समाधान करने का तरीका मौजूद है - बीबीआई के पास कोई फ्रेम नहीं है क्योंकि वे NSView उप-वर्ग नहीं हैं। ऐप्पल जानता है कि आप इस तरह की चीज करना चाहते हैं, और इस विधि को प्रदान करते हैं। साथ ही, मुझे लगता है कि यदि आप इस विधि का उपयोग करते हैं, तो आपका ऑटोरोटेशन भी काम करेगा। मैं इसके बारे में गलत हो सकता हूं, इसे एक शॉट दें।

जहां तक ​​आपके अनुकूलित लेआउट का संबंध है, मुझे लगता है कि यदि आप इसे UIView में दोहराते हैं और इसके साथ बीबीआई कस्टम बनाते हैं, तो आप बेहतर करेंगे। यह निश्चित रूप से आप पर निर्भर है।

किसी भी तरह से, आप इसे अपने एनआईबी के साथ आईबीओलेट के रूप में कनेक्ट करके बीबीआई का संदर्भ प्राप्त करते हैं, या जब आप इसे कोड में बनाते हैं तो इसका संदर्भ सहेजते हैं। फिर बस ऊपर वर्णित पॉपओवर विधि के संदर्भ को पास करें। मुझे लगता है कि यह आपके लिए काम कर सकता है।

MOAR

BBI सिर्फ अपने वर्ग के एक सदस्य है - यह पर एक मजबूत संदर्भ संपत्ति के साथ एक इवर, शायद अपने निब के लिए एक IBOutlet के रूप में जुड़े। फिर आप कक्षा में जो भी तरीका चाहते हैं उससे इसे एक्सेस कर सकते हैं।

उदाहरण: (यकीन नहीं मैं पॉपओवर नियंत्रक स्मृति प्रबंधन का अधिकार है)

@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

वास्तविक समस्या मेरा पॉपओवर है जो UIButton की कार्रवाई से प्रस्तुत किया गया है। जब मैं स्क्रीन को घुमाता हूं, तो पॉपओवर UIBarButtonItem पर लगाया नहीं जाता है, यह क्रिया के प्रेषक के फ़्रेम पर लगाया जाता है, जो UIButton है। मुझे UIButton की आवश्यकता है क्योंकि मेरा UIToolBar कस्टम है, बटन नीचे 84x48 हैं, 3 बटन, फ्लेक्स स्पेस, 4 बटन।UIButton मुझे BartxtonItem के पास एक कस्टम ग्राफिक और लेबल 84x48 में विशिष्ट स्थितियों में लेबल करने की अनुमति देता है। – scooter133

+0

चूंकि BarButtonItems से प्रस्तुत पॉपओवर के पास पोजीशनिंग समस्या नहीं है, मैंने सोचा कि मैं एक प्रेषक कर सकता हूं। UIButton पर SuperView और UIBarButtonItem प्राप्त करें। इसके बजाय मुझे UIToolBar मिल गया। मेरे पास एक टैग के रूप में बटन की स्थिति है, क्या मैं UIBarButtonItem के लिए बस UIToolBar को पार कर सकता हूं? – scooter133

+0

hrms .... एक – QED

0

मान लीजिए कि आप निम्नलिखित के रूप में UIBarButtonItem info_Button को UIButton aButton जोड़ लिया है चलो, इस UIBarButtonItem info_button पारित करेंगे काम करता है से अधिक पॉप बनाने के लिए:

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