Добавить UIDatePicker в UIAlertView


Я пытаюсь добавить средство выбора даты в представление предупреждений. Я могу добавить анимацию на экран, основываясь на нажатии кнопки, и я вижу черный ящик, но не выбор даты.

Вот что у меня есть до сих пор....
- (IBAction)showDatePicker {
    CGRect frame = CGRectMake(200, self.view.frame.size.height, self.view.frame.size.width, 0);  //CGRectMake(225, 145, 260, 125);
    UIPickerView *datePicker = [[UIPickerView alloc] initWithFrame:frame];
    UIAlertView *showDateAlert = [[UIAlertView alloc]
                                  initWithTitle:@"Enter the Code Date"
                                  message:@"Sample message"
                                  delegate:self
                                  cancelButtonTitle:@"Cancel"
                                  otherButtonTitles:@"Update", nil];

    [self.view addSubview:datePicker];
    [UIView beginAnimations:@"slideIn" context:nil];
    [datePicker setCenter:CGPointMake(datePicker.frame.origin.x, self.view.frame.size.height - datePicker.frame.size.height/2)];
    [UIView commitAnimations];
}

Я нашел пример, который, кажется, работает, но я не вижу никаких диалоговых окон или кнопок в моем окне оповещения, только сам выбор даты. Я что-то упустил?

- (IBAction)showDatePicker {
    CGRect frame = CGRectMake(225, self.view.frame.size.height, self.view.frame.size.width, 125);
    UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:frame];
    datePicker = [[UIDatePicker alloc] init];
    datePicker.datePickerMode = UIDatePickerModeDate;

    [datePicker setDate:[NSDate date]];

    UIAlertView *alert;
    alert = [[UIAlertView alloc]
             initWithTitle:@"Enter the Code Date"
             message:@"Sample message"
             delegate:self
             cancelButtonTitle:@"Cancel"
             otherButtonTitles:@"Update", nil];
    alert.delegate = self;
    [alert addSubview:datePicker];
    [alert show];
}
5 6

5 ответов:

Я согласен с комментаторами, которые говорят, что это не способ достичь этого, по нескольким причинам. Во-первых, никому не нравится, когда постоянно появляются предупреждающие виды. Во-вторых, и это не применимо к вашей ситуации, это может в конечном итоге привести к отклонению приложения. Apple изменила формулировку в ссылке на класс UIAlertView, ссылаясь на свою иерархию представлений как приватную; и мы все знаем, как apple относится к тому, что вы путаетесь в том, что они считают приватным.

От Ссылка на класс UIAlertView:

Класс UIAlertView предназначен для использования как есть и не используется поддержка подклассов. Иерархия представлений для этого класса является частной и не должно быть изменено.

Но поскольку вы говорите, что это частное приложение,вот оно. A UIAlertView - это просто подкласс UIView. Таким образом, все правила фреймов и границ все еще применимы. Вот базовый пример того, как настроить рамку средства выбора и границы предупреждения, чтобы сжать дату сборщик.
// Create alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello" message:@"message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
// Show alert (required for sizes to be available)
[alert show];
// Create date picker (could / should be an ivar)
UIDatePicker *picker = [[UIDatePicker alloc] initWithFrame:CGRectMake(10, alert.bounds.size.height, 320, 216)];
// Add picker to alert
[alert addSubview:picker];
// Adjust the alerts bounds
alert.bounds = CGRectMake(0, 0, 320 + 20, alert.bounds.size.height + 216 + 20);

EDIT

Как было отмечено как комментариями, так и новыми ответами на многие из вопросов " как я могу добавить некоторое представление к UIAlertView", Этот метод больше не работает в iOS7 и выше. Это действительно следует воспринимать как доказательство того, что это в корне плохая идея.

Также обратите внимание на использование setValue:forKey: в распространенном "решении" проблемы невозможности изменить иерархию частных представлений Apple. setValue:forKey: является одним из тех методов, который рисует интерес частных сканеров API. Перейдите к поиску accessoryView в документации UIAlertView и заголовках. Этого нет в документах. Единственный связанный элемент в заголовках-это Ивар с именем _accessoryView, который помечен как @private.

Опять же для внутреннего или частного приложения я полагаю, что это нормально, просто хорошо.

Вам не понравится этот ответ, но я предлагаю: не делайте этого! UIAlertView не предназначен для того, чтобы вы добавляли свои собственные подвиды; примеры, которые вы находите у людей, делающих это, являются примерами неправильного поведения. Создайте свой собственный вид, содержащий палитру, текст, кнопки и т. д. то, что вы хотите, и преподносите это как-то. Например, вы можете представить его модально через свой собственный контроллер вида, например, с помощью presentModalViewController:animated: или presentViewController:animated:completion:. Если вы находитесь на iPad, вы можете использовать popover (он может быть модальным, если это важный).

Это то, что сработало для меня (используя iOS7). Назовем это раньше [alertView show]:

[alertView setValue:customContentView forKey:@"accessoryView"];

Пример:

UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"TEST" message:@"subview" delegate:nil cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil];
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
v.backgroundColor = [UIColor yellowColor];
[av setValue:v forKey:@"accessoryView"];
[av show];

Источник: iOS 7 UIDatePicker в настройке UIAlertView

Это работает для меня в ios7 и выше.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Select Date" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
UIDatePicker *picker = [[UIDatePicker alloc] initWithFrame:CGRectMake(10, alert.bounds.size.height, 320, 216)];
[alert addSubview:picker];
alert.bounds = CGRectMake(0, 0, 320 + 20, alert.bounds.size.height + 216 + 20);
[alert setValue:picker forKey:@"accessoryView"];
[alert show];

В Swift:

        let myDatePicker: UIDatePicker = UIDatePicker()
        // setting properties of the datePicker
        myDatePicker.timeZone = NSTimeZone.localTimeZone()
        myDatePicker.frame = CGRectMake(0, 15, 270, 200)

        let alertController = UIAlertController(title: "\n\n\n\n\n\n\n\n", message: nil, preferredStyle: UIAlertControllerStyle.Alert)
        alertController.view.addSubview(myDatePicker)
        let somethingAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil)
        let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
        alertController.addAction(somethingAction)
        alertController.addAction(cancelAction)
        self.presentViewController(alertController, animated: true, completion:{})