Ich bin mit einem seltsamen Fehler zum Nachladen eines UITableViewCell
enthält UITextField
mit einem benutzerdefinierten rightView
konfrontiert.Reloading Zeile enthält UITextField mit einem RightView verursacht Endlosschleife und Speicherüberlauf
habe ich ein sehr einfaches Beispiel, die Fehler zu demonstrieren:
Meine benutzerdefinierte Zelle mit einem UITextField
:
@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
My-View-Controller mit einem 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
Das ist es. Dann drücke ich den Reload-Button. Die Endlosschleife wird gestartet, die Anwendung hängt. Nach einigen Sekunden stürzt die App, weil es zu viel Speicher verwendet:
Terminated due to memory error.
Aber, wenn ich die rightView
in einer Eigenschaft nicht speichern und neue Ansicht erstellen jedes Mal tableView
dequeue der Zelle, dann gibt wird kein Problem sein.
- (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;
}
Aber mein rightView
(real app) ist keine einfache Ansicht so will ich nicht, neu zu erstellen, es jedes Mal die Zeile auftaucht.
Wer weiß, warum das passiert ist? Warum ist es nicht passiert, wenn ich die rightView
nicht aufbewahre? Danke fürs Lesen.
zurückkehren wird, warum Sie nicht die richtige Ansicht in Ihrem TableViewCell wie das Textfeld erstellen? – thorb65
Ich habe eine Unterklasse von 'UITableViewCell', die an jeder Stelle in der App zu verwenden ist, und ich verwende' rightView' nur in einem View-Controller, so dass ich es nicht innerhalb der Zellen-Unterklasse hinzufügen möchte. – kientux
Der richtige Weg ist, verschiedene UITableViewCell-Klassen zu verwenden, nicht nur eine über die ganze App :-) – thorb65