4

グループ化されたテーブルビュー内でフォームを作成しています。このフォームには、UIswitches と textfields があります。しかし、下にスクロールすると、セルのスタイルが変化しています。

これが私のcellForRowAtIndexです

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = nil;
    static NSString *MyIdentifier = @"GenericCell";
    cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
    }
        NSString *text = nil;

    if(indexPath.section == CREDENTIALS_SECTION){
        if (indexPath.row == 0) {
            NSLog(@"tot hier login");
            UITextField *login = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
            login.adjustsFontSizeToFitWidth = YES;
            login.placeholder = @"example@gmail.com";
            login.keyboardType = UIKeyboardTypeEmailAddress;
            login.returnKeyType = UIReturnKeyNext;
            login.backgroundColor = [UIColor clearColor];
            login.tag = 0;
            login.delegate = self;

            [login setEnabled: YES];

            [cell addSubview:login];
        }else if (indexPath.row == 1){
            NSLog(@"tot hier pass");
            UITextField *pass = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
            pass.adjustsFontSizeToFitWidth = YES;
            pass.placeholder = @"Required";
            pass.keyboardType = UIKeyboardTypeDefault;
            pass.returnKeyType = UIReturnKeyDone;
            pass.secureTextEntry = YES;

            pass.backgroundColor = [UIColor clearColor];
            pass.tag = 0;
            pass.delegate = self;
            [cell addSubview:pass];
        }

        if (indexPath.row == 0) { // Email
            text = @"Email";
        }
        else if(indexPath.row == 1) {
            text = @"Password";
        }
    }else  if(indexPath.section == METHODS_SECTION){
        UISwitch *toggleSwitch = [[UISwitch alloc]initWithFrame:CGRectMake(220, 10, 100, 30)];
        toggleSwitch.tag = indexPath.row;
        [toggleSwitch addTarget:self action:@selector(toggleSwitched:) forControlEvents:UIControlEventValueChanged];
        [cell addSubview:toggleSwitch];

        if (indexPath.row == 0) { // Web
            text = @"Web applicatie";
        }
        else if(indexPath.row == 1) { //Mobile
            text = @"Mobiele applicatie";
        }
        else if(indexPath.row == 2) { //Mail
            text = @"E-mail";
        }


    }else  if(indexPath.section == PHONE_SECTION){
        UITextField *phoneText = [[UITextField alloc] initWithFrame:CGRectMake(20, 10, 185, 30)];
        phoneText.adjustsFontSizeToFitWidth = YES;
        phoneText.font = [UIFont fontWithName:@"Arial-BoldMT" size:18];
        phoneText.keyboardType = UIKeyboardTypeNumberPad;
        phoneText.delegate = self;
        phoneText.textColor = [UIColor blackColor];
        phoneText.text = _person.phone;
        [cell addSubview:phoneText];


    }else  if(indexPath.section == REMARK_SECTION){
        UITextView *textView = [[UITextView alloc]initWithFrame:CGRectMake(20, 10, 280, 260)];
        textView.text = _person.remark;
        textView.delegate = self;
        textView.font = [UIFont fontWithName:@"Arial" size:15.0];
        textView.backgroundColor = [UIColor clearColor];

        [cell addSubview:textView];
        text = @"";


    }else  if(indexPath.section == BUTTON_SECTION){
        cell.backgroundColor = [UIColor redColor];
        text = @"test";

    }
    cell.textLabel.text = text;
    return cell;
}

いくつかの検索の後、私はより多くの人々がこの問題を抱えていることを発見しました. そして、問題はこのコード部分にあります。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = nil;
    static NSString *MyIdentifier = @"GenericCell";
    cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
    }
        NSString *text = nil;

しかし、私はそれに対する解決策を見つけていません。誰でも助けてくれることを願っています!

敬具!

明確化

わかりましたので、ここに私のフォームのスクリーンショットが表示されます。下にスクロールすると赤いセル(保存ボタン)が表示され、他のセルの背景が赤くなっています。また、一部のセル、テキスト プロパティが変更されています。 ここに画像の説明を入力

4

6 に答える 6

3

それはうまくいきません。明らかに、再利用メカニズムがどのように機能するかをまだ完全には理解していません。

職業はなんですか?まず、再利用するセルを取得します。これまでのところ罰金が1つでも問題は後で発生します。取得できない場合は、新しいものを作成します。

