#iphone #objective-c #ios #ipad #uitableview
#iPhone #objective-c #iOS #iPad #uitableview
Вопрос:
У меня есть сегментированный TableView, который загружает все данные во все ячейки всех разделов. В каждой ячейке есть текстовое поле.
Tableview не соответствует экрану iPad полностью, и я не могу получить доступ ко всем невидимым ячейкам для чтения / сохранения данных. И когда я вношу изменения в «Текстовое поле», затем прокручиваю вверх, прокручиваю вниз, все изменения исчезают.
Мне нужно загрузить все ячейки, даже невидимые один раз, чтобы иметь к ним доступ.
Извините, я только начал работать с таблицами несколько дней назад… Я думаю, что эта проблема как-то связана с ячейками многократного использования, но не уверен, как ее решить.
Прошу вашей помощи.
инициализация:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
}
UITextField *textField = (UITextField*)cell.accessoryView;
if(indexPath.section == 0)
cell.textLabel.text = [idenInfo objectAtIndex:indexPath.row];
else if (indexPath.section == 1)
cell.textLabel.text = [prodInfo objectAtIndex:indexPath.row];
else if (indexPath.section == 2)
cell.textLabel.text = [visInfo objectAtIndex:indexPath.row];
if(indexPath.section == 0)
textField.text = [idenInfoRez objectAtIndex:indexPath.row];
else if (indexPath.section == 1)
textField.text = [prodInfoRez objectAtIndex:indexPath.row];
else if (indexPath.section == 2)
textField.text = [visInfoRez objectAtIndex:indexPath.row];
textField = nil;
return cell;
}
Ответ №1:
Прежде всего: вам не обязательно загружать все ячейки, включая невидимые. В этом весь смысл шаблона UITableView и MVC: отделите ваши представления от ваших данных.
Что вам нужно будет сделать, так это обновить ваш источник данных (то есть idenInfoRez
, prodInfoRez
и vizInfoRez
в вашем случае), когда пользователь изменил значение внутри текстового поля. Итак, вам нужно будет установить свой UIViewController в качестве делегата каждого текстового поля и обновлять значения по мере ввода пользователем.
Комментарии:
1. Как я узнаю, текстовое поле какой ячейки (indexPath) вызвало событие? Значит, я действительно могу изменить соответствующий источник данных?
2. посмотрите на методы протокола UITableViewDataSource. В таблице вы найдете методы, которые необходимо реализовать, чтобы узнать, какой indexPath был изменен действием пользователя. Я бы также немного почитал. В руководстве по программированию приложений для iOS описывается шаблон проектирования MVC. Руководство по программированию контроллера табличного представления — лучшее начало для таблиц.
Ответ №2:
[UIView beginAnimations: контекст @»ShiftUp»: ноль]; [UIView setAnimationDuration:0.0001]; — (UITableViewCell *)TableView: (UITableView *)TableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { раздел NSInteger = [раздел indexPath];
static NSString *CellIdentifier = @"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
если (ячейка == ноль) {
[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = objCustCell;
cell.selectionStyle = UITableViewCellSelectionStyleNone ;
}
if (section == 0) {
switch (indexPath.row) {
case 0:{
cell.lable.text = @"Date of Birth";
cell.field.placeholder = @"Birth Name";
break;
}
case 1:{
cell.lable.text = @"Enter Your Name";
cell.field.placeholder = @"Full Name";
break;
}
default:
break;
}
}
[UIView beginAnimations:@"ShiftUp" context:nil];
[UIView setAnimationDuration:0.0001];
// [UIView beginAnimations: @"ShiftUp" context:nil];
NSLog(@"Load cellfor raw at index ");
// Configure the cell.
return cell;
}
Примечание: Анимация UIView не позволит текстовому полю удалять данные, иначе любой UIController останется прежним в своем старом состоянии!! Не фиксируйте анимацию, иначе она не будет работать!!
Ответ №3:
Что вы можете сделать, так это следующее: при редактировании измененного события каждого из TextField
сохранений значение содержится в текстовом поле в NSMutableArray
, номер которого равен количеству ячеек. т.е.
-(IBAction) EditingChanged: (id) sender
{
UITextField *txt =(UITextField*)sender;
NSString* str =[[NSString alloc] initWithString: txt.text];
//get current text string
NSInteger path =[tableView indexPathForSelectedRow].row;
// get currently selected row, this could be a bit different depending on the number of sections
[yourMutableArray insertObject: str atIndex: path];
[str release]
}
Затем вы можете заполнить TextField
значениями из NSMutableArray
в любое время, когда ячейки будут воссозданы заново, т.Е.
(UITableViewCell *) tableView: (UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath
{
...... // create the cells here and use viewTag to get the textFields
textField.text= [yourMutableArray objectAtIndex:indexPath.row];
//This may be a bit different depending on the number of sections.
}
Кроме того, обратите внимание, что было бы целесообразно инициализировать yourMutable
массив до емкости, равной количеству ячеек.
Прошу прощения, если коды неправильно отформатированы, поскольку это мой первый пост о stackoverflow — также в коде могут быть некоторые опечатки. Надеюсь, это кому-то поможет.
Ответ №4:
каждый раз, когда мы выделяем ячейку для разных данных, данные не будут перезагружать ячейку, каждый раз, когда данные переопределяют предыдущие данные, перед выделением ячейки для очистки ячейки, например, cell = nil
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=nil;
//it clear data in the cell
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
}
Ответ №5:
Вы правы, проблема в том, что ячейки будут использоваться повторно. Есть два решения проблемы, быстрое и грязное — не использовать ячейки многократного использования:
Удалите это:
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
И просто оставьте это:
UITableViewCell * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 400, 30)] ;
textField.enabled = NO;
cell.accessoryView = textField;
[textField release];
Это должно быть нормально, если у вас в tableview всего небольшое количество ячеек (примерно менее 50).
Лучшим решением было бы оставить повторное использование ячеек включенным и заполнить их текстовые поля по мере их запроса. Подход отличается от приложения к приложению, но вы в принципе никогда не должны обращаться к ячейкам напрямую и хранить данные ячейки где-то еще, например, в NSArray NSStrings. Затем вы могли бы манипулировать NSArray. Ваш метод cellForRowAtIndexPath будет выглядеть примерно так:
textField.text = [arrData objectAtIndex:indexPath.row];
Комментарии:
1. Если я удалю статическую NSString *cellIdentifier = @»Cell»; Я не смогу выполнить инициализацию с использованием вашего кода. Потому что CellIdentifiel не существует. Если я сохраню это, но удалю «если», проблема не будет решена. (У меня всего 13 ячеек)
2. Просто передайте
nil
в качестве аргумента. Пожалуйста, обратите внимание, однако, что это сделает ваше табличное представление очень неэффективным, если позже оно будет содержать значительно больше строк, чем текущие 13.3. Доступ к ячейкам по-прежнему недоступен, и данные по-прежнему перезагружаются после прокрутки.
4. Совершенно неправильный ответ. Вам необходимо правильно обновлять свою модель данных, когда пользователь вносит изменения. Когда вы это сделаете, таблица загрузится правильно.