Могут ли UITextFields, определенные в xib контроллера представления, использоваться в UITableViewCells? - PullRequest
0 голосов
/ 28 марта 2012

Я пытаюсь сделать что-то, что, на мой взгляд, было бы довольно простым и вполне приемлемым. За исключением, похоже, ни того, ни другого.

Я создал XIB, владельцем которого является контроллер представления. В этом XIB я создал, среди прочего, несколько UITextFields и связал их с соответствующими IBOutlets в контроллере представления. Контроллер представления также является делегатом для UITableView, который содержится в главном представлении контроллера.

В tableView: cellForRowAtIndexPath: Затем я создаю UITableViewCell, как и следовало ожидать (повторное использование идентификаторов и т. Д.). Затем я добавляю соответствующий IBOutletted UITextField (в зависимости от текущей строки) в contentView UITableViewCell (после первого вызова removeFromSuperview для UITextField).

Это прекрасно работает при начальной загрузке представления. Однако, как только я начинаю выполнять действия, которые заставляют UITableView перезагружать свои данные, с UITextFields происходят странные вещи. А именно, большинство из них начинают исчезать из таблицы, в то время как другие резко уменьшаются в ширине.

Итак, я делаю то, чего не должен делать? Как вы можете догадаться, настройка этих UITextFields в IB чрезвычайно полезна, за исключением того, что кажется, что это неправильный подход.

Фрагмент кода из таблицыПросмотр: cellForRowAtIndexPath: ниже ...

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
int row = indexPath.row;

if (indexPath.section == kSectionReg) {
    NSString *reuseIdent = @"RegCell";
    cell = [aTableView dequeueReusableCellWithIdentifier:reuseIdent];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:reuseIdent] autorelease];
    }
    cell.detailTextLabel.font = [UIFont systemFontOfSize:15];
    cell.detailTextLabel.backgroundColor = [UIColor clearColor];


    if (row == [self rowIndexForRegEmail]) {
        [regEmailText removeFromSuperview];
        [cell.contentView addSubview:regEmailText];
        cell.detailTextLabel.text = @"Email";
    } else if (row == [self rowIndexForRegPassword]) {
        [regPasswordText removeFromSuperview];
        [cell.contentView addSubview:regPasswordText];
        cell.detailTextLabel.text = @"Password";
    ... etc...
    }

    return cell;
}

Ответы [ 2 ]

1 голос
/ 28 марта 2012

Это полностью развалится.(Который, я думаю, вы уже сказали нам, что он имеет)

Я предполагаю, что вы рассматриваете это как «статическое табличное представление» - то есть когда-нибудь будет одинаковое количество ячеек с данными того же типа.

Проблема в том, что если какие-либо ячейки прокручиваются вне поля зрения, они будут использованы повторно, поскольку все они повторного использования, идентифицированные как @ "RegCell".

В стороне: вы дона't нужно удалитьFromSuperview, при добавлении в подпредставление будет хорошо воспроизводиться.

Вы хотите построить иерархию представлений только один раз.Они выглядят одинаково, но если они разные, используйте разные идентификаторы повторного использования.Если они одинаковые, постройте их только в первый раз (внутри if (cell == nil).

1 голос
/ 28 марта 2012

Я не уверен на 100%, но я думаю, что это ваша проблема:

    [regEmailText removeFromSuperview];
    [cell.contentView addSubview:regEmailText];

Управление памятью подразумевается в иерархии представлений: представления владеют (сохраняют) свои подпредставления. Когда вы удаляете представление из его суперпредставления, оно освобождается, а если его больше не удерживает, оно освобождается.

Вы делаете это каждый раз, когда табличное представление запрашивает ячейку, а не только при первом создании ячейки: при первом проходе текстовое поле все еще ссылается на что-то (1), когда вы вызываете removeFromSuperview, поэтому на следующей строке он еще есть, чтобы добавить его в ячейку. При последующих вызовах больше ничего не остается в текстовом поле; он освобождается, когда вы удаляете его из ячейки, поэтому он переходит к следующей строке, где вы добавляете его снова - поэтому он исчезает. (2)

Самое простое решение - убедиться, что текстовое поле не исчезает - вставьте его в сохраняющий / сильный ивар или свойство (или просто retain перед вами removeFromSuperview и release после addSubview: , если вы не используете ARC). Другой вариант может заключаться в использовании различных идентификаторов многоразовых ячеек для каждой ячейки, которая имеет уникальное текстовое поле.

В более общем случае вы можете рассмотреть методику Apple для статического содержимого строк . Или даже лучше: если вы используете iOS 5, вы можете создать статическую таблицу полностью в IB, используя раскадровку.


(1) (2): Точно то, что вначале ссылается на него, и почему некоторые поля изменяются в размерах, менее просто и частично зависит от того, что не показано в вашем вопросе. Я должен бежать прямо сейчас - остальная часть моего ответа должна решить вашу проблему, и я отредактирую этот ответ с деталями для дальнейшего просвещения позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...