Objective c NSTableView列标题中的复选框
我需要在NSTableView列标题中添加一个复选框。 我可以在上述列的所有行中添加复选框。但我需要在列标题级别。我需要执行selectall功能,但无法在表头级别添加一个复选框。任何示例代码或想法都会有所帮助 谢谢,Objective c NSTableView列标题中的复选框,objective-c,cocoa,nstableview,Objective C,Cocoa,Nstableview,我需要在NSTableView列标题中添加一个复选框。 我可以在上述列的所有行中添加复选框。但我需要在列标题级别。我需要执行selectall功能,但无法在表头级别添加一个复选框。任何示例代码或想法都会有所帮助 谢谢, Subrat创建NSButtonCell @interface CheckboxHeaderCell : NSButtonCell { NSButtonCell *cellCheckBox; NSColor *bkColor; } -(void)setTitle
Subrat创建
NSButtonCell
@interface CheckboxHeaderCell : NSButtonCell {
NSButtonCell *cellCheckBox;
NSColor *bkColor;
}
-(void)setTitle:(NSString *)title;
-(void)setBkColor:(NSColor *)color;
-(BOOL)getState;
-(void)onClick;
@end
@implementation CheckboxHeaderCell
- (id)init
{
if (self = [super init])
{
bkColor = nil;
cellCheckBox = [[ NSButtonCell alloc] init];
[cellCheckBox setTitle:@""];
[cellCheckBox setButtonType:NSSwitchButton];
[cellCheckBox setBordered:NO];
[cellCheckBox setImagePosition:NSImageRight];
[cellCheckBox setAlignment:NSLeftTextAlignment];
[cellCheckBox setObjectValue:[NSNumber numberWithInt:0]];
[cellCheckBox setControlSize:NSSmallControlSize];
[cellCheckBox setFont:[NSFont systemFontOfSize:[NSFont
smallSystemFontSize]]];
}
return self;
}
- (void)dealloc
{
[cellCheckBox release];
[bkColor release];
[super dealloc];
}
-(void)setTitle:(NSString *)title
{
[cellCheckBox setTitle:title];
}
-(void)setBkColor:(NSColor *)color
{
[color retain];
[bkColor release];
bkColor = color;
}
-(BOOL)getState
{
return [[cellCheckBox objectValue] boolValue];
}
-(void)onClick
{
BOOL state = ![[cellCheckBox objectValue] boolValue];
[cellCheckBox setObjectValue:[NSNumber numberWithBool:state]];
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
if (bkColor != nil)
[cellCheckBox setBackgroundColor:bkColor];
[cellCheckBox drawWithFrame:cellFrame inView:controlView] ;
}
@end
如何使用:
CheckboxHeaderCell *mHeaderCell = [[CheckboxHeaderCell alloc] init];
NSTableColumn *checkBoxColumn = [mOutlineView tableColumnWithIdentifier:@"state"];
[checkBoxColumn setHeaderCell:mHeaderCell];
- (void)tableView: (NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn
{
NSLog(@"didClickTableColumn");
CheckboxHeaderCell *headerCell = [tableColumn headerCell];
[headerCell onClick];
}
使用自定义的
NSCell
实例不起作用,原因很简单,协调NSHeaderCell
实例的NSTableHeaderView
将处理所有鼠标事件处理。因此,表格标题中的单元格按钮从不响应鼠标事件
解决方案是将所需的NSControl
实例添加到自定义NSTableHeaderView
。可以在IB中的表视图上设置自定义子类。控件添加到标识的表列中,如下所示:
[(BPTableHeaderView *)self.tableView.headerView addSubview:self.passwordTableHeaderButton
columnIdentifier:@"password"
alignment:NSLayoutAttributeRight];
任何NSView
实例都可以添加到列标题,但添加NSControl
实例可能是最常见的
NSTableHeaderView
子类
@interface BPTableHeaderView : NSTableHeaderView
- (void)addSubview:(NSView *)view columnIdentifier:(NSString *)identifier alignment:(NSLayoutAttribute)alignment;
@end
@interface BPTableHeaderView()
// collections
@property (strong) NSMutableDictionary<NSString *, NSDictionary *> *store;
// primitives
@property (assign, nonatomic) BOOL subviewsVisible;
@end
@implementation BPTableHeaderView
- (id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self) {
[self commonInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit
{
_subviewsVisible = YES;
_store = [NSMutableDictionary new];
}
#pragma mark -
#pragma mark Accessors
- (void)setSubviewsVisible:(BOOL)subviewsVisible
{
if (_subviewsVisible == subviewsVisible) return;
_subviewsVisible = subviewsVisible;
for (NSString *identifier in self.store.allKeys) {
NSDictionary *info = self.store[identifier];
NSView *view = info[@"view"];
view.hidden = !_subviewsVisible;
}
}
#pragma mark -
#pragma mark Drawing
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
if (self.draggedColumn != -1 || self.resizedColumn != -1) {
[self layoutSubviews];
}
}
#pragma mark -
#pragma mark View management
- (void)addSubview:(NSView *)view columnIdentifier:(NSString *)identifier alignment:(NSLayoutAttribute)alignment
{
self.store[identifier] = @{@"view" : view, @"alignment" : @(alignment)};
[self addSubview:view];
self.needsLayout = YES;
}
#pragma mark -
#pragma mark Layout
- (void)layout
{
[super layout];
[self layoutSubviews];
}
- (void)layoutSubviews
{
for (NSString *identifier in self.store.allKeys)
{
// info
NSDictionary *info = self.store[identifier];
NSView *view = info[@"view"];
NSLayoutAttribute alignment = [info[@"alignment"] integerValue];
// views and cells
NSTableColumn *column = [self.tableView tableColumnWithIdentifier:identifier];
NSTableHeaderCell *headerCell = column.headerCell;
NSInteger idx = [self.tableView.tableColumns indexOfObject:column];
if (idx == NSNotFound) continue;
// rects
NSRect headerRect = [self headerRectOfColumn:idx];
NSRect sortIndicatorRect = NSZeroRect;
if (column.sortDescriptorPrototype) {
sortIndicatorRect = [headerCell sortIndicatorRectForBounds:headerRect];
}
// position view
NSPoint viewOrigin = NSMakePoint(0, 0);
CGFloat y = (headerRect.size.height - view.frame.size.height)/2;
CGFloat xDelta = 3;
if (alignment == NSLayoutAttributeLeft) {
viewOrigin = NSMakePoint(headerRect.origin.x + xDelta, y);
}
else {
viewOrigin = NSMakePoint(headerRect.origin.x + headerRect.size.width - view.frame.size.width - sortIndicatorRect.size.width - 5, y);
}
[view setFrameOrigin:viewOrigin];
}
}
@end
@接口BPTableHeaderView:NSTableHeaderView
-(void)addSubview:(NSView*)视图列标识符:(NSString*)标识符对齐:(NSLayoutAttribute)对齐;
@结束
@接口BPTableHeaderView()
//收藏
@属性(强)NSMutableDictionary*存储;
//原语
@属性(赋值,非原子)布尔子视图可见;
@结束
@实现BPTableHeaderView
-(id)initWithFrame:(NSRect)frameRect
{
self=[super initWithFrame:frameRect];
如果(自我){
[self commonInit];
}
回归自我;
}
-(id)initWithCoder:(NSCoder*)编码器
{
self=[super initWithCoder:coder];
如果(自我){
[self commonInit];
}
回归自我;
}
-(void)commonInit
{
_子视图可视=是;
_store=[NSMutableDictionary new];
}
#布拉格标记-
#pragma标记存取器
-(void)设置子视图可见:(BOOL)子视图可见
{
if(_subviewsVisible==subviewsVisible)返回;
_子视图可视=子视图可视;
for(self.store.allkey中的NSString*标识符){
NSDictionary*info=self.store[identifier];
NSView*视图=信息[@“视图”];
view.hidden=!\u子视图可视;
}
}
#布拉格标记-
#杂注标记图
-(void)drawRect:(NSRect)dirtyRect{
[super-drawRect:dirtyRect];
if(self.draggedColumn!=-1 | | self.resizedColumn!=-1){
[自布局子视图];
}
}
#布拉格标记-
#pragma标记视图管理
-(void)addSubview:(NSView*)视图列标识符:(NSString*)标识符对齐:(NSLayoutAttribute)对齐
{
self.store[identifier]=@{@“视图”:视图,@“对齐”:@(对齐)};
[自添加子视图:视图];
self.needsLayout=是;
}
#布拉格标记-
#杂注标记布局
-(空)布局
{
[超级布局];
[自布局子视图];
}
-(无效)布局子视图
{
for(self.store.allkey中的NSString*标识符)
{
//信息
NSDictionary*info=self.store[identifier];
NSView*视图=信息[@“视图”];
NSLayoutAttribute alignment=[info[@“alignment”]integerValue];
//视图和单元格
NSTableColumn*column=[self.tableView tableColumnWithIdentifier:identifier];
NSTableHeaderCell*headerCell=column.headerCell;
NSInteger idx=[self.tableView.tableColumns索引对象:column];
如果(idx==NSNotFound)继续;
//直肠
NSRect headerRect=[self-headerRectOfColumn:idx];
NSRect sortindirectorrect=NSZeroRect;
if(column.sortDescriptorPrototype){
sortIndicatorRect=[headerCell sortIndicatorRectForBounds:headerRect];
}
//位置视图
NSPoint viewOrigin=NSMakePoint(0,0);
cgy=(headerRect.size.height-view.frame.size.height)/2;
CGFloat xDelta=3;
如果(对齐==NSLayoutAttributeLeft){
viewOrigin=NSMakePoint(headerRect.origin.x+xDelta,y);
}
否则{
viewOrigin=NSMakePoint(headerRect.origin.x+headerRect.size.width-view.frame.size.width-sortIndicatorRect.size.width-5,y);
}
[查看设置框架原点:查看原点];
}
}
@结束
它从子类化NSTableHeaderCell开始。看看这是否让您从正确的方向开始:使用新的xcode,可以直接将复选框拖动到tableview标题单元格中。xcode的版本是什么?这似乎对Xcode 5不起作用。这不起作用。有关为什么要查看我的答案的解释。@JonathanMitchell您也可以拖放表视图标题单元格中的复选框。@JonathanMitchell我面临密码保护pdf文件的问题。最后打开的文件在密码字段的背景中可见,密码字段在普通pdf文件中可见。也可在10.12.4 beta 1上重现。你能帮帮我吗?