Ответ 1
UIPickerView наследует UIView, поэтому вы можете просто переключить его "скрытое" свойство:
if (pickerView) pickerView.hidden = !pickerView.hidden;
У меня есть событие touchsEnded, которое проверяет, когда нажата UITextField. То, что я хотел бы сделать, это скрыть/показать UIPickerView. Как это можно сделать?
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if (CGRectContainsPoint([self.textField frame], [touch locationInView:self.view]))
{
NSString * error = @"Touched the TextField";
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Selection!" message:error delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
//Want to show or hide UIPickerView
}
}
У меня уже есть выделенный UIPickerView, когда происходит прикосновение
@interface ThirdViewController : UIViewController <UITextFieldDelegate,UIPickerViewDelegate> {
IBOutlet UIPickerView *pickerView;
}
UIPickerView наследует UIView, поэтому вы можете просто переключить его "скрытое" свойство:
if (pickerView) pickerView.hidden = !pickerView.hidden;
Переключение "скрытого" свойства будет делать трюк, но также даст очень резкое раскрытие.
Один из способов избежать этого - заставить сборщик скользить снизу экрана, вставив его в таблицу UIActionSheet.
Вот пример:
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
CGRect pickerFrame = CGRectMake(0, 0, 0, 0);
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
[sheet addSubview:pickerView];
[pickerView release];
[sheet showInView:view];
[sheet setBounds:CGRectMake(0, 0, 320, 415)];
self.actionSheet = sheet; // assuming you have setup a property to hold the action sheet
[sheet release];
Когда вы закончите с сборщиком, отпустите его:
[self.actionSheet dismissWithClickedButtonIndex:0 animated:YES];
Этот подход также можно использовать для включения кнопок в панели над сборщиком ( "Готово", "Предыдущий", "Следующий" и т.д.) - есть хорошее объяснение, как это сделать .
Поскольку я видел комментарий об этих решениях, не работающих на iOS 7, я предполагаю, что этот поток по-прежнему релевантен и выполняется поиск.
Лучший способ, который я нашел для этого, - подключить UIPickerView к (скрытому) UITextField в качестве представления ввода, например:
_myPicker = [[UIPickerView alloc] init];
_myPicker.delegate = self;
_myPicker.showsSelectionIndicator = YES;
myTextField.inputView = _myPicker;
При желании вы всегда можете скрыть текстовое поле. Затем вы можете показать/скрыть UIPickerView, активировав текстовое поле как первый ответчик, например:
[myTextField becomeFirstResponder];
[myTextField resignFirstResponder];
Я подтвердил, что это работает на iOS 7, и у меня он работал еще в IOS 5.
Я использую фиктивный UITextField
для отображения/скрытия UIPickerView
Сначала добавьте UITextField как @property
на ваш UIViewController
. Необязательно добавьте UIPickerView
, а также
@property (strong, nonatomic) UITextField *dummyTextField;
Во-вторых, назначьте UIPickerView
как inputView
для UITextField
. Назначьте себя как dataSource
и delegate
для UIPickerView
. UITextField
необходимо добавить в качестве подзаголовка на UIViewController
view
.
- (void)viewDidLoad {
[super viewDidLoad];
UIPickerView *picker = [[UIPickerView alloc] init];
[picker setDataSource:self];
[picker setDelegate:self];
self.dummyTextField = [UITextField new];
self.dummyTextField.inputView = picker;
[self.dummyTextField setHidden:YES];
[self.view addSubview:self.dummyTextField];
}
Наконец, добавьте механизм для отображения и скрытия UIPickerView
. Поскольку я использую манекен UITextField
, я решил добавить UIBarButtonItem
с именем "Фильтр" со следующим IBAction
:
- (IBAction)tappedFilterButton:(UIBarButtonItem *)sender {
if (self.dummyTextField.isFirstResponder) {
[self.dummyTextField resignFirstResponder];
}
else {
[self.dummyTextField becomeFirstResponder];
}
}
Итак, я использовал множество ссылок, пытаясь понять это, а затем моя лучшая ссылка (верьте или нет), была из документов apple по ссылке UIView Class.
Я построил мини-представление ( "_pickerView" поверх моего основного представления, содержавшего UIToolBar, UIToolButton (с IBAction "closePicker" ) и UIPicker.
*** учтите, что работает только для iOS 4.0 и выше
код закрытия и отображения UIView ( "_pickerView" ):
-(IBAction)closePicker:(id)sender
{
[UIView animateWithDuration:0.3 animations:^{
_pickerView.frame = CGRectMake(_pickerView.frame.origin.x,
460, //Displays the view off the screen
_pickerView.frame.size.width,
_pickerView.frame.size.height);
}];
}
-(IBAction)showPicker:(id)sender
{
[UIView animateWithDuration:0.3 animations:^{
_pickerView.frame = CGRectMake(_pickerView.frame.origin.x,
107, //Displays the view a little past the
//center ling of the screen
_pickerView.frame.size.width,
_pickerView.frame.size.height);
}];
}
И для вашего видаDidLoad просто вызовите "closePicker", чтобы иметь скрытый вид при загрузке
Вы можете использовать ActionSheetPicker-3.0
Похоже на UIPickerView внутри UIActionSheet
, а также для iOS 6-7-8.
В приложении на основе scrollView отображение и скрытие UIPickerView может быть сложной проблемой, так как относительно трудно привязать ее к нижней части видимого прямоугольника экрана. Вы можете сделать это легко с помощью следующего кода.
let alertController = UIAlertController(title: title, message: "\n\n\n\n\n\n\n\n\n\n", preferredStyle: .ActionSheet)
alertController.view.addSubview(pickerView)
alertController.addAction(UIAlertAction(title: "OK", style: .Cancel) { action in
})
self.presentViewController(alertController, animated: true, completion: nil)
Подводя итог, вы создаете UIAlertController с пустым сообщением. Чтобы заставить alertController иметь размер вашего pickerView, вы даете сообщение необходимое количество разрывов строк. И, наконец, вы добавляете свой pickerView в качестве подзадачи alertController.view
Затем вы выполняете выбранные строки pickerView с помощью методов UIPickerViewDelegate.
Я везде искал чистый способ скрыть и показать (переключить) UIPickerView с помощью одного элемента кнопки и найти только фрагменты. Для тех, кто хочет сделать то же самое, здесь мой рабочий результат через базовый условный оператор.
ViewController.m
- (IBAction)animatePicker {
if ([self.userSelection.title isEqualToString: (NSString *)@"Select"]) {
_userPicker.hidden = NO;
UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
float pvHeight = pickerView.frame.size.height;
float y = [[UIScreen mainScreen] bounds].size.height - (pvHeight); // the root view of view controller
[UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.userPicker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
} completion:nil];
} else if ([self.userSelection.title isEqualToString: (NSString *)@"Done"]) {
UIPickerView *pickerView = [[UIPickerView alloc] init]; // default frame is set
float pvHeight = pickerView.frame.size.height;
float y = [[UIScreen mainScreen] bounds].size.height - (pvHeight * -2); // the root view of view controller
[UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.userPicker.frame = CGRectMake(0 , y, pickerView.frame.size.width, pvHeight);
} completion:nil];
self.userSelection.title = @"Select";
}
}
Итак, вот что происходит здесь: у меня есть элемент кнопки под названием "userSelection" с заголовком "Выбрать" и скрытый UIPickerView, называемый "userPicker" (чтобы скрыть, просто скопируйте бит о "_userPicker.hidden", вставьте его в свое объявление сборщика и установите для boolean значение YES). Элемент кнопки подключен к вышеуказанному действию. При загрузке (т.е. Когда заголовок кнопки говорит "Выбрать" ), он отображает сборщик и оживляет его. Вы можете использовать опции animateWithDuration и delay для управления этой функцией, но эти настройки мне кажутся довольно естественными.
Затем у меня есть этот метод, изменивший название кнопки на "Готово", когда что-то было выбрано. Я уверен, что есть более чистый способ сделать этот бит, но метод переключения дает мне некоторую свободу, если я захочу внести изменения в пользовательский интерфейс позже.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(@"Selected Row %ld", (long)row);
switch(row)
{
case 0:
self.userSelection.title = @"Done";
break;
case 1:
self.userSelection.title = @"Done";
break;
case 2:
self.userSelection.title = @"Done";
break;
case 3:
self.userSelection.title = @"Done";
break;
case 4:
self.userSelection.title = @"Done";
break;
case 5:
self.userSelection.title = @"Done";
break;
}
}
Наконец, действие закрывается с "else if", которое говорит, когда кнопка говорит "Готово", скрыть сборщик с обратной анимацией (тот же код, но с "pvHeight * -2" ), а затем устанавливает заголовок кнопки назад к "Выбрать" , который служит для завершения цикла всего действия.
Вероятно, более простой способ для профессионалов, но для людей, которые новичок в этом, как и я, это наиболее логично. Плюс это работает, так что всегда бонус!
Ниже приведен пример кода для скрытия и отображения UIPickerView
с анимацией: -
//Для отображения
-(void)showPickerView{
self.pickerSheet = [UIAlertController alertControllerWithTitle:@"Select font" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
self.pickerView = [[UIPickerView alloc]initWithFrame:CGRectZero];
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
self.pickerView.showsSelectionIndicator = YES;
[self.pickerView selectRow:1 inComponent:0 animated:YES];
[self.pickerSheet.view addSubview:self.pickerView];
self.pickerView.translatesAutoresizingMaskIntoConstraints = NO;
UIView *view = self.pickerView;
[self.pickerSheet.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|[view]|"
options:0l
metrics:nil
views:NSDictionaryOfVariableBindings(view)]];
[self.pickerSheet.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|[view]|"
options:0l
metrics:nil
views:NSDictionaryOfVariableBindings(view)]];
[self presentViewController:self.pickerSheet animated:YES completion:^{
}];
}
//Для скрытия
-(void)hidePickerView{
[self.pickerSheet dismissViewControllerAnimated:YES completion:^{
}];
}