2008-10-14 1 views
22

Я пытаюсь подклассы NSCell для использования в NSTableView. Ячейка, которую я хочу создать, довольно сложна, поэтому было бы очень полезно, если бы я мог ее спроектировать в Interface Builder, а затем загрузить NSCell из наконечника.Возможно ли создание подклассов NSCell в Interface Builder?

Возможно ли это? Как мне это сделать?

+0

Теперь, когда NSTableView поддерживает NSTableCellView, я задаюсь вопросом, есть ли лучший способ поддержать выполнение всего от IB. – tofutim 2014-02-21 12:50:17

ответ

0

Я делаю это так:

/* example of a silly way to load a UITableViewCell from a standalone nib */ 

+ (CEntryTableViewCell *)cell 
{ 
// TODO -- this is really silly. 
NSArray *theObjects = [[NSBundle mainBundle] loadNibNamed:@"EntryTableViewCell" owner:self options:NULL]; 
for (id theObject in theObjects) 
    if ([theObject isKindOfClass:self]) 
     return(theObject); 
NSAssert(NO, @"Could not find object of class CEntryTableViewCell in nib"); 
return(NULL); 
} 

Однако это не очень эффективно, и если вы загружаете много данных, это может повредить вам. Конечно, вы должны использовать reuseIdentifier, который должен заставить этот код запускать только несколько раз за стол.

+1

Вопрос был о Cocoa, а не о Cocoa Touch – srgtuszy 2012-03-27 17:51:18

5

В IB запустите пустой XIB. Теперь перейдите в палитру и перетащите в UITableViewCell, дважды щелкните, чтобы открыть и отредактировать.

Включает только пользовательский UITableViewCell (нет других UIViews или других элементов верхнего уровня) - убедитесь, что это настоящий UITableViewCell в IB, или вы не можете установить идентификатор повторного использования (в отличие от литья UIView в IB как ваш пользовательский класс UITableViewCell). Затем вы можете добавить в ячейку ярлыки или что угодно, а также установить идентификатор повторного использования или установить любой индикатор раскрытия информации, который может вам понравиться.

Для использования, вы предоставляете код, как это в Tableview: cellForRow: atIndexPath: метод:

YourCustomCellClass *cell = (YourCustomCellClass *)[tableView dequeueReusableCellWithIdentifier:<IDYouSetInXIBFile>]; 
if (cell == nil) 
{ 
     NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:<YourXIBName> owner:self options:nil]; 
    id firstObject = [topLevelObjects objectAtIndex:0]; 
    if ([ firstObject isKindOfClass:[UITableViewCell class]]) 
     cell = firstObject; 
    else cell = [topLevelObjects objectAtIndex:1]; 
} 

Если у вас есть какие-либо этикетки или другие элементы управления, которые вы хотите ссылаться в коде, проволоки их в ИБ для ваш собственный класс ячеек - НЕ владелец файла, который вам никогда не нужно устанавливать с использованием вышеуказанного кода (вы можете оставить его как NSObject).

Редактировать: Я отмечаю, что вы действительно ищете ответ NSCell, но кодовый подход к использованию IB должен быть идентичным в Cocoa с кодом Cocoa Touch, который я использовал выше, поскольку loadNibNamed является стандартным вызовом Cocoa.

+0

Как-то я сделал это неправильно в первый раз, но ваши подробные инструкции (начало) сохранили этот день. Thanx! – JOM 2010-01-14 08:36:37

+6

У вас здесь неправильная ОС. Это не Cocoa Touch. – Domness 2010-11-14 13:50:03

11

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

NSCell - это не точка зрения. Хотя закладка пользовательской ячейки в IB была бы полезной, чтобы быть в состоянии сделать, я думаю, что ответ в основном «нет, это невозможно». Когда вы подклассе NSCell, вы в значительной степени просто делаете свой собственный рисунок. Существует не поддержка subcells, или параметризованная автоматическая компоновка (пружины и стойки ala NSView), что я подозреваю, что вы ищете.

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

