如何根据tableviewcell选择将子视图的nsdictionary保存到主视图

时间:2011-10-27 20:57:22

标签: iphone ios uitableview nsxmlparser

我目前正在解析一些看起来像这个

的xml
<Rows>
<Row MANUFACTURERID="76" MANUFACTURERNAME="Fondont" ISMANU="F" ISAUTO="F"/>
<Row MANUFACTURERID="18" MANUFACTURERNAME="Anti" ISMANU="T" ISAUTO="T"/>
</Rows>

我解析它以便有一个字典数组(每个字典都包含Row的四个值)。

然后我将ManufacturerName传递给我的startSortingTheArray方法,就像这样

if (dataSetToParse == @"ICMfg") // ICMfg is a string passed to this view from the parent view cell selection enabling me to pass different data sets to this view
    {
       //Filter results (ISAUTO = T)
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",@"ISAUTO",@"T"];
        NSArray *filteredArray = [myDataArray filteredArrayUsingPredicate:predicate];
        //Passes Manufacturer strigs over to startSortingtheArray method
        [self startSortingTheArray:[filteredArray valueForKey:@"MANUFACTURER"]];
    }

因此,从这里将所有ManufacturerNames作为字符串数组发送到我的方法。然后我使用这个数组来设置我的所有section / index-scroller。下面的方法显示了我是如何做到的。

//method to sort array and split for use with uitableview Index
- (IBAction)startSortingTheArray:(NSArray *)arrayData
{
    //If you need to sort incoming array alphabetically use this line of code
    //TODO: Check values coming in for capital letters and spaces etc
    sortedArray = [arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    //If you want the standard array use this code
    //sortedArray = arrayData;

    self.letterDictionary = [NSMutableDictionary dictionary];
    sectionLetterArray = [[NSMutableArray alloc] init];

    //Index scrolling Iterate over values for future use
    for (NSString *value in sortedArray) 
    {
        // Get the first letter and its associated array from the dictionary.
        // If the dictionary does not exist create one and associate it with the letter.
        NSString *firstLetter = [[value substringWithRange:NSMakeRange(0, 1)] uppercaseString]; //uppercaseString puts lowercase values with uppercase

        NSMutableArray *arrayForLetter = [letterDictionary objectForKey:firstLetter];
        if (arrayForLetter == nil) 
        {
            arrayForLetter = [NSMutableArray array];
            [letterDictionary setObject:arrayForLetter forKey:firstLetter];

            [sectionLetterArray addObject:firstLetter]; // This will be used to set index scroller and section titles
        }
        // Add the value to the array for this letter
        [arrayForLetter addObject:value];
    }      
    //Reload data in table
    [self.tableView reloadData];
}

从这里开始在 [self.tableView reloadData]; 之后设置tableview时要做几件事情,主要的是我用字符串值设置单元格数组。

//Display cells with data
    NSArray *keys = [self.letterDictionary objectForKey:[self.sectionLetterArray objectAtIndex:indexPath.section]];
    NSString *key = [keys objectAtIndex:indexPath.row];

    cell.textLabel.text = key;

然后选择单元格后,单元格内的字符串值将被发送回主视图,并在以后用作搜索参数...事实是我正在设置几个将用作一个参数的参数搜索字符串。

回顾我解析的XML

<Rows>
    <Row MANUFACTURERID="76" MANUFACTURERNAME="Fondont" ISMANU="F" ISAUTO="F"/>
    <Row MANUFACTURERID="18" MANUFACTURERNAME="Anti" ISMANU="T" ISAUTO="T"/>
</Rows>

这些是SQl表中具有keyvalue MANUFACTURERID的列的值,该值也可以在我解析的其他表中找到。我想使用这些键值来限制/优化其他查询但我无法弄清楚如何将它们传递给我设置所有搜索参数的父视图,这是我的问题如何保存值的字典与子视图中的用户tableview选择有关。这样我就可以将其中一个或一些值传递回不同数据集的子视图,以限制显示的信息,具体取决于用户以前的选择。

我花了大约一个小时打字。希望它有意义,我仍然是iOS开发和Objective C的新手,这个概念真的在推动我的能力,在我继续前进并最终得到一些废话之后我将不得不修复我希望那个或者你们中的一些人能够将这种类型的经验借给我,所以我可以第一时间做到这一点:)

