2010-09-20 18 views
8

मुझे UIAlertView अवरुद्ध करने की आवश्यकता है। क्योंकि मेरे पास काम है और मुझे UIAlertView विकल्प वापस करने की आवश्यकता है। लेकिन समस्या यह है कि UIAlertView के बाद दिखाया गया है कि मेरा फ़ंक्शन कोड आगे निष्पादित कर रहा है इसलिए मैं UIAlertView पसंद नहीं कर सकता (मैं इसे प्रतिनिधि तरीकों से कर सकता हूं, लेकिन मुझे फ़ंक्शन परिणाम वापस करने की आवश्यकता है)।UIAlertView ब्लॉकिंग

मैंने NSCondition के साथ अवरुद्ध करने की कोशिश की। लेकिन कोड काम नहीं करता है।

condition = [NSCondition new]; 
result = 0 ; 
[condition lock]; 
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Fingerprint" message:@"test" delegate:window_self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil]; 
[alert setDelegate:self]; 
[alert show]; 
while (result == 0) [condition wait]; 
[condition unlock] ; 

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
[condition lock] ; 
if (buttonIndex == 0) 
{ 
    result = 2; 
} 
else if (buttonIndex == 1) 
{ 
    result = 3 ; 
} 
[condition signal] ; 
[condition unlock] ; 
} 

हो सकता है कि कैसे इस कोड को या किसी अन्य सुझाव ठीक करने के लिए? धन्यवाद

उत्तर

8

आप जो चाहते हैं उसे हासिल करने का कोई तरीका नहीं है। केवल प्रतिनिधि के माध्यम से। आपको अपने फ़ंक्शन को फिर से डिजाइन करना चाहिए या UIAlertView

+0

धन्यवाद। मैंने अपने फ़ंक्शन तर्क को फिर से डिजाइन किया। – kesrut

2

का उपयोग करके इनकार करना चाहिए, मुझे बस एक ही समस्या का सामना करना पड़ रहा था। हालांकि कोई समाधान नहीं है, कम से कम 2 कामकाज हैं जिनके बारे में मैंने सोचा था।

लूप "समाधान" यूआईएलर्ट को कॉल करने के ठीक बाद आप एक लूप शुरू करते हैं जो आपके ऑब्जेक्ट पर वैश्विक रूप से एक वैरिएबल में परिवर्तन की तलाश करता है (पूरे प्रोजेक्ट पर नहीं, आपको दिमाग में) वह चर है जिसे आप सेट करते हैं UIAlert प्रतिनिधि में जो उत्तर लेता है। तो मूल रूप से आप "ए == 1, अगर नहीं करते हैं" और इसके लिए लूप की प्रतीक्षा करें।

तब प्रतिनिधि पर आप बनाना एक = 1 आप इस सवाल का जवाब है, जब

और इससे पहले कि कोई यह बताता है कोको में कोई DoEvents है कि वहाँ:

void MyTestClass::DoEvents() 
{ 

  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
  NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask 
    untilDate:[NSDate distantPast] 
    inMode:NSDefaultRunLoopMode 
    dequeue:YES]; 
  if (event) { 
    [NSApp sendEvent:event]; 
    [NSApp updateWindows]; 
  } 
  [pool release]; 
} 

प्रतिनिधि समाधान के बजाय कोड होने कि अलर्ट को कॉल करने वाले फ़ंक्शन में उत्तर ए, बी या सी से संबंधित है, प्रतिनिधि को कोड में ही कोड है।

उम्मीद है कि यह मदद करता है। मैंने अपनी परियोजना में दूसरा इस्तेमाल किया और यह काम किया।

@interface EvilShitClass() <UIAlertViewDelegate> 
@end 

@implementation EvilShitClass { 
    BOOL _isCanceled, _wasYes; 
} 

यहाँ एक हाँ/नहीं क्वेरी के लिए स्थिर विधि है:

+0

ओपी आईओएस के समाधान के बाद था, जो मुझे नहीं लगता कि यह है। –

1

मैं बस दुर्घटना से और यहां तक ​​कि इस पोस्ट करके एप्पल नरक दर्ज करके इस सवाल का पाया, मैं इसके द्वारा अवधारणा का एक सबूत के रूप में इस का प्रचार:

+ (BOOL)yesNoQueryWithTitle:(NSString*)title text:(NSString*)text { 

    EvilShitClass *shit = [EvilShitClass new]; 
    UIAlertView *alertView = [UIAlertView new]; 
    alertView.delegate = shit; 
    alertView.title = title; 
    alertView.message = text; 
    [alertView addButtonWithTitle:@"Yes"]; 
    [alertView addButtonWithTitle:@"No"]; 

    NSRunLoop *run_loop = [NSRunLoop currentRunLoop]; 

    [alertView show]; 

    while(!shit->_isCanceled) { 
     BOOL tmp = [run_loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]]; 
    } 

    return shit->_wasYes; 
} 

