uncaught exception 'NSGenericException: приложение представило UIAlertController стиля UIAlertControllerStyleActionSheet

Я работаю над приложением, которое я запускаю на iPhone, работает хорошо, но когда я пытаюсь запустить на iPad, происходит сбой

Вот мой код:

- (void)parseCountryStates:(NSDictionary *)json
{    
    countryPickerView.hidden = TRUE;
    NSDictionary *listing = [json objectForKey:@"country"];
    countryArray = [listing allValues];
    countryIDArray = [listing allKeys];

    [countryPickerView reloadAllComponents];
    alertController = [UIAlertController
                       alertControllerWithTitle:@"Select Service Type"
                       message:nil
                       preferredStyle:UIAlertControllerStyleActionSheet];
    int count = (int)[countryPickerView numberOfRowsInComponent:0];

    for (int i = 0; i < count; i++)
    {
        UIAlertAction* button = [UIAlertAction
                                 actionWithTitle:[[countryPickerView delegate] pickerView:countryPickerView titleForRow:i forComponent:0]
                                 style:UIAlertActionStyleDefault
                                 handler:^(UIAlertAction * action)
                                 {
                                     countryField.text = [action title];
                                     countryStr = countryField.text;
                                     if ([countryArray containsObject:countryStr]) {
                                         countryidStr = [countryIDArray objectAtIndex:[countryArray indexOfObject:countryStr]];
                                         NSLog(@"CountryidStr %@",countryidStr);
                                         [self getState];
                                     }
                                 }];
        [alertController addAction:button];

    }

    UIAlertAction* cancel = [UIAlertAction
                             actionWithTitle:@"Cancel"
                             style:UIAlertActionStyleCancel
                             handler:^(UIAlertAction * action)
                             {
                                 //  UIAlertController will automatically dismiss the view
                             }];
    [alertController addAction:cancel];
    [self presentViewController:alertController animated:true completion:nil];
}

Я делюсь журналом сбоев

*** Завершение работы приложения из-за неперехваченного исключения «NSGenericException», причина: «Ваше приложение представило UIAlertController () стиля UIAlertControllerStyleActionSheet. ModalPresentationStyle UIAlertController с этим стилем - UIModalPresentationPopover. Вы должны предоставить информацию о местоположении для этого всплывающего окна через popoverPresentationController контроллера предупреждений. Вы должны предоставить либо sourceView и sourceRect, либо barButtonItem. Если эта информация неизвестна, когда вы представляете контроллер предупреждений, вы можете предоставить ее в методе UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation.


person Abhinandan Pratap    schedule 21.09.2018    source источник
comment
ipad не поддерживает Actionsheet. Вы должны показать его как всплывающий контроллер. Слишком много похожих вопросов. Найдите его.   -  person Prashant Tukadiya    schedule 21.09.2018
comment
Возможный дубликат ActionSheet не работает на iPad   -  person Prashant Tukadiya    schedule 21.09.2018
comment
вместо того, чтобы пометить его как дубликат, пожалуйста, ответьте на него   -  person Abhinandan Pratap    schedule 21.09.2018
comment
Вместо того, чтобы спрашивать, пожалуйста, поищите его   -  person Prashant Tukadiya    schedule 21.09.2018


Ответы (3)


Добавьте исходное представление и исходный прямоугольник в свой alertController.

[[alertController popoverPresentationController] setSourceView:self.view];
[[alertController popoverPresentationController] setSourceRect:CGRectMake(0,0,1,1)];
[[alertController popoverPresentationController] setPermittedArrowDirections:UIPopoverArrowDirectionUp];

[self presentViewController:alertController animated:true completion:nil];
person Ankit Jayaswal    schedule 21.09.2018

фактически на ipad alertcontrollers не разрешены, вместо этого вы можете использовать всплывающие окна для отображения вида предупреждения

Программно

UIViewController *newViewCont = [[UIViewController  alloc] init];
newViewCont.view = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 180, 180)];
newViewCont.modalPresentationStyle = UIModalPresentationPopover;

[self presentViewController:newViewCont animated:YES completion:nil];

UIPopoverPresentationController *pop = [newViewCont popoverPresentationController];
pop.permittedArrowDirections = UIPopoverArrowDirectionAny;

[pop setSourceView:myButton];
[pop setSourceRect:myButton.bounds];

Использование раскадровки

// grab the view controller we want to show
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"Pop"];

// present the controller
// on iPad, this will be a Popover
// on iPhone, this will be an action sheet
controller.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:controller animated:YES completion:nil];

// configure the Popover presentation controller
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popController.delegate = self;

// in case we don't have a bar button as reference
popController.sourceView = self.view;
popController.sourceRect = CGRectMake(30, 50, 10, 10);

закрыть всплывающее окно

[self dismissViewControllerAnimated:YES completion:nil];

Существует новый протокол под названием UIPopoverPresentationControllerDelegate, который вызывается при увольнении и изменении должности из-за ротации или изменений интерфейса. Мы даже можем предотвратить увольнение Поповера, если захотим. Вот три метода, которые мы можем реализовать:

- (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {

// called when a Popover is dismissed
}

- (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController {

// return YES if the Popover should be dismissed
// return NO if the Popover should not be dismissed
return YES;
}

- (void)popoverPresentationController:(UIPopoverPresentationController *)popoverPresentationController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing  _Nonnull *)view {

// called when the Popover changes position
}

Не забудьте соответствовать протоколу и назначить делегата вашему классу реагирования.

person Devil Decoder    schedule 21.09.2018

UIPopovers не разрешены на iPad, но есть способ сделать это, как указано в других ответах. Вот версия Swift 5.x.

let ac = UIAlertController(title: "Some title goes here", message: nil, preferredStyle: .actionSheet)

ac.addAction(UIAlertAction(title: "Some button name", style: .default) {
        [unowned self] _ in
        // stuff to do goes here
        self.doSomething()
    })

// iPad specific code
ac.popoverPresentationController?.sourceView = self.view
let xOrigin = nil // Replace this with one of the lines at the end
let popoverRect = CGRect(x: xOrigin, y: 0, width: 1, height: 1)
ac.popoverPresentationController?.sourceRect = popoverRect
ac.popoverPresentationController?.permittedArrowDirections = .up

present(ac, animated: true)

Замена строки let xOrigin = nil на одну из приведенных ниже будет определять, где будет отображаться всплывающее окно под панелью навигации. Вы также можете изменить x и y на правильные значения в границах или кадре другого элемента, если у вас есть элемент управления, который находится под панелью навигации на iPad.

Верхний левый

 let xOrigin = 0

Верхняя середина

let xOrigin = self.view.bounds.width / 2

В правом верхнем углу

let xOrigin = self.view.bounds.width

Надеюсь это поможет.

person Alex Zavatone    schedule 05.11.2020