2016-08-08 6 views
1

UITableViewCellのリロードに関する奇妙なバグに直面しています。にカスタムrightViewが含まれています。 UITextFieldUITextFieldにrightViewを含むリロードすると無限ループとメモリがオーバーフローする

マイカスタムセル:

@implementation TableViewCell 

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 
     _textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 
     _textField.text = @"This is a text field"; 
     [self.contentView addSubview:_textField]; 
    } 

    return self; 
} 

@end 

UITableViewと私のビューコントローラ:

@interface ViewController() <UITableViewDataSource> 

@property (weak, nonatomic) IBOutlet UITableView *tableView; 
@property (nonatomic) UIView *rightView; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    // Press to reload the row with rightView 
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(reloadRow)]; 

    // Create rightView and store to a property 
    _rightView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)]; 
    _rightView.backgroundColor = [UIColor greenColor]; 

    [_tableView registerClass:[TableViewCell class] forCellReuseIdentifier:@"Cell"]; 
    _tableView.dataSource = self; 
} 

- (void)reloadRow { 
    [_tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 
                  inSection:0]] 
         withRowAnimation:(UITableViewRowAnimationAutomatic)]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return 1; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 

    cell.textField.rightView = _rightView; 
    cell.textField.rightViewMode = UITextFieldViewModeAlways; 

    return cell; 
} 

@end 

App screenshot

私はバグを証明するのは非常に簡単な例を作成しました

それだけです。次に、リロードボタンを押します。無限ループが始まり、アプリケーションがハングします。私はそこ、プロパティにrightViewを格納し、各時間セルデキューtableView新しいビューを作成しない場合は、

Terminated due to memory error.

しかし:それはあまりにも多くのメモリを使用するため、いくつかの秒後、アプリがクラッシュします問題はありません。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 

    cell.textField.rightView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 24, 24)]; 
    cell.textField.rightView.backgroundColor = [UIColor greenColor]; 
    cell.textField.rightViewMode = UITextFieldViewModeAlways; 

    return cell; 
} 

しかし、私のrightView(実際のアプリで)ので、私は行が現れるたびにそれを再作成する必要はありません単純なビューではありません。

これがなぜ起こったのか誰でも知っていますか?私がrightViewを保管していないと、なぜそれは起こりませんでしたか?読んでくれてありがとう。

+0

のインスタンスを返します生地の方法を作るからそれを削除してみてください? – thorb65

+0

私は 'UITableViewCell'のサブクラスを1つ持っています。これは、アプリケーション内のあらゆる場所で使うことができ、' rightView'を1つのビューコントローラで使用するので、セルのサブクラス内に追加することはできません。 – kientux

+0

正しい方法は、アプリケーション全体で1つだけでなく、異なるUITableViewCellクラスを使用することです:-) – thorb65

答えて

0

複数のsuperviewに1つのビューを追加しようとしています。あなたはそれをすることはできません。 @property (nonatomic) UIView *rightViewには、superViewの1つしか指定できません。サブビューcell.textField.subviews

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 
    for (UIView *subview in cell.textField.subviews) { 
     if ([subview isEqual:_rightView]) { 
      [subview removeFromSuperView]; 
     } 
    } 
    cell.textField.rightView = _rightView; 
    cell.textField.rightViewMode = UITextFieldViewModeAlways; 

    return cell; 
} 

それとも、テキストフィールドのようなあなたのTableViewCell内部右のビューを作成しない理由rightView

+0

私はあなたの言うことを試みましたが、問題はまだそこにあります。そして、はい、セルが必要とするたびに新しい 'rightView'メソッドを作成しました。問題は解決しましたが、私が言ったように、私のカスタムビューは単純なビューではないので、何度も再作成したくありません。スクロール中にtableViewがちらつきます。 – kientux

+0

私はちょっと私の答えを変えました、サブビューから差分を削除しようとしました – iSashok

関連する問題