我正在尝试为使用在NSTableView中的子类化NSCell。我想创建的单元格相当复杂,因此如果我可以在Interface Builder中设计它,然后从nib中加载NSCell,那将非常有用。
这是否可能?我该如何做到这一点?
我正在尝试为使用在NSTableView中的子类化NSCell。我想创建的单元格相当复杂,因此如果我可以在Interface Builder中设计它,然后从nib中加载NSCell,那将非常有用。
这是否可能?我该如何做到这一点?
由于一些回答谈论了Cocoa Touch,而原始问题是关于Cocoa的 - 在这方面,两个API有很大不同,Cocoa Touch使它变得容易,因为UITableViewCell是一个视图子类。NSCell不是,这就是问题所在。
顺带提一下,最近我需要在NSOutlineView中做类似的事情 - 这基本上是相同的,但如果说更难一些的话,那是因为你必须处理级别的折叠/展开。 如果您对代码感兴趣,我在这里发布了相关内容:http://www.stevestreeting.com/2010/08/08/cocoa-tip-using-custom-table-outline-cells-designed-in-ib/
希望对你有所帮助
NSCells
和NSViews
是不同的,只有在NIB中才能布局NSView
层次结构,而不是NSCells
(它们没有任何明确的层次结构)。NSViews
的层次结构,并使用它来绘制你的NSCell
- 你可以将它们添加为单元格父视图的子视图,告诉它们显示,并从窗口中删除它们,没有人会发现。NSCells
的对象,而用我的NSViews
,但这意味着编写自己的鼠标处理代码,这非常棘手。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];
}
几年前,Joar Wingfors为Stepwise撰写了一篇相关主题的文章,TableView行中的Subviews。
主要技术是创建一个可以承载NSView的NSCell。如果您这样做,那么您可以在Interface Builder中设计一个NSView子类,您可以将其嵌入到需要特定单元格的任何位置。
另一个可能性是,如果您可以针对Leopard,那么请查看是否需要使用NSTableView或者是否可以使用NSCollectionView。集合视图直接处理“项目视图”,而不是单元格,因此在Interface Builder中设计它们更加简单明了。
我找到了一些有趣的例子,但是我并不完全理解。
NSTextFieldCell
,引用了这篇文章。最后两个示例使用 NSTableViewDataSource
和 NSTableViewDelegate
。我想在 InterfaceBuilder
中使用 Bindings
和 ArrayController
来连接其他 UI 元素,如文本字段。
我偶然发现了另一个讨论,其中Abizern指出了Alex Rozanski的PXListView,看起来非常有前途!
我想在这里提供一种更现代的方法。
从iOS 5开始,UITableView有一个方法
(void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
一旦您注册了包含单元格的NIB,只需使用
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
来获取新单元格。如果有可重用的单元格,则会返回它,否则将自动创建一个新单元格,并且在这种情况下,这意味着从NIB文件中加载。
/* 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) 创建 NSViewController
TableViewCell.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;
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;