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メソッド、特にnumberOfRowsInSectionnumberOfSectionsInTableView、およびの適切な使用に関するいくつかの観察cellForRowAtIndexPath:

    • これらは実際には、何らかのモデル データ構造 (たとえば a NSMutableArray) によって駆動される必要があり、他には何もありません。

    • これらのメソッドはステートレスにする必要があります。NSStringなどのインスタンス変数の値に依存するのでは_textFromUserDefaultsなく、常にパラメーターNSMutableArrayの値に基づいてモデル構造内の値を検索する必要がありindexPathます。がいつcellForRowAtIndexPath呼び出されるかについて、まったく推測することはできません。これは、重複した値の原因となる可能性があります。

    • UITableViewこれらのいずれも、問い合わせへの対応以外に何もすべきではありません。たとえば、あなたcellForRowAtIndexPathは を呼び出してperformTextSearchいます。セルを返す以外は何もすべきではありません。

    • 現在、条件付きロジックcellForRowAtIndexPathがあり、特定の条件が満たされている場合にのみセルを更新します。セルは再利用されるため、関係なくセルを初期化する必要があります。取得時にセルが空白であることや、以前の内容がその以前の値であることを保証することはできませんindexPath。セルは再利用されるため、まったく別の行になる可能性があります。これは、重複したエントリの原因にもなります。

  2. マスター ビュー コントローラーと詳細ビュー コントローラーの相互作用に関しては、 を介してデータをやり取りするよりも洗練された方法がありますNSUserDefaults。たとえば、詳細ビュー コントローラーを開始するときに、必要な情報を渡すことができます。完了したら、マスター ビュー コントローラーのメソッドを呼び出して、マスター ビューのデータを更新する必要があります。これを行うには、マスター ビュー コントローラーが独自に作成したプロトコルに準拠する必要があります。チャットで共有した例を見れば、それがどのように見えるかがわかります。いずれにせよ、マスター ビュー コントローラーにデリゲート メソッドがあり、それが完了したときに詳細ビュー コントローラーが呼び出すことviewDidAppearで、マスター テーブル ビューの更新を制御するために使用するかなり脆弱な手法を排除できます。

  3. Xcode が提供する標準の「master-detail」テンプレートのような「編集」ボタン (特定の行を削除したり、場合によっては編集することもできます) および「追加」ボタンを使用することを検討することをお勧めします。ここには、タップできる空のセルの配列を用意するよりも優れた標準的な規則がいくつかあります。明らかに、ユーザー エクスペリエンスは完全にあなた次第ですが、採用する可能性のある既存の使い慣れた規則があるかどうかを常に検討することができます。

于 2013-01-06T20:42:43.973 に答える
0

ロブのフィードバックは良いです。UITableViewより広い意味で言えば、データを保持するために内のセルに依存することはできません。効率化のために、セルを自由に作成、使用、および破壊し、それらを使用してセルがcellForRowAtIndexPathどのように見えるべきかを把握します。セルの内容をテストする代わりに、各セルの値を説明する独自のデータ セットを用意し、に基づいて値を設定する必要がありますindexPath。必要に応じて、すべてのセル情報をs またはより複雑なものNSMutableArrayを含むに保存することをお勧めします。NSString配列にセルを追加するときにデフォルト値を設定するのは簡単です。次にcellForRowAtIndexPath、現在のセルに基づいて独自のロジックを試行するのではなく、配列にアクセスできます。

于 2013-01-06T17:50:27.510 に答える