ユーザーがスクロールを開始する前の開始時など、新しいものを作成したら、セクションと行に応じていくつかの UIItems を追加します。これが実際に賢明なことではない理由を説明します。

次に、ユーザーがスクロールします。セルは画面から消え、再利用できるようになります。次に、再利用のためにセルをフェッチします。しかし、それらのセルを以前にそのように使用したことがあるために、それらのセルに既に追加の UI-Item が存在する可能性があります。次のプロセスでは、そのセルに既に追加の UI アイテムがあるかどうかに関係なく、新しい UI アイテムを追加します。

できること:

  1. 独自のカスタム テーブル セル サブクラスを作成します。必要な追加の UI 項目のセットごとに 1 つのサブクラス。それはおそらくそれを行うための最もきちんとした方法です。サブクラスごとに異なる再利用識別子を使用します (!!!) これは私が推奨するものです! ただし、代替手段があります。

  2. あなたはまだあなたのコンセプトを受け入れることができますが、いくつかのタイプの追加の ui アイテムを持つセルのタイプごとに、個別のタイプの再利用識別子を発明することができます。if (cell == nil)その場合は、これらの UI 項目がコードのブランチのサブビューとしてのみ作成および追加されるようにしてください。一度だけ作成してから再利用してください。セルの再利用 ID は、「email-display」、「email-input」、「password-display」、「password-input」、「switch」などです。

  3. 上記のソリューションの違いは、行とセクションを再利用識別子に計算することです。セクション 0 と行 2 の「cell-id-0.2」など。ただし、追加の UI ビューを実際に再利用し、セルにデータが入力されるたびに再作成しないようにする必要があります。さらに、最初のセクションのレイアウトは、パスワードと電子メールを入力するか、単に表示するかによって異なります。これらのバリエーションに対処する必要があります。

  4. cell == nil の場合 - セルが再利用されている場合 - まず、以前に追加した可能性のあるすべての UI アイテムから削除します。作成時にUIViewに-たとえば99とタグ付けすることでそれを行うことができます-(0以外の場合は何でも行う必要があります)、すべてのサブビューを列挙して再利用するときは、タグ99を持つものを削除します。あなたはすでに作っています。

于 2012-12-14T11:08:31.037 に答える
2

最も簡単な修正は次のとおりです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"GenericCell"] ;
    //some more code
    return cell;
}

これにより、テーブルビューから再利用性が失われますが、制限された設定ビューであるため、問題ありません。Hermann Kleckerのソリューションから1つまたは2つ取ることをお勧めします。

于 2012-12-14T11:20:16.203 に答える
1

UIControl の状態も保持する必要がある場合は、使用します

static NSString *MyIdentifier = [NSString stringWithFormat:@"GenericCell%d",indexPath.row];

常に一意のテーブル行が返され、必要に応じて使用できます。

于 2012-12-14T11:00:40.887 に答える
0

再利用する前に、セルからすべてのサブビューを削除してみてください。コードを試してください:

if (cell == nil) 
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
else
{
   [cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}
于 2012-12-14T10:53:29.297 に答える
0

セルにサブビューを追加する前に、すべてのサブビューを削除してください。

if (cell == nil)
{
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault    reuseIdentifier:SimpleTableIdentifier]autorelease];
}
else 
{
    //To remove the subview of cell.
    for (UIView *vwSubviews in [cell.contentView subviews])
    {
            [vwSubviews removeFromSuperview];
    }
}

それはあなたの問題を解決するかもしれません。

于 2012-12-14T10:57:45.367 に答える
0

実際には、ここにいくつかの悪いコードがあります。

方法では

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

にないif (cell == nil)場合を除き、初期化して使用しないでください。

-(void)addSubview:(UIView*)view 

なんで?

セルは、tableview から再利用されるビューです。したがって、サブビューを追加すると、次回セルを再利用するときに、さらにサブビューが追加されます。単にそれらが重なっており、MEMORY LEAK を引き起こす可能性があります。

セルは再利用可能であることを忘れないでください。そう;

テキストを別の場所に設定しない限り、次のコードがある場合。すべてのセルのテキスト ラベルに「これはテキストです」というテキストが含まれていることが期待されます。再利用できるからです。

if (someChangingBool) {
   cell.textLabel.text = @"this is a text"; 
}

したがって、テキストを別のものに設定する場合は、else が必要です。

詳細について

于 2012-12-14T11:00:28.813 に答える