UIDatePicker в проблеме с наслоением UIActionSheet

Кто-то разместил этот код в другом вопросе, чтобы поместить UIDatePicker в UIAlertSheet:

UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:@"Date Picker" 
                                                  delegate:self
                                         cancelButtonTitle:@"Cancel"
                                    destructiveButtonTitle:nil
                                         otherButtonTitles:nil];

// Add the picker
UIDatePicker *pickerView = [[UIDatePicker alloc] init];
pickerView.datePickerMode = UIDatePickerModeDate;
[menu addSubview:pickerView];
[menu showInView:self.view];        
[menu setBounds:CGRectMake(0,0,320, 500)];

CGRect pickerRect = pickerView.bounds;
pickerRect.origin.y = -100;
pickerView.bounds = pickerRect;

[pickerView release];
[menu release];

Я изменил его на это:

    UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:nil
                                                      delegate:nil
                                             cancelButtonTitle:@"Done"
                                        destructiveButtonTitle:nil
                                             otherButtonTitles:nil];

    // Add the picker
    UIDatePicker *pickerView = [[UIDatePicker alloc] init];
    pickerView.datePickerMode = UIDatePickerModeCountDownTimer;
    [menu addSubview:pickerView];
    [menu showInView:self.navigationController.tabBarController.view];        
    [menu setBounds:CGRectMake(0,0,320, 516)];
    [pickerView setFrame:CGRectMake(0, 85, 320, 216)];

Это приводит к правильному расположению листа предупреждений (игнорируйте nil делегата, это просто для отображения). Проблема здесь:

alt text
(источник: hosting-wizards.com )

Как видите, над минутным скроллером есть проблема с наслоением. Я не подтвердил, происходит ли это на устройстве. Любые идеи относительно того, почему это происходит?

Другой вопрос: почему селектор setBounds на UIActionSheet имеет размер Y, установленный на такое высокое значение для правильного отображения? Установка размера Y на 480 должна создать полноэкранный режим, не так ли? Установка этого значения на ноль делает его почти невидимым.

ПРИМЕЧАНИЕ. Код, вставленный выше, не размещает UIDatePicker в том же месте, что и на картинке, но проблема с наслоением возникает независимо от того, где находится UIDatePicker. Проблема со слоями только сверху, а не снизу.


person jmeado3    schedule 28.07.2009    source источник


Ответы (5)


Вы избежите проблемы с отображением и получите гораздо более привлекательный результат, если просто поместите UIDatePicker в новое представление и самостоятельно реализуете поведение слайда вверх снизу. Это не так сложно.

  1. Создайте UIView, содержащий средство выбора даты и панель инструментов с кнопкой «Готово». (В коде или с помощью Interface Builder не имеет значения.)
  2. Добавьте всплывающее окно в качестве подпредставления основного представления.
  3. Установите рамку всплывающего окна так, чтобы она находилась за пределами нижней части экрана: frame.origin.y = CGRectGetMaxY(mainView.bounds)
  4. Звоните [UIView beginAnimations:nil context:nil]
  5. Установите рамку туда, где она должна быть: frame.origin.y -= CGRectGetHeight(popupView.bounds)
  6. Звоните [UIView commitAnimations]

(Обратите внимание, что настройка фрейма — это псевдокод.)

Вот и все. Сделайте это в обратном порядке, когда вам нужно закрыть вид. Я думаю, это того стоит; вставка средства выбора даты в UIActionSheet выглядит невероятно безвкусно.

person benzado    schedule 08.01.2010

Используя описанные выше шаги benzado, примерно так будет выглядеть ваш код, если вы используете UIView вместо ActionSheet:

int height = 255;

//create new view
UIView * newView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, 320, height)];
newView.backgroundColor = [UIColor colorWithWhite:1 alpha:1];

//add toolbar
UIToolbar * toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, 320, 40)];
toolbar.barStyle = UIBarStyleBlack;

//add button
UIBarButtonItem *infoButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:nil];
toolbar.items = [NSArray arrayWithObjects:infoButtonItem, nil];

//add date picker
UIDatePicker *datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.hidden = NO;
datePicker.date = [NSDate date];
datePicker.frame = CGRectMake(0, 40, 320, 250);
[datePicker addTarget:self action:nil/*@selector(changeDateInLabel:)*/ forControlEvents:UIControlEventValueChanged];
[newView addSubview:datePicker];

//add popup view
[newView addSubview:toolbar];
[self.view addSubview:newView];

//animate it onto the screen
CGRect temp = newView.frame;
temp.origin.y = CGRectGetMaxY(self.view.bounds);
newView.frame = temp;
[UIView beginAnimations:nil context:nil];
temp.origin.y -= height;
newView.frame = temp;
[UIView commitAnimations];

Я согласен, это выглядит намного лучше, чем использование ActionSheets, которые предназначены для отображения кнопок, а не средств выбора. Вам все еще нужно добавить свои собственные обработчики действий на кнопку «Готово» и когда пользователь меняет средство выбора, но это должно помочь вам начать работу.

person Jonesy    schedule 12.09.2011

Вам действительно нужно поместить свой сборщик на UIActionSheet? Почему бы вам не использовать свойство inputView из класса UIResponder? Он автоматически показывает UIDatePicker (или любое другое представление), когда ваш элемент управления (например, UITextField) становится первым ответчиком. Пример использования inputView с исходным кодом можно найти здесь: Работа со сборщиками.

person lechec    schedule 01.10.2010
comment
inputView доступен в iOS 4.0 и выше. Не могу использовать его, если вы хотите поддерживать 3.1 - person o_o; 04.11.2010

попробуй это

[menu sendSubviewToBack: pickerView];

а также переместите средство выбора на 10 пикселей вниз, как вы видите на скриншоте, оно не выровнено по низу, может быть

[pickerView setFrame:CGRectMake(0, 100, 320, 216)];
person yasirmturk    schedule 06.01.2011

Эта ветка может оказаться полезной для альтернативного подхода: http://discussions.apple.com/message.jspa?messageID=7923095

person Simon Woodside    schedule 06.01.2010