2

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

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

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

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

提前致谢!麦克风

4

2 回答 2

1

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

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

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

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

一些提示:

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

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

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

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

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>

希望这可以帮助。

于 2012-08-09T16:02:43.227 回答
1

这取决于您需要的数据源类型。如果您的数据源是静态的,并且永远不会改变,那么您所需要的可能只是一个简单的 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)componentmethod below method, which gets called when the picker needs to load its components, or in this case also if you callreloadComponent

你将需要这样的东西:

- (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 类参考

希望有帮助。

于 2012-08-09T15:57:07.763 回答