如果您需要我澄清任何内容或为您提供更多帮助我帮助我的信息,请告诉我。

提前致谢!

3 个答案:

答案 0 :(得分:6)

在视图控制器层次结构中向后传递信息的常见模式是使用委托。您可以通过实施以下方法在您的方案中实现此目的:

1)在SearchParametersViewController中定义一个协议,该协议代表您提到的父视图控制器。

@protocol SearchParametersViewControllerDelegate <NSObject>
@optional
- (void)searchOptionsSelected:(NSArray *)selectedSearchOptions;
@end

2)符合SearchOptionsSelectionViewController中的协议,该协议表示具有可供选择的选择列表的表视图控制器。确保导入或转发声明定义协议的类(例如SearchParametersViewController)。

#import "SearchParametersViewController.h"

@interface SearchOptionsSelectionViewController <SearchParametersViewControllerDelegate>

3)在SearchOptionsSelectionViewController中定义委托属性(假设您在iOS 5.0上使用ARC,4.x使用unsafe_unretained而不是weak。使用{{1如果项目使用手动内存管理)。此委托对象将包含对父视图控制器的引用(例如,SearchParametersViewController)。您不希望保留此属性,以避免保留周期/循环引用,其中一个对象引用另一个对象,而该引用又返回第一个引用,并且两个对象都不会被释放。

assign

4)在父视图控制器(SearchParametersViewController)中实例化SearchOptionsSelectionViewController实例时,将@property (nonatomic, weak) id<SearchParametersViewControllerDelegate> delegate; 属性设置为父视图控制器实例,如delegate关键字所示。这可确保您可以在视图控制器层次结构中向后发送消息(和相应的数据),但对象关系保持松散耦合。此委托协议可以符合任何其他视图控制器,选择视图控制器中没有紧密的关系回到父视图控制器,链接它们的唯一事情是选择视图控制器采用灵活的委托协议。

self

5)最后,在SearchOptionsSelectionViewController表视图的SearchOptionsSelectionViewController *selectionViewController = [[SearchOptionsSelectionViewController alloc] init]; selectionViewController.delegate = self; 委托方法中,通过您定义的委托方法将对应于所选行的数据传递回父视图控制器(SearchParametersViewController)在SearchParametersViewControllerDelegate协议中。您必须使用-tableView:didSelectRowAtIndexPath:方法来确保委托对象实际实现-respondsToSelector:委托方法。要强制执行此实现,请在步骤#1中的协议定义中将方法原型上方的-searchOptionsSelected:更改为@optional@required表示您与选择表视图控制器一起使用的数据源。可以更改发送回父视图控制器的委托协议方法和数据对象的细节,这里重要的是委托模式,并且在任一类的实例之间没有任何紧密耦合的关系,但特别是向后视图控制器层次结构。

self.someDataArray

6)- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([self.delegate respondsToSelector:@selector(searchOptionsSelected:)]) { NSArray *selectedObjs = [NSArray arrayWithObject:[self.someDataArray objectAtIndex:indexPath.row]]; [self.delegate searchOptionsSelected:selectedObjs] } }

中实施委托方法
SearchOptionsSelectionViewController.m

进一步阅读:

Cocoa Fundamentals Guide - Delegates and Data Sources

Cocoa Core Competencies - Protocol

答案 1 :(得分:3)

您可以使用应用程序委托来实现您的目标。

我假设您的应用程序的结构有点像这样。请原谅这种模式的粗糙。

Application delegate (A) --> Search Options View (B) --> Table where you do selections (C)
                      |
                      |
                      --> Some other view where you need the selection (D)

您的问题是您需要从C到D的信息。

您的申请代表的优点是可以通过[[UIApplication sharedApplication] delegate]普遍访问。所以你可以从任何地方获得指向它的指针。从C,您可以将您的选择信息发送回A. A可以自动发送给D,或者D可以随时从A请求它。

有几点:

  • 我现在不会再对我的答案进一步扩展,因为现在这里有啤酒,加上我可能误解了你的要求。如果你还需要其他任何东西,我将在英国时间早上起床,所以可能会有一些延迟。
  • 有些人不赞成使用应用程序委托作为我建议的方式的“数据转储”。其中一些人宁愿设置一个完整的单例类,而是将其视为数据转储。这似乎是那些无休止的争论之一,所以我尽量不介入。

答案 2 :(得分:1)