好的,我真的很难过这个。我想用一个复选框 NSTextFieldCell结合在一起。复选框很重要 如果鼠标击中框而不是文本,则为ON。我已经完成了 这个,或多或少,但问题是接收鼠标事件,因为 我单击一行中的一个复选框,但所有这些复选框都转到NSOnState。一世 将展示我所做的和我的各种失败尝试 让这个工作。
所以这就是我到目前为止所做的:
头:
@interface MyCheckboxCellToo : NSTextFieldCell {
NSButtonCell *_checkboxCell;
}
实现:
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView {
NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
NSLog(@"%@", NSStringFromPoint(point));
NSRect checkFrame;
NSDivideRect(cellFrame, &checkFrame, &cellFrame, cellFrame.size.height/*3 + [[_checkboxCell image] size].width*/, NSMinXEdge);
if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) {
// the checkbox, or the small region around it, was hit. so let's flip the state
NSCellStateValue checkState = ([_checkboxCell state] == NSOnState) ? NSOffState:NSOnState;
[self setState:checkState];
[_checkboxCell setState:checkState];
[controlView setNeedsDisplay:YES];
return NSCellHitTrackableArea;
}
return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];
}
我知道我可能不应该这样做:
[self setState:checkState];
[_checkboxCell setState:checkState];
[controlView setNeedsDisplay:YES];
在那里...因为结果是每个复选框都去了 NSOnState。这是因为细胞被重复使用了吗?为什么ImageAndTextCell可以在同一个tableview中拥有不同的图像?我该如何处理鼠标事件?
我试过了:
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame
ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
NSLog(@"%s %@", _cmd, theEvent);
return [_checkboxCell trackMouse:theEvent inRect:cellFrame
ofView:controlView untilMouseUp:untilMouseUp];
// return YES;
// return [super trackMouse:theEvent inRect:cellFrame
ofView:controlView untilMouseUp:untilMouseUp];
}
- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView {
NSLog(@"%s %@", _cmd, NSStringFromPoint(startPoint));
return [super startTrackingAt:startPoint inView:controlView];
}
- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint
inView:(NSView *)controlView {
NSLog(@"%s %@", _cmd, NSStringFromPoint(currentPoint));
return [super continueTracking:lastPoint at:currentPoint
inView:controlView];
}
- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint
inView:(NSView *)controlView mouseIsUp:(BOOL)flag {
NSLog(@"%s %d %@", _cmd, flag, NSStringFromPoint(stopPoint));
}
trackMouse:......被调用
但
startTrackingAt:...,continueTracking:...,和stopTracking:.... DO 当我点击“点击区域”复选框
时,不会被调用 在trackMouse中的:...我试过了
return [_checkboxCell trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
和
return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
并且似乎都没有导致复选框处理鼠标事件。
如何让单个复选框转到NSOnState?我知道我很漂亮 关闭但经过大量的文档阅读和谷歌搜索我没有 成功地解决了这个问题。
建议和评论欢迎..
好的,这里可以更多地展示对象的创建和破坏..
- (id)init {
if ((self = [super init])) {
_checkboxCell = [[NSButtonCell alloc] init];
[_checkboxCell setButtonType:NSSwitchButton];
[_checkboxCell setTitle:@""];
[_checkboxCell setTarget:self];
[_checkboxCell setImagePosition:NSImageLeft];
[_checkboxCell setControlSize:NSRegularControlSize];
}
return self;
}
- copyWithZone:(NSZone *)zone {
MyCheckboxCellToo *cell = (MyCheckboxCellToo *)[super copyWithZone:zone];
cell->_checkboxCell = [_checkboxCell copyWithZone:zone];
return cell;
}
- (void)dealloc {
[_checkboxCell release];
[super dealloc];
}
答案 0 :(得分:0)
我不能直接回答问题中处理事件的细胞部分,但我可以回答这些部分:
我知道我可能不应该这样做:
[self setState:checkState]; [_checkboxCell setState:checkState]; [controlView setNeedsDisplay:YES];
在那里...因为结果是每个中的每个复选框都转到NSOnState。这是因为细胞被重复使用了吗?
它们的重用方式与UITableView重用UITableViewCells的方式不同。
(我注意到你标记了问题“NSTableViewCell”.AppKit中不存在这样的类。)
为什么ImageAndTextCell可以在同一个tableview中拥有不同的图像?
这两个问题的答案都是一样的。
虽然UITableView每行使用一个单元格,并且屏幕上的行数与单元格一样多,但NSTableView会为每列使用单个单元格。
每个列都以NSTableColumn对象的形式存在,每个NSTableColumn只有一个单元格*。表视图将单元格的对象值设置为您为该列 - 行交集提供的任何值,然后告知单元格在其边界内的适当位置绘制。对于每一行,对于同一个单元格,它会做同样的事情。
(这里有例外,因为Apple增加了为特定行使用不同单元格的能力,并且因为它们添加了没有列并使用不同单元格的组行。但基本机制是相同的。)
对不起,我无法帮助你一路解决问题(除了我刚刚制作他们的单独栏目建议),但我希望这至少可以帮助你解决问题。< / p>
*它也有一个标题单元格,但这不算数。我正在谈论的“正好一个单元格”是它的数据单元。
答案 1 :(得分:0)
好的,这似乎可以解决我的问题,或多或少。
在hitForTestEvent中的:...
而不是
if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) {
// the checkbox, or the small region around it, was hit. so let's flip the state
NSCellStateValue checkState = ([_checkboxCell state] == NSOnState) ? NSOffState:NSOnState;
[self setState:checkState];
[_checkboxCell setState:checkState];
[controlView setNeedsDisplay:YES];
return NSCellHitTrackableArea;
}
它应该是:
if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) {
[_checkboxCell setState:![_checkboxCell state]];
return NSCellHitTrackableArea;
}
我仍然有一些问题,如果我点击某个地点的复选框点击区域,它没有注册,但或多或少有效。
答案 2 :(得分:0)
我创建了一个自定义单元类,它是NSButtonCell的子类而不是NSTextFieldCell。它在hitTestForEvent中返回0:inRect:ofView:如果复选框上没有点击。
当用户点击复选框时,在NSBrowser委托的浏览器中:setObjectValue:forItem:我得到一个NSBoolean并将我对应的“node”对象的“checked”ivar设置为等于NSBoolean。
在NSBrowser委托的浏览器中:willDisplayCell:atRow:column:方法我调用[browser itemAtIndex:]来获取我的“节点”,并使用节点的“已检查”ivar调用单元格的setState:方法。
查看“ComplexBrowser”Xcode示例项目,了解浏览器委托内容的示例代码。
无论你做什么,我都不建议继承NSBrowserCell。那对我来说是一个巨大的死胡同。
更新2011年8月30日:这在10.5中不起作用。啊。我回到原点。