और बटन क्लिक से निपटने के लिए अंत में प्रतिनिधि विधि और रोक runloop प्रसंस्करण:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 
    _wasYes = (buttonIndex == 0); 
    _isCanceled = YES; 
} 

यह काम करता है लेकिन याद रखें: आपको इसे इस तरह से नहीं करना चाहिए :- डी सुंदर कृपया शैली और सामान के बारे में बहस न करें, यह सबूत के लिए केवल 5 मिनट का त्वरित हैक किया जा सकता है! यह एआरसी (नया -> autorelease) के बिना काम करना चाहिए, लेकिन यदि मैं गलत हूं तो आप इसे संभालने के बारे में जानते हैं;)

अस्वीकरण: इस स्निपेट के उपयोग से आपके संभावित नुकसान के लिए मैं ज़िम्मेदार नहीं हूं आवेदन या उपकरण। धन्यवाद।

5

यह इसे अवरुद्ध नहीं करता है, लेकिन मैंने ब्लॉक स्टाइल सिंटैक्स जोड़ने के लिए एक सबक्लास लिखा है जो बटन को क्लाइंट करने के लिए बटन को आसान बनाने में आसान बनाता है और यदि आपके पास एकाधिक विवरण हैं तो बयानों का पूरा समूह एक वर्ग में UIAlertViews।

#import <UIKit/UIKit.h> 

@interface UIAlertViewBlock : UIAlertView<UIAlertViewDelegate> 
- (id) initWithTitle:(NSString *)title message:(NSString *)message block: (void (^)(NSInteger buttonIndex))block 
    cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_AVAILABLE(10_6, 4_0); 
@end 


#import "UIAlertViewBlock.h" 

@interface UIAlertViewBlock() 
{ 
    void (^_block)(NSInteger); 
} 
@end 

@implementation UIAlertViewBlock 

- (id) initWithTitle:(NSString *)title message:(NSString *)message block: (void (^)(NSInteger buttonIndex))block 
cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_AVAILABLE(10_6, 4_0) 
{ 
    if (self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles, nil]) 
    { 
     _block = block; 
    } 
    return self; 
} 

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 
{ 
    _block(buttonIndex); 
} 

@end 

फिर इसे कॉल करने के लिए यहां कुछ उदाहरण कोड है। दूसरा ठंडा हिस्सा यह है कि चूंकि एक ब्लॉक स्थानीय चर के चारों ओर बंद हो जाता है, इसलिए जब मैं UIAlertView दिखाता हूं तब तक मौजूद सभी राज्यों तक पहुंच हो सकती है। पारंपरिक प्रतिनिधि दृष्टिकोण का उपयोग करके, आपको प्रतिनिधि स्तर पर बटनक्लिडएटइंडेक्स को कॉल में पहुंचने के लिए सभी अस्थायी स्थिति को कक्षा स्तर चर में स्टोर करना होगा। यह बहुत साफ है।

{ 
    NSString *value = @"some random value"; 
    UIAlertViewBlock *b = [[UIAlertViewBlock alloc] initWithTitle:@"Title" message:@"Message" block:^(NSInteger buttonIndex) 
     { 
      if (buttonIndex == 0) 
       NSLog(@"%@", [value stringByAppendingString: @" Cancel pressed"]); 
      else if (buttonIndex == 1) 
       NSLog(@"Other pressed"); 
      else 
       NSLog(@"Something else pressed"); 
     } 
     cancelButtonTitle:@"Cancel" otherButtonTitles:@"Other", nil]; 

    [b show]; 
} 
+1

धन्यवाद @ जोसेफ। यह पूरी तरह से सतर्क दृश्य और पागलपन पागल है। इस समाधान के लिए धन्यवाद। – Eddy

1

यूआईएल से ब्लॉक के साथ UIAlertView का उपयोग करें और इसमें सेमफोर जोड़ें। एक वैश्विक सेमाफोर

dispatch_semaphore_t generateNotificationsSemaphore; 

घोषित करने और ब्लॉक हैंडलर

[alert showWithHandler:^(UIAlertView *alertView, NSInteger buttonIndex) { 
    if (buttonIndex == [alertView cancelButtonIndex]) { 

    } else { 

    } 

    dispatch_semaphore_signal(generateNotificationsSemaphore); 
}]; 

में सेमाफोर संकेत showWithHandler सेमाफोर

while (dispatch_semaphore_wait(generateNotificationsSemaphore, DISPATCH_TIME_NOW)) { 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:20]]; 

} 

आपका वास्तविक टाइमआउट मान का उपयोग कर एक प्रतीक्षा पाश जोड़ने कॉल करने के बाद हो सकता है अपनी जरूरतों के आधार पर अलग रहें।

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