从另一个 ViewController 重新加载 UIPickerView 的数据

Posted

技术标签:

【中文标题】从另一个 ViewController 重新加载 UIPickerView 的数据【英文标题】:Reload data for UIPickerView from another ViewController 【发布时间】:2014-10-14 07:29:35 【问题描述】:

我的问题是关于从另一个 ViewController 为我的 UIPickerView 设置新数据。我有 main.storyboard(ViewController.h 和 ViewController.m),里面有一个 pickerview(我称之为 aPicker)。我有一个 CustomTableViewController 来加载一些图像。当我点击这些图片时,aPicker 的数据会发生变化。

ViewController.m 中的一个Picker

- (NSInteger)numberOfComponentsInPickerView: (UIPickerView *)pickerView;
    return 1;


- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    if(pickerView== aPicker)
    
        //I will code it later
    


-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
    if(pickerView==aPicker)
    
        return [aPickerAdapter count];
    


- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view

    UIView* tmpView= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 32)];
    UILabel *lbl;

    if(pickerView==aPicker)
    
        lbl = [[UILabel alloc] initWithFrame:CGRectMake(64, 0, 256, 32)];
        [lbl setText:[aPickerAdapter objectAtIndex:row]];
    
    [tmpView insertSubview:lbl atIndex:0];

    return tmpView;
    

我在这里调用自定义表:

NSMutableArray* tranferData= [[NSMutableArray alloc] init];

[tranferData addObject:aPickerAdapter];
[tranferData addObject:aPicker];
[tranferData addObject:self];
aPicker.delegate=self;
[tranferData addObject:aPicker.delegate];
aPicker.dataSource=self;
[tranferData addObject:aPicker.dataSource];



customTableViewController=[[CustomTableViewController alloc] initWithNibName:@"CustomTableViewController" bundle:[NSBundle mainBundle] set:tranferData];
customTableViewController.delegate=self;

[self.view addSubview:customTableViewController.view]; 

在CustomTableViewController.m中接收

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil set:(NSMutableArray *)myarray
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        myArray=myarray;
        // Custom initialization on passed parameter observation object
        aPickerAdapter=[myarray objectAtIndex:0];
        aPicker=[myarray objectAtIndex:1];
        tranferSeft=[myarray objectAtIndex:2];
        pickerDelegate=[myarray objectAtIndex:3];
        pickerDataSource=[myarray objectAtIndex:4];
    
    return self;

点击表格中的图片时

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    NSString *string= [@"tap to row " stringByAppendingString:[NSString stringWithFormat:@"%d",indexPath.row]];
    NSLog(string);

    //NSString *str= [onlineIdList objectAtIndex:indexPath.row];
    //UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Demo" message:str delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];

    //[alert show];

    NSMutableArray *testArr= [[NSMutableArray alloc]init];
    [testArr addObject:@"2"];
    [testArr addObject:@"4"];
    [testArr addObject:@"6"];

    //aPicker.delegate= pickerDelegate;
    //aPicker.dataSource= pickerDataSource;

    **aPickerAdapter=testArr;
    [aPicker reloadAllComponents];**

    [self hideAndShowSubChannel];//this funtion is to hide and show aPicker, defaut aPicker is hide, on first tap it will show([aPicker setHidden:NO]), and it hide on second tap....

当我点击图像时,选择器仅隐藏和显示(我认为这意味着我的程序可以理解指向 aPicker 的指针),但它无法将数据从我的 testArr 添加到 aPicker,我也尝试重置委托和收到数据源,直到无法正常工作。我在 ViewController.m 中使用相同的代码(创建 testArr,设置 aPickerAdapter,reloadAllComponent...)进行测试,它可以工作。为什么我不能重新加载它?请帮帮我!

ps:我只是个新手,英语不好。如有错误请见谅,谢谢

【问题讨论】:

你说:“当我点击图像时,选择器只会隐藏和显示”。两个视图控制器同时显示? 您能否进一步解释您的代码,或者添加您的属性声明的代码-sn-p?例如什么是aPickerAdapter... 嗨,aPickerAdapter 是一个 NSMutableArray。它包含 aPicker 的数据(您可以在 numberOfRowsInComponent 和 viewForRow 上看到它)。我认为 aPickerAdapter 是问题所在,可能 ViewController.m 中指向 aPickerAdapter 的指针和 CustomTableViewController.m 中指向 aPickerAdapter 的指针不相等。但我不知道如何处理:( @kelin:我只有一个故事板。每件事都会自动加载,我的自定义表也是如此。当它显示时,我在 tableview 中点击图像,aPicker 将显示(并隐藏->显示->隐藏....每次点击)。 :D @HuyHómHỉnh,你想说你甚至没有在模拟器上运行你的应用程序? :D 【参考方案1】:

我会做不同的事情。您正试图让您的 TableViewController 直接更新另一个视图控制器的视图 - 您不应该这样做。相反,您需要将数据传递回您的第一个视图控制器,以便它可以更新自己的视图。为此有多种技术(请参阅this link),但在您的情况下,我会在您的视图控制器中实现一个方法并从您的自定义 TableViewController 中调用它:

在 ViewController 中:

-(void)updatePicker:(NSArray *)newArray 
    aPickerAdapter = testArr;
    [aPicker reloadAllComponents]
    // and do anything else you need

在您的 CustomerTableViewController didSelectRow 方法中:

[self.delegate updatePicker:testArr];

【讨论】:

我理解你的方式,但我不知道如何从 CustomTableViewController.m 调用方法 updatePicker(in Viewcontroller.m)。我不明白 seft.delegate 是什么意思?在 didSelectRow 中的 seft 将意味着 CustomTableViewController?谢谢! 是的,didSelectRow 中的 self 将引用 customTableViewController。但是你在实例化它之后立即设置了delegate 属性(customTableViewController.delegate=self)。该行在您的主视图控制器中,因此self 指的是主视图控制器。因此,在您的customTableViewController 中,self.delegate 指回您的主视图控制器。【参考方案2】:

我已经通过@pbasdf anh 他的link 解决了这个问题 (@Matt Price 的回答真的很有用)。 Tks 全部 :D

【讨论】:

【参考方案3】:

尝试实现 UIPickerViewDelegate-Method

(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;

而不是 viewForRow 方法。

例如这样:

- (NSString *)pickerview:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    
    return [aPickerAdapter objectAtIndex:row];

【讨论】:

如果有 viewForRow,titleForRow 可能不起作用。我使用 viewForRow 是因为我需要自定义这个选择器。关于在情节提要中指定委托和数据源,是否拖放到视图控制器中(情节提要屏幕设计上方的黄色按钮)?谢谢:D 很抱歉,关于数据源/委托的评论不正确。我误解了一些东西。

以上是关于从另一个 ViewController 重新加载 UIPickerView 的数据的主要内容,如果未能解决你的问题,请参考以下文章

需要从另一个viewController调用其他viewController中的方法

从另一个被关闭的 vc 访问 viewcontroller 时的运行方法

从另一个 Popover 中关闭显示为 Popover segue 的 ViewController

如何从另一个 UIViewController 重新加载 UITableViewController

从另一个类重新加载 UITableView?

从另一个视图重新加载表视图