UIPickerView — убрать кривизну и добавить текст

Я пытаюсь создать UIPicker, где я могу выбирать минуты и секунды. Вот код:

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if(component == 0)
        return 24;

    return 60;
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
    return 30;
}

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    [paragraphStyle setAlignment:NSTextAlignmentCenter];
    [paragraphStyle setTailIndent:20];

    NSString *value = [NSString stringWithFormat:@"%d", row];

    return [[NSAttributedString alloc] initWithString:value
                                           attributes:@{NSParagraphStyleAttributeName:paragraphStyle}];
}

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
{
    return 160;
}

Как мне избавиться от надоедливой кривизны и просто сделать вертикальные столбцы?

Кроме того, как я могу добавить «мин» и «сек» в строку выбора?

сборщик


person soleil    schedule 05.09.2014    source источник
comment
Вы можете использовать UIDatePicker и избавиться от необходимости кодировать это самостоятельно.   -  person ZeMoon    schedule 05.09.2014
comment
Насколько я знаю, вы не можете делать минуты и секунды с UIDatePicker.   -  person soleil    schedule 05.09.2014
comment
Я думаю, вам придется создать свой собственный, если вы не хотите кривизны. Должно быть легко просто использовать 2 узких представления таблицы. Вам нужно будет только добавить код в методы делегата представления прокрутки, чтобы значение автоматически выбиралось при остановке прокрутки.   -  person rdelmar    schedule 05.09.2014


Ответы (3)


Я обнаружил, что изменение ширины компонентов влияет на степень смещения или кривизны, которую UIPickerView применяет к выбранной строке. В своем делегате реализуйте pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat и попробуйте вернуть значения, которые достаточно велики, чтобы показать информацию, которую вы хотите отобразить, скажем, 40 или 60 всего за два символа текста для простого числа. Чтобы изменить расстояние между столбцами/компонентами, вы можете добавить дополнительные компоненты, которые возвращают 0 для количества строк, и использовать ширину этих пустых компонентов для перемещения и настройки размещения компонентов, в которых вы отображаете данные.

person Jim    schedule 28.03.2018

Поскольку вы делаете это за 24 минуты и 60 секунд, я бы подделал это с помощью 24-часового выбора даты. ИМО

Как мне избавиться от надоедливой кривизны и просто сделать вертикальные столбцы?

Вы не знаете. В противном случае реализуйте свои собственные, используя 2 табличных представления или что-то в этом роде.

Кроме того, как я могу добавить «мин» и «сек» в строку выбора?

NSString *value;

if(component == 0) value = [NSString stringWithFormat:@"%d min", row];
else  value = [NSString stringWithFormat:@"%d sec", row];
person marko    schedule 05.09.2014
comment
Этот код добавляет min и sec ко ВСЕМ строкам. Я просто хочу, чтобы в средней выбранной строке отображался текст min и sec. - person soleil; 05.09.2014
comment
И что касается подделки с помощью 24-часового средства выбора даты, это кажется невозможным, поскольку мне нужно отображать минуты и секунды, а не часы и минуты. - person soleil; 05.09.2014
comment
24-часовой выбор даты просто показывает числа (проверяет приложение будильника, убедитесь, что вы установили устройство на 24 часа). и если вы хотите одну минуту и ​​​​секунду, сделайте ее 4 компонентами для сборщика и верните минуты и секунды для компонентов 1 и 3 соответственно и верните 1 строку для них обоих. - person marko; 05.09.2014

Как уже говорили другие, существующий API не может этого сделать. Если вы хотите сделать это, вам придется написать свой собственный код, чтобы сделать это. В прошлом я создал средство выбора значений по горизонтали, и это раздражало, но довольно прямолинейно. Для этого я использовал UILabel, изображение и UIScrollView.

Сначала настройте пользовательский интерфейс

  1. Возьмите метку и приклейте ее в виде прокрутки. Заполните метки нужными вам значениями.
  2. Установите высоту, ширину и положение прокрутки, чтобы показать то, что вы хотите, чтобы пользователь видел. Если вы хотите, чтобы пользователь видел выбранный элемент и 3 сверху и 3 снизу, сделайте его достаточно большим, чтобы отображались 7 строк в метке.
  3. Ваше изображение является «индикатором выбора», которое вы накладываете поверх центрального элемента в представлении прокрутки, чтобы показать пользователю, что это выбранный элемент.
  4. Если вам нужен красивый эффект затухания по мере того, как ваши значения выходят за пределы конца, вы можете создать белый (или любой другой фон вашего приложения) блок, который затухает до прозрачного и накладывает его поверх и снизу прокрутки. Это создает эффект затухания числа на краях компонента.

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

  1. Создайте UIScrollViewDelegate и реализуйте scrollViewDidScroll:, который сообщит вам о смещении содержимого вашего представления прокрутки, когда пользователи его изменят.
  2. Напишите метод, который будет преобразовывать смещение содержимого прокрутки, в которое был выбран «элемент». Если вы знаете, сколько строк в метке (и вы должны это сделать), и вы знаете, насколько высока метка (и вы должны), возьмите высоту/линии метки, чтобы получить высоту каждого «элемента». Затем вы берете смещение содержимого, делите его на высоту элемента, устанавливаете его на пол, и вы знаете, на какой строке вы находитесь... при этом помня, что смещение содержимого находится в верхней части вашего прокрутки, поэтому добавьте половину высоты. :)

Итак, основная функциональность реализована, и она работает, но некрасиво.

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

Другой проблемой, которая у меня была, была динамика. Как и в случае с настоящим колесом, я хотел, чтобы мой сборщик имел импульс, поэтому, если вы сильно щелкнете по нему, он будет работать некоторое время, но если вы слегка щелкнете по нему, он остановится довольно быстро. У меня был длинный список, и если люди переходили от 7 до 70, я хотел, чтобы они могли сделать это легко. Если вас это интересует, я могу показать вам, как я это сделал, и опубликовать код, когда вернусь к машине с моим кодом.

person DBD    schedule 05.09.2014
comment
У вас есть код, которым вы можете поделиться, это очень поможет. - person user1046037; 17.11.2017