2010-07-14 11 views
8

मैं एक गतिशील मेनू (शीर्षक और क्रियाएं सर्वर से आती हैं) के लिए UIMenuController का उपयोग करने का प्रयास कर रहा हूं। समस्या यह है कि मुझे UIMenuItems initWithTitle का उपयोग करना होगा: क्रिया: जहां क्रिया एक @ चयनकर्ता है।डायनेमिक UIMenuItems @selector और गतिशील विधियों के साथ

मैं @ चयनकर्ता (प्रेषण :) का उपयोग कर सकता हूं लेकिन फिर मैं उपयोगकर्ता द्वारा दबाए गए आइटमों में से किस अंतर को अलग करने में सक्षम नहीं हूं। - (शून्य) प्रेषण: (आईडी) प्रेषक {एनएसएलओजी (@ "% @", प्रेषक); } कहता है कि यह एक UIMenuController है और इसमें कोई विधि नहीं है जो बताएगी कि कौन सा मेनू आइटम दबाया गया था।

मैं हर संभावित चयनकर्ता को प्रेषित करने के लिए केवल 100 विधियों को नहीं लिख सकता, ठीक है तो 10 और नहीं होंगे लेकिन फिर भी, यह एक अच्छा विचार नहीं है।

क्या मुझे ऐसे प्रत्येक चयनकर्ता के लिए गतिशील तरीकों को बनाना है? http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html? यह भी अजीब लगता है।

तो इन दोनों के बेहतर प्रस्ताव?

// यह दृष्टिकोण काम नहीं करता है।

- (void)showMenu { 

    [self becomeFirstResponder]; 

    NSMutableArray *menuItems = [[NSMutableArray alloc] init]; 

    UIMenuItem *item; 
    for (MLAction *action in self.dataSource.actions) { 
     item = [[UIMenuItem alloc] initWithTitle:action.title action:@selector(action:)]; 
     [menuItems addObject:item]; 
     [item release]; 
    } 

    UIMenuController *menuController = [UIMenuController sharedMenuController]; 
    menuController.menuItems = menuItems; 
    [menuItems release]; 
    [menuController update]; 
    [menuController setMenuVisible:YES animated:YES]; 

} 

- (void)action:(id)sender { 
    NSLog(@"%@", sender); // gives UIMenuController instead of UIMenuItem 
    // I can not know which menu item was pressed 
} 

// यह दृष्टिकोण वास्तव में बदसूरत है।

- (void)showMenu { 

    [self becomeFirstResponder]; 

    NSMutableArray *menuItems = [[NSMutableArray alloc] initWithCapacity:5]; 

    UIMenuItem *item; 
    NSInteger i = 0; 
    for (MLAction *action in self.dataSource.actions) { 
     item = [[UIMenuItem alloc] initWithTitle:action.text 
                      action:NSSelectorFromString([NSString stringWithFormat:@"action%i:", i++])]; 
     [menuItems addObject:item]; 
     [item release]; 
    } 

    UIMenuController *menuController = [UIMenuController sharedMenuController]; 
    menuController.menuItems = menuItems; 
    [menuItems release]; 
    [menuController update]; 
    [menuController setMenuVisible:YES animated:YES]; 

} 

- (void)action:(NSInteger)number { 
    NSLog(@"%i", number); // gives the index of the action in the menu. 
} 

// This is a hack, I have to assume that there will never be more then 15 actions 
- (void)action0:(id)sender { [self action:0]; } 
- (void)action1:(id)sender { [self action:1]; } 
- (void)action2:(id)sender { [self action:2]; } 
- (void)action3:(id)sender { [self action:3]; } 
- (void)action4:(id)sender { [self action:4]; } 
- (void)action5:(id)sender { [self action:5]; } 
- (void)action6:(id)sender { [self action:6]; } 
- (void)action7:(id)sender { [self action:7]; } 
- (void)action8:(id)sender { [self action:8]; } 
- (void)action9:(id)sender { [self action:8]; } 
- (void)action10:(id)sender { [self action:10]; } 
- (void)action11:(id)sender { [self action:11]; } 
- (void)action12:(id)sender { [self action:12]; } 
- (void)action13:(id)sender { [self action:13]; } 
- (void)action14:(id)sender { [self action:14]; } 

उत्तर

10

वह दृष्टिकोण काम करेगा, हालांकि आपको प्रत्येक बटन के लिए एक अद्वितीय चयनकर्ता-नाम और उस नाम से मैपिंग की आवश्यकता है जिसे आप लक्षित करना चाहते हैं।
चयनकर्ता नाम के लिए एक अनूठी स्ट्रिंग को चुना जाना है (यूयूआईडी या शायद एक sanitized & शीर्षक का उपसर्ग संस्करण काम करेगा)।

- (void)updateMenu:(NSArray *)menuEntries { 
    Class cls = [self class]; 
    SEL fwd = @selector(forwarder:); 
    for (MenuEntry *entry in menuEntries) { 
     SEL sel = [self uniqueActionSelector]; 
     // assuming keys not being retained, otherwise use NSValue: 
     [self.actionDict addObject:entry.url forKey:sel]; 
     class_addMethod(cls, sel, [cls instanceMethodForSelector:fwd], "[email protected]:@"); 
     // now add menu item with sel as the action 
    } 
} 

अब फारवर्डर देख सकते हैं क्या यूआरएल मेनू आइटम से संबद्ध है::

- (void)forwarder:(UIMenuController *)mc { 
    NSLog(@"URL for item is: %@", [actionDict objectForKey:_cmd]); 
} 
तो फिर तुम एक विधि है कि कॉल और अलग चयनकर्ता नाम के साथ "उर्फ" यह निराकरण की जरूरत है

चयनकर्ताओं आप की तरह कुछ इस्तेमाल कर सकते हैं बनाने के लिए:

- (SEL)uniqueActionSelector { 
    NSString *unique = ...; // the unique part 
    NSString *selString = [NSString stringWithFormat:@"menu_%@:", unique]; 
    SEL sel = sel_registerName([selString UTF8String]); 
    return sel; 
} 
+0

_cmd कहां से आता है और यह क्या है? – Jeena

+2

@ जेन: चयनकर्ता के लिए एक कीवर्ड जिसके साथ कार्यान्वयन समारोह लागू किया जाता है। 'NSStringFromSelector (_cmd)' लॉगिंग करने का प्रयास करें। –

+1

बहुत बढ़िया काम दोस्तों, बहुत बहुत धन्यवाद। – sachin

0

जब तक मेनू आइटम एक ही बात करते हैं, क्यों वे एक कार्रवाई साझा करना चाहिए? मैं आगे बढ़ूंगा और उन कार्यों को लिखूंगा जो आपके इच्छित व्यवहार को निर्दिष्ट करते हैं और मेनू आइटम को उनसे लिंक करते हैं।

+1

समस्या यह है कि मैं जो कार्यों वहाँ संकलन समय पर हो जाएगा पता नहीं कर सकते हैं क्योंकि कार्यों ग होगा सर्वर से ओमे, यह हमेशा मेनू के लिए एक शीर्षक होता है और एक http-url जिसे उपयोगकर्ता पर क्लिक करने पर कॉल किया जाना चाहिए। मैं कुछ कोड के साथ सवाल अद्यतन कर दूंगा। – Jeena

संबंधित मुद्दे