Это, однако, вероятно, сложнее, чем писать небольшое пользовательское приложение, которое делает более или менее одно и то же. Поместите NSCell в элемент управления посередине окна и сделайте себе интерфейс для настройки параметров, которые вам интересны. Привязки могут сделать это довольно простым для позиционирования материала (т. Е. Привязать значение x к слайдеру), хотя вы будете не получить прямое управление элементами, конечно. Когда вы закончите, вы можете архивировать свою ячейку и загружать архив во время выполнения в реальном приложении, или вы можете просто выйти из свойств и установить их в коде в своем приложении.

2

Joar Wingfors написал статью за Stepwise несколько лет назад по соответствующей теме, Subviews in TableView Rows.

Основная методика - создать NSCell, который может разместить NSView. Если бы вы это сделали, вы могли бы создать подкласс NSView в Interface Builder, который вы могли бы внедрить в любом месте, где вам нужна эта конкретная ячейка.

Другая возможность, если вы можете нацелить Leopard, заключается в том, нужно ли вам использовать NSTableView или использовать NSCollectionView. Представления коллекции напрямую рассматриваются в терминах «представления элементов», а не в ячейках, поэтому они гораздо проще разрабатывать в Interface Builder.

7

Как Кен говорит, NSCells и NSViews разные, и вы можете заложить только NSView иерархий в СИБ, не NSCells (которые не имеют какой-либо явной иерархии).

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

В этом случае использование NIB будет работать, хотя это похоже на тонну хлопот. Обычно я только что заменил объект, который принимает NSCells с пользовательским, который принимает мой NSViews, но это означает, что вы можете написать собственный код обработки мыши, который очень обидчив.

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

-1

Добавить свой UITableViewCell в свой tableviewcontroller и объявить IBOutlet свойство:

@interface KuguTableViewController : UITableViewController { 
    IBOutlet UITableViewCell *customTypeCell; 
} 

@property (readonly) UITableViewCell *customTypeCell; 

... то в cellForRowAtIndexPath вы можете просто использовать ячейку и установить его повторно:

static NSString *CellIdentifier = @"CustomCell" 
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) 
     cell = customTypeCell; 
     cell.reuseIdentifier = CellIdentifier; 
+0

У вас здесь неправильная ОС. – Domness 2010-11-14 13:49:37

11

Некоторые ответы в этой теме ушли с темы, потому что они говорят о Cocoa Touch, когда исходный вопрос касался Cocoa. В этом отношении два API-интерфейса сильно отличаются друг от друга, и Cocoa Touch упрощает работу, поскольку UITableViewCell является av iew. NSCell нет, и в этом проблема

Для информации мне в последнее время пришлось сделать что-то очень похожее в NSOutlineView - это в основном то же самое, но немного сложнее, если что-либо, потому что вам приходится иметь дело с раскрытием/срывом уровней , Если вы заинтересованы в коде, я отправил об этом здесь: http://www.stevestreeting.com/2010/08/08/cocoa-tip-using-custom-table-outline-cells-designed-in-ib/

НТН

1

Я нашел несколько интересных примеров, которые я не совсем понимаю, хотя.

Последние 2 примера работы с NSTableViewDataSource и NSTableViewDelegate. Я хотел бы использовать BindingsArrayController в InterfaceBuilder для подключения других элементов пользовательского интерфейса, таких как текстовые поля.

0

1) Создание NSViewControllerTableViewCell.h

2) Создать в TableViewCell.h некоторые процедуры, такие как

-(void)setText:(NSString *)text image:(NSImage *)image 

3) В главном классе #import "TableViewCell.h"

4) В главном классе в -(NSView *)tableView:viewForTableColumn:row: write:

NSImage *img = //some image 
TableViewCell *cell = [[TableViewCell alloc] initWithWindowNibName:@"TableViewCell"]; 
cell.view.init; 
[cell setText:@"some text" image:img]; 
return cell; 

Надеюсь, что это поможет =)

0

Я хочу предложить более современный подход здесь.

Начиная с прошивкой 5, UITableView имеет метод

(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier

После того, как вы зарегистрировали свой СИБ, содержащий вашу клетку, просто использовать

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier

, чтобы получить новую клетку. Если ячейка доступна для повторного использования, она будет возвращена, в противном случае новая ячейка будет автоматически создана, и в этом случае это означает, что она загружена из файла NIB.

Смежные вопросы