iOS раскадровка: как работать с динамическим, плавающим контентом? - PullRequest
1 голос
/ 07 декабря 2011

Мое приложение содержит новостной раздел. Я пытаюсь создать вид в моей раскадровке, который будет показывать новости. Новости содержат заголовок, дату, изображение и текст.

Контент, подобный этому, будет легко отображать в HTML, поскольку он плавающий, но, насколько я понимаю, элементы iOS имеют фиксированный размер. Я думаю, что UILabel может подойти для заголовка и даты, UIImage для изображения и UITextView для текста. Я думаю, что все элементы должны быть внутри прокрутки. Проблема в том, что заголовок для некоторых новостей будет занимать одну строку, а для других - несколько строк.

Как я могу обработать такую ​​настройку в раскадровке? Ссылка на руководство, учебник будет в порядке.

1 Ответ

3 голосов
/ 07 декабря 2011

Есть много разных способов подойти к этому. В конечном итоге вы можете контролировать размер любого из этих элементов во время выполнения. С точки зрения UX вы, вероятно, захотите сохранить хотя бы некоторые элементы фиксированного размера (например, изображение и представление прокрутки, представляющие общий размер элемента новостей). Это оставило бы игру с относительными размерами заголовка и детализацией. Если вы хотите показать весь заголовок, вы можете использовать метод sizeWithFont (или один из его вариантов) класса NSString, чтобы вычислить, сколько места нужно использовать для заголовка, и выделить пространство из оставшегося количества для детализации. по желанию.

ОБНОВЛЕНО: Я мог бы добавить, что я задумал это как общую стратегию, не предназначенную специально для новой функциональности раскадровки iOS 5.

ОБНОВЛЕНО: Ну, нет учебника, но вот несколько общих рекомендаций (по крайней мере, о том, как я могу справиться с этим).

Я бы создал класс NewsItem, который инкапсулирует элементы, которые вы здесь описываете, подобно тому, что я выложил на примере изображения. Как вы разоблачаете NewsItem - дело вкуса; Вы можете начать с UITableView в качестве контейнера, поскольку это упростит управление коллекцией NewsItem. Я бы создал подкласс UITableViewCell как NewsItemTableViewCell и сгенерировал бы номинальный макет для NewsItem с помощью Interface Builder. Таким образом, на изображении примера новость будет соответствовать одной строке таблицы.

Основная часть, о которой вы спрашиваете, обозначена красной и синей рамками на изображении. Используя вышеупомянутый подход, я бы добавил логику в NewsItemTableViewCell для вычисления степени заголовка - это предполагает, что представление (в данном случае NewsItemTableViewCell) имеет явные знания о модели (базовые данные для новость) в виде ссылки (т. е. экземпляра класса NewsItem) содержит элементы, которые вы описали, полученные из веб-службы). Если ширина заголовка больше ширины красной рамки по умолчанию, я бы отрегулировал высоту красной рамки (увеличив ее), одновременно уменьшив высоту синей рамки. Такой подход позволяет избежать необходимости использовать дополнительную логику для разной высоты ячеек в таблице.

Альтернатива, которую я часто использую, заключается в том, чтобы класс Controller являлся посредником между представлением и моделью. Это может быть полезно, когда у вас есть требование, чтобы ваша таблица содержала различные типы ячеек; это также значительно упрощает повторное использование ячеек таблицы. В этом случае объявите базовый класс. Это может выглядеть примерно так:

@protocol GenericCellController

- (UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath;
@optional
- (void) tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath;

@end

и затем:

@interface NewsItemTableCellController : NSObject<GenericCellController> {
    NewsItem* newsitem;
}

Затем вы настраиваете коллекцию объектов контроллера ячейки таблицы. Преимущество этого заключается в том, что при реализации tableView:cellForRowAtIndexPath: в коде контроллера табличного представления вам нужно только делегировать объект контроллера ячейки в соответствующей строке. Более того, вы можете ссылаться на него, используя обозначение суперкласса; например, в гипотетическом NewsItemTableViewController классе вы можете иметь:

- (UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*) path {
    NSObject<GenericCellController>* cellController = [cellControllerArray objectAtIndexPath:indexPath.row];
    UITableViewCell* cell = [cellController tableView:tableView cellForRowAtIndexPath:indexPath];
    return cell;
}

Этот подход позволяет вам иметь любой класс, производный от NSObject, в коллекции и полиморфно использовать делегирование, чтобы производный класс обрабатывал логику рендеринга. Производный класс Controller имеет собственную реализацию tableView:cellForRowAtIndexPath: с соответствующим производным UITableViewCell подклассом, как описано выше.

Если вы решите пойти по этому пути, есть множество примеров основ табличных представлений и их контроллеров, которые вы можете использовать в качестве предисловия к реализации этих идей.

enter image description here

...