根据数据显示数据 UIPickerView

Posted

技术标签:

【中文标题】根据数据显示数据 UIPickerView【英文标题】:Displaying data UIPickerView depending on data 【发布时间】:2012-08-09 15:30:28 【问题描述】:

我正在为 iPhone 开发一个应用程序(我的第一个应用程序),我想使用两个 UIPickerView 来显示一些数据。第一个 UIPickerView 将显示汽车品牌列表(例如 BMW、Mercedes、Ford 等),第二个 UIPickerView 将显示模型,具体取决于您在第一个 UIPickerView 中选择的 UIPickerViewItem。

我的问题是没有设置 UIPickerView,这已经完成了。

我想知道如何从某种数据存储中填充两个 PickerViews(可能是 sqlite、core-data...?虽然不确定它们是如何工作的),而且第二个 PickerView 应该只填充第一个一个人选择了一个项目,所以它只显示该品牌的模型。

我希望你能理解,因为我真的不知道如何做到这一点(我通常只做网络开发,使用 phpmysql 非常容易......);)

提前致谢! 迈克

【问题讨论】:

显示你目前拥有的东西。听起来您可以只使用 .plist 并根据您的第一个选择为第二个选择器视图设置数据源数组。 我只有两个 PickerViews,它们设置为在单击按钮时显示(在 html 中用作选择),当您单击其他位置时它被隐藏。但是我仍然可以将所有模型放在同一个数组中吗?我怎么知道它连接到什么品牌?我的意思是像一个外键左右:) 我对 plist 的了解非常基本,所以如果这是我可以使用的东西,那就太好了! 【参考方案1】:

核心数据是必经之路,但学习曲线陡峭。你应该花一些时间来学习它。

对于您的目的来说,使用 plist 会容易得多,也许就足够了。这些是 Apple 特定的 xml 文件,结构非常简单。您可以直接在 Xcode 中编辑它们,格式非常透明。

然后,您可以一次从 plist 加载所有数据,并根据第一个选择器填充第二个选择器。

您也可以使用 JSON 文件。这些甚至更简单,作为网络程序员,您可能对这些很熟悉。

一些提示:

你的数据应该有这样的结构:字典数组;每个字典都有一个品牌键和一个用于另一个数组的键,一个模型列表。这个子数组是一个带有名称键的字典(如果您的应用程序中需要它,可能还有更多)。

您可以像这样加载名为“Data.plist”的 plist 文件(JSON 是模拟的):

NSString *path = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"];
NSArray *data = [NSArray arrayWithContentsOfFile:path];

现在您可以获得这样的品牌列表(假设您的品牌名称键是“name”):

NSArray *brands = [data valueForKeyPath:@"name"]; 

还有一个品牌的品牌列表:

NSArray *models = [[[data filteredArrayUsingPredicate:[NSPredicate
   predicateWithFormat:@"name = %@", @"Ford"]] objectAtIndex:0] 
    valueForKey:@"models"]);

要对第一个选择器视图的选择做出反应,请确保您的视图控制器是选择器视图的委托并覆盖 pickerView:didSelectRow:inComponent:

您可以通过分配tags 并在回调方法中检查它们来区分这些委托方法中的选择器。

这是您的 plist 结构的示例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>name</key>
        <string>Ford</string>
        <key>models</key>
        <array>
            <string>Mustang</string>
            <string>Capri</string>
        </array>
    </dict>
    <dict>
        <key>name</key>
        <string>VW</string>
        <key>models</key>
        <array>
            <string>Polo</string>
            <string>Golf</string>
        </array>
    </dict>
</array>
</plist>

希望这会有所帮助。

【讨论】:

嗨,我相信这是我应该这样做的正确方式,但我不完全确定我应该如何构建我的 plist。你能给我一个例子来说明它应该是什么样子吗? :) 我给你贴一个模板。 非常感谢,这真的很有帮助! 您好,我遇到了一个新问题:当我尝试添加更多品牌时,例如,如果我向其中添加 BMW 和一些车型,当我在 PickerView 中选择该品牌时,应用程序会终止。这是我收到的消息:“由于未捕获的异常 'NSRangeException' 而终止应用程序,原因:'-[__NSCFArray objectAtIndex:]: index (2) beyond bounds (2)' *** First throw call stack:”...它指向的行是:“if(pickerView == modelPicker) return [models objectAtIndex:row]; ” 位于“- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forCompon"... 方法 您的数组models 需要在您选择新品牌时进行更新。您似乎仍在使用之前选择的那个。【参考方案2】:

这取决于您想要的数据源类型。如果您的数据源是静态的,并且永远不会改变,那么您可能需要的只是一个简单的 NSArray,您可以在每次启动应用程序时创建。从您的要求看来,这绝对是您想要做的,因为它是更简单的方法。

每当您创建 UIPickerController 或如果它是 IBOUTLET 时,请对 ivar/property 执行此操作:

myPicker1.tag = 1;
myPicker2.tag = 2;

分配一个标签来区分它们,因为它们都将在您的委托/数据源(本例中为您的 ViewController)上调用相同的回调方法

然后,由于您想根据在 Picker 1 上选择的值对 Picker 2 执行操作,因此您需要这样的操作:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component


    if (pickerView.tag == 1) 
         //Means a value just changed on your picker 1!, update datasource for your second picker
        [myPicker2 reloadComponent:0]; // This will trigger the method - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component method below
    


Finally implement the - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component method below method, which gets called when the picker needs to load its components, or in this case also if you call reloadComponent

你需要这样的东西:

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

     if (pickerView.tag == 2) 
      //Get appropriate value from the array and return the string for that row
            MyObject *selectedObject = [myArray objectAtIndex:[pickerActivity selectedRowInComponent:0]];
            //Return what you need depending on your needs.
       

最后我建议看看UIPickerView class reference

希望对您有所帮助。

【讨论】:

以上是关于根据数据显示数据 UIPickerView的主要内容,如果未能解决你的问题,请参考以下文章

php根据html切换开关显示数据库中的数据

从 sql 数据库中检索数据并在表格中显示 - 根据选中的复选框显示某些数据

根据用户名显示 Firebase 数据

求救: Gridview绑定数据时如何根据数据 显示相应图片。。。

mysql使用内部连接根据数据库中的日期范围显示数据

根据选择的初始值显示 JSON 数据