Загружать данные в UIPickerView до того, как они появятся

Я использую UIPickerView в контроллере просмотра, который находится в модальном представлении (если так он называется). Я везде читал, что [picker reloadAllComponents]; в viewDidLoad должен помочь, но это не так. Я переопределил -(UIView*)viewForRow-метод, но не думаю, что это должно быть проблемой ..

Дело в том, что когда viewController появляется вертикально, средство выбора пусто. И он остается пустым, пока я не прокручу вниз, чтобы появилась новая строка. Однако, если я добавлю [picker reloadAllComponents]; к viewDidAppear, данные появятся сразу после того, как viewController завершит свою вводную анимацию (по вертикали). Хотя это раздражает. Я хочу, чтобы у сборщика уже были данные, когда он сдвигается вверх.

Я попытался вставить reloadAllComponents как в viewDidLoad, так и в viewWillAppear, но это не сработало.

Я помещаю NSLog в метод делегата, и он распечатывает правильные данные, и делает это до появления представления, но почему он его не показывает?

У меня была такая же проблема с tableViewController раньше, и я думаю, что reloadData помогло тогда, но почему он не отображает мои представления в viewDidLoad? Он делает это только в том случае, если он вызывается в viewDIDappear ..

Код:

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if(component == TYPE1)
        return [[con getTypes] count];

    else return 1;

}
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    UIView* newView = [[UIView alloc] init];

    //Create a label, put it on the left side of the view
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(view.frame.origin.x + 5, view.frame.origin.y, view.frame.size.width-45, view.frame.size.height)];
    [label setText:[[[con getTypes] objectAtIndex:row] getName]];
    [newView addSubview:label];//add

    //Create an imageview, put it on the right side of the view
    UIImageView*imageViewType = [[UIImageView alloc] initWithFrame:CGRectMake(view.frame.origin.x+(view.frame.size.width-40), view.frame.origin.y, 40, 40)];
    [imageViewType setImage:[[[con getTypes] objectAtIndex:row] getImage]];
    [newView addSubview:imageViewType];//add

    [label setBackgroundColor:[UIColor clearColor]];


    NSLog(@"%@", [[[con getTypes]objectAtIndex:row] getName]);
    //This NSLog prints out the correct name for the top three items of the list
    //-even when called from viewDidLoad, and even before the view appears, but
    //the content never shows up in the picker unless I scroll or call it again in 
    //viewDidAppear..

    return newView;
}

person Sti    schedule 26.04.2013    source источник
comment
Что вы загружаете в UIPicker, NSMutableArray? Если да, то когда элементы добавляются в массив?   -  person JDx    schedule 26.04.2013
comment
@JDx NSMutableArray с некоторыми объектами. Я создаю этот viewController программно и использую initWithController:(Controller*)c (самодельный), а контроллер уже содержит изменяемый массив. В моем методе инициализации я использую self = [storyboard instantiateViewControllerWithIdentifier:@"identifier"];, а затем устанавливаю данные, это проблема? .. Я так не думаю .. Когда я вызываю reloadAllComponents из viewDidLoad, он распечатывает правильный текст (текст, который должен отображаться в сборщике ), но он не будет отображать его, пока я не прокручу вниз, чтобы делегат вмешался или что-то в этом роде ...   -  person Sti    schedule 26.04.2013
comment
Пожалуйста, покажите код вашего перезаписанного viewForRow и вашу реализацию - numberOfComponentsInPickerView: и - pickerView: numberOfRowsInComponent:   -  person Hermann Klecker    schedule 26.04.2013
comment
Добавлен код @HermannKlecker .. Это потому, что я не использую предоставленный UIView *view в viewForRow? Я думал, что это похоже на повторное использование, я могу ошибаться ..   -  person Sti    schedule 26.04.2013
comment
Странный. Это должно сработать. Метод вообще вызывается? В противном случае делегат, вероятно, настроен неправильно.   -  person Hermann Klecker    schedule 26.04.2013
comment
Однако не следует создавать новое представление при каждом вызове. Создавайте новый только тогда, когда использованный один переданный равен нулю. Когда вы повторно используете старую, либо удалите все ее подпредставления, либо повторно используйте подпредставления. В вашем случае я бы повторно использовал подвиды. Но это не решает вашу проблему.   -  person Hermann Klecker    schedule 26.04.2013
comment
Вы используете view.frame.origin независимо от того, является ли представление нулевым или нет. Для первых вызовов он будет равен нулю, потому что ничего не используется повторно. При втором вызове уже есть просмотры, те, которые вы создали ранее. И для них view.frame.origin имеет какое-то разумное значение, то есть (0,0), я думаю. Когда view равен нулю, тогда в источнике есть непредсказуемое значение. Это означает, что ваше представление отображается, но метка и рисунок находятся в другом месте. Попробую скатать кодовую базу на твоей.   -  person Hermann Klecker    schedule 26.04.2013


Ответы (1)


person    schedule
comment
Спасибо! Теперь это работает. Мне пришлось немного поправить код, например, [label setText] недоступен после оператора if, поэтому, если кому-то еще интересно, я получил их UILabel *label=(UILabel*)[[newView subviews]objectAtIndex:0];´. 0` для метки, 1 для imageView. Сложность заключалась в том, что этого было недостаточно! Несмотря на то, что данные устанавливаются после оператора if, по-видимому, они не устанавливаются, когда view = nil. Итак, поместив [label setText] и setImage в else, это наконец сработало. И размеры, которые я в итоге использовал, были (15, 6, 140, 44). Спасибо еще раз! - person Sti; 26.04.2013
comment
Хотя ... когда я думаю об этом ... Мне кажется странным, что остальные строки выглядели правильными после прокрутки, когда я никогда не устанавливал рамку .. Рыбный .. - person Sti; 26.04.2013
comment
Вы инициализируете фрейм. Это соответствует инициализации и установке кадра в два этапа. Если только рамка не изменится, а это не произойдет, насколько я понимаю, нет необходимости повторно устанавливать рамку. Кадры остаются неизменными, когда супервизор (здесь ячейка) прокручивается за пределы экрана. - person Hermann Klecker; 29.04.2013