ios - यूआईएक्शनशीट को बदलने के लिए UIAlertController का उपयोग कैसे करें?




objective-c uiactionsheet (4)

मैं एक पुराने iOS प्रोजेक्ट को बनाए रख रहा हूं जो SDK 6.0 पर आधारित है।

इस परियोजना पर एक विधि कहा जाता है

-(void) showComboBox:(UIView*)view:withOptions:(NSDictionary*)options

एक कॉम्बो बॉक्स दिखाने के लिए उपयोग किया जाता है। लक्ष्य को प्राप्त करने के लिए, इसने UIActionSheet का उपयोग किया, जो iOS8 पर अपग्रेड किया गया है।

मेरा समाधान इस तरह है:

        if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8) {
        UIAlertController* alertController = [UIAlertController 
           alertControllerWithTitle:@"title" 
           message:@"message" 
           preferredStyle:UIAlertControllerStyleActionSheet];

        UIAlertAction* item = [UIAlertAction actionWithTitle:@"item" 
           style:UIAlertActionStyleDefault 
           handler:^(UIAlertAction *action) {
            //do something here 
            //inform the selection to the WebView 
            ...
            [alertController dismissViewControllerAnimated:YES completion:nil];
        }];

        UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            [alertController dismissViewControllerAnimated:YES completion:nil];
        }];

        [alertController addAction:item];
        [alertController addAction:cancelAction];
        //I am not sure whether it's the right way
        if ([view.nextResponder isKindOfClass:UIViewController.class]) {
            UIViewController* vc = (UIViewController*)view.nextResponder;
            [vc presentViewController:alertController animated:YES completion:nil];
        }

क्या यह एक उचित समाधान है?

यह वही है जिसके बारे में मुझे ज्यादातर चिंता है : UIAlertController को एक UIViewController में जोड़ने की आवश्यकता है लेकिन मैं केवल UIView का पॉइंटर प्राप्त कर सकता हूं, इसलिए मैंने view.nextResponder का उपयोग किया जो मुझे चाहिए, लेकिन यह एक अच्छा तरीका है?


आप इसके बजाय view.window.rootViewController उपयोग कर सकते हैं। यदि आप प्रस्तुतकर्ता के बारे में परवाह नहीं करते हैं तो यह ठीक है।


मैंने UIAlertViewController का उपयोग करके एक्शन शीट दिखाने के लिए निम्नलिखित कोड का उपयोग किया है और यह सही काम करता है।

- (IBAction)buttonClicked:(id)sender {

    UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:@"Action Sheet" message:@"Using the alert controller" preferredStyle:UIAlertControllerStyleActionSheet];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {

        // Cancel button tappped.
        [self dismissViewControllerAnimated:YES completion:^{
        }];
    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) {

        // Distructive button tapped.
        [self dismissViewControllerAnimated:YES completion:^{
        }];
    }]];

    [actionSheet addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {

        // OK button tapped.

        [self dismissViewControllerAnimated:YES completion:^{
        }];
    }]];

    // Present action sheet.
    [self presentViewController:actionSheet animated:YES completion:nil];
}

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

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

और ऊपर कोड में अंतिम पंक्ति की तरह होगा

[self.viewController presentViewController:actionSheet animated:YES completion:nil];

self.viewController एक वैश्विक चर है जो आपको वास्तव में यह दृश्य प्राप्त करने से पहले सेट किया जाएगा।

क्योंकि जिस दृष्टिकोण को आप अभी देख रहे हैं view.nextResponder का उपयोग कर view.nextResponder । मुझे डर है कि यह काम न करे।


स्विफ्ट अपडेट -

    let actionSheet = UIAlertController.init(title: "Please choose a source type", message: nil, preferredStyle: .actionSheet)
    actionSheet.addAction(UIAlertAction.init(title: "Take Photo", style: UIAlertActionStyle.default, handler: { (action) in
        self.openCamera()
    }))
    actionSheet.addAction(UIAlertAction.init(title: "Choose Photo", style: UIAlertActionStyle.default, handler: { (action) in
        self.showPhotoLibrary()
    }))
    actionSheet.addAction(UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (action) in
        // self.dismissViewControllerAnimated(true, completion: nil) is not needed, this is handled automatically,
         //Plus whatever method you define here, gets called,
        //If you tap outside the UIAlertController action buttons area, then also this handler gets called.
    }))
    //Present the controller
    self.present(actionSheet, animated: true, completion: nil)

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

मैं काफी समय से एक समाधान की तलाश में था और यहां बताया गया है कि मैं अपने ऐप में अलर्ट नियंत्रक का उपयोग कैसे करता हूं।

+ (void)alertWithPresenting:(UIViewController *)presenting title:(NSString *)title
                       text:(NSString *)text buttons:(NSArray *)buttons
                    handler:(void (^)(UIAlertAction *action, NSUInteger index))handler
{
        UIAlertController *alert = [UIAlertController
                                    alertControllerWithTitle:title message:text
                                    preferredStyle:UIAlertControllerStyleAlert];
        __weak __typeof(alert) weakAlert = alert;
        for (NSString *title in buttons) {
                UIAlertActionStyle style = UIAlertActionStyleDefault;
                if ([title isEqualToString:[L10n cancelButton]])
                        style = UIAlertActionStyleCancel;
                else if ([title isEqualToString:[L10n deleteButton]])
                        style = UIAlertActionStyleDestructive;
                else if ([title isEqualToString:[L10n archiveButton]])
                        style = UIAlertActionStyleDestructive;

                UIAlertAction *action = [UIAlertAction actionWithTitle:title style:style handler:^(UIAlertAction *action) {
                        if (handler != nil)
                                handler(action, [buttons indexOfObject:action.title]);
                        [weakAlert dismissViewControllerAnimated:YES completion:nil];
                }];
                [alert addAction:action];
        }
        [presenting presentViewController:alert animated:YES completion:nil];
}

यह सब नहीं है। यहाँ एक उदाहरण है कि आप इसे अपने दृश्य नियंत्रक में कैसे उपयोग करते हैं। मेरे मामले में खोज के साथ इसका tableview , इसलिए प्रस्तुत करने वाला नियंत्रक अलग हो सकता है।

- (void) deleteCases:(NSArray *)selectedRows
{
        NSString *text = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.text",
                                                           @"Localizable",  [NSBundle mainBundle],
                                                           @"Deleted cases cannot be restored. Continue with delete?",
                                                           @"Delete alert text");
        NSString *title = NSLocalizedStringWithDefaultValue(@"cases.delete.alert.title",
                                                            @"Localizable",  [NSBundle mainBundle],
                                                            @"Delete cases", @"Detete alert title");
        UIViewController *presenting = self.searchController.active ? self.searchController : self;
        __weak __typeof(presenting) weakPresenting = presenting;
        __weak __typeof(self) weakSelf = self;
        [YourClassName alertWithPresenting:weakPresenting title:title text:text
                                   buttons:@[[L10n deleteButton], [L10n cancelButton]]
                                   handler:^(UIAlertAction *action, NSUInteger index)
        {
                if (action.style == UIAlertActionStyleDestructive) {
                        __typeof(weakSelf) strongSelf = weakSelf;
                        // Perform your actions using @strongSelf
                }
         }];
}




uiactionsheet