1

下面的代码正在创建对许多字符串的搜索。最初有 5 行,当您到达第 5 行时,它会添加另一行。我不只是直接编辑行,而是加载一个过滤器控制器(另一个视图控制器,当您键入它时,它会为您完成单词)。当用户找到一个单词时,他点击它并返回到这个视图控制器。现在我想用过滤器中的文本填充最初点击的单元格。

我试着早点问,并没有得到任何具体的答案。

我遇到了一个问题,当我滚动时(添加新行后),它开始用表格中已有的信息填充这些行,(而不是保持空白)

请帮助我哪里出错了

//global indexpath to remember which cell tapped
NSIndexPath *globalPath;
@interface SearchViewController ()

@end

@implementation SearchViewController

//Load implementation once per launch
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self linkInputTableToDelegate];
    _temporaryResultsArray =[[NSMutableArray alloc]init];
    _flurryArray=[[NSMutableArray alloc]init];
    _numberOfSections=6;
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:NO];
    [InputTable reloadData];

    textFromUserDefaults=[[[HelperMethods alloc]init]getObjectUserDefault:@"textFiltered"];
    [self addTextToFlurryArrayForFlurryAndSavedLists:_textFromUserDefaults];
}

-(void)viewDidDisappear:(BOOL)animated{

}

- (IBAction)searchButtonPressed:(UIButton *)sender {
     self.tabBarController.selectedIndex = 1;
}

//Makes the input table respond to delegate table view methods
-(void)linkInputTableToDelegate{
    _inputTable.dataSource=self;
    _inputTable.delegate=self;
}

-(void)performSearch:(NSString*)text{
    //do search
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    int numberOfRows=_numberOfSections;

    //Rows for iPhone 4
    if ([[UIScreen mainScreen]bounds].size.height==480) {
        numberOfRows=numberOfRows;
        //Rows for iPhone 5
    }else if ([[UIScreen mainScreen]bounds].size.height==568){
        numberOfRows=numberOfRows+1;
    }
    return numberOfRows;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //In reality groups are created with 1 row inside, this is to allow spacing between the rows
    return 1;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *kCellID = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];

    if (!cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
    }

    //Is the cell the same as the one clicked when going to ingredient filter
    BOOL cellIndexPathSameAsSelected=[self isCellIndexSameAsPreviousClicked:indexPath];

    cell.textLabel.textColor=[UIColor blackColor];
    if (cellIndexPathSameAsSelected && _textFromUserDefaults!=nil) {

        if (![cell.textLabel.text isEqualToString:_textFromUserDefaults]) {

            cell.textLabel.text=_textFromUserDefaults;
            [self performTextSearch:_textFromUserDefaults];
        }

    }
    return cell;
}

//Compares the previous clicked cell with the cell now selected
-(BOOL)isCellIndexSameAsPreviousClicked: (NSIndexPath*)cellPath{

    if (cellPath.row == globalPath.row && globalPath.section==cellPath.section) {
        return YES;
    }
    else{
        return NO;
    }
}

- (void)updateTableViewWithExtraRow :(NSIndexPath*)rowSelected{
    NSLog(@"number of sections =%i",_numberOfSections);
    if (rowSelected.section == _numberOfSections) {
        _numberOfSections ++;
    }
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = [tableView cellForRowAtIndexPath:indexPath].textLabel.text;
    [[[HelperMethods alloc]init]saveObjectToUserDefaults:cellText :@"textFiltered"];
    globalPath = indexPath;
    [self updateTableViewWithExtraRow:indexPath];
}

-(void)addTextToFlurryArrayForFlurryAndSavedLists:(NSString*)text{
    if ([_flurryArray count]==0 &&[text length]>0) {
        [_flurryArray addObject:text];
    }
    for (int i=0;i<[_flurryArray count];i++) {
        NSString *textInArray=[_flurryArray objectAtIndex:i];
        if (![textInArray isEqualToString:text]) {
            [_flurryArray addObject:text];
        }

    }
    NSLog(@"Total number of saved items = %i",[_flurryArray count]);
}

// Dispose of any resources that can be recreated.
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
4

2 回答 2

2

我对代码有几个反应:

  1. 关于正确使用这些UITableViewDataSource方法的一些观察,特别numberOfRowsInSection是 、numberOfSectionsInTableViewcellForRowAtIndexPath

    • 这些确实应该由一些模型数据结构(例如 a NSMutableArray)驱动,仅此而已;

    • 这些方法应该是无状态的。他们不应该依赖某些NSString实例变量的值,例如_textFromUserDefaults),而是始终NSMutableArray根据参数的值在模型结构中查找值indexPath。您根本无法对何时cellForRowAtIndexPath被调用做出任何假设。这很可能解释了您的重复值。

    • UITableView除了回应询问之外,这些都不应该做任何事情。例如,您cellForRowAtIndexPath正在调用performTextSearch. 除了返回单元格之外,它真的不应该做任何事情。

    • cellForRowAtIndexPath当前具有条件逻辑,并且仅在某些条件成立时才更新单元格。因为单元格被重用,所以您真的要确保无论如何都初始化单元格。你不能保证当你得到它时单元格是空白的,也不能保证以前的内容就是那个indexPath. 因为单元格被重复使用,它可能用于完全不同的行。这也可能导致您的重复条目。

  2. 关于主视图控制器和细节视图控制器的交互,有比通过NSUserDefaults. 例如,当您启动详细信息视图控制器时,您可以将所需的信息传递给它。完成后,它应该调用主视图控制器中的方法来更新主视图中的数据。为此,主视图控制器应符合您自己创建的某些协议。如果您看到我通过聊天分享的示例,您可以看到它的样子。无论如何,通过在主视图控制器中有一些委托方法,详细视图控制器在完成时调用它,这消除了viewDidAppear用于控制主表视图更新的相当脆弱的技术。

  3. 您可能需要考虑使用“编辑”(它允许您删除,也可能编辑特定行)和“添加”按钮,例如 Xcode 提供的标准“主-详细信息”模板。这里有许多标准约定可能比拥有一组空白单元格然后您可以点击更好。显然,您的用户体验完全取决于您,但您始终可以考虑是否存在您可能采用的现有、熟悉的约定。

于 2013-01-06T20:42:43.973 回答
0

Rob 的反馈很好。从更广泛的意义上讲,您不能依赖 a 中的单元格UITableView来保存它们的数据。为了提高效率,它将随意创建、使用和破坏细胞,并使用cellForRowAtIndexPath它来弄清楚它们应该是什么样子。您需要拥有自己的一组数据来描述每个单元格的值,而不是测试单元格中的内容,并且只需根据indexPath. 我建议将所有单元格信息存储在NSMutableArray包含NSStrings 或必要时更复杂的内容中。将单元格添加到数组时,很容易设置默认值。然后cellForRowAtIndexPath可以只访问数组,而不是尝试基于当前单元格的自己的逻辑。

于 2013-01-06T17:50:27.510 回答