在基于视图的表视图中响应文本字段中的鼠标事件 [英] Respond to mouse events in text field in view-based table view
问题描述
我在 NSOutlineView
中的自定义视图中有文本字段.编辑其中一个单元格需要单击、暂停和再次单击.第一次单击选择表视图行,第二次单击在字段中绘制光标.双击单元格,可让您在基于单元格的表格视图中进行编辑,只会选择该行.
I have text fields inside a custom view inside an NSOutlineView
. Editing one of these cells requires a single click, a pause, and another single click. The first single click selects the table view row, and the second single click draws the cursor in the field. Double-clicking the cell, which lets you edit in a cell-based table view, only selects the row.
我想要的行为:一键更改选择和编辑.
The behavior I want: one click to change the selection and edit.
我需要覆盖什么才能获得这种行为?
What do I need to override to obtain this behavior?
我读过其他一些帖子:
NSTextField
享元模式似乎不适用于基于视图的表格视图,其中单元格视图都是从笔尖实例化的.- 我尝试将
NSTextField
子类化,例如 这个解决方案描述了,但我重写的mouseDown
方法没有被调用.覆盖了awakeFromNib
和viewWillDraw
(在 这篇文章中提到) 被调用.当然mouseDown
如果我将文本字段放在表格视图之外的某个地方就会被调用.
- The
NSTextField
flyweight pattern wouldn't seem to apply to view-based table views, where the cell views are all instantiated from nibs. - I tried subclassing
NSTextField
like this solution describes, but my overriddenmouseDown
method is not called. OverriddenawakeFromNib
andviewWillDraw
(mentioned in this post) are called. Of coursemouseDown
is called if I put the text field somewhere outside a table view.
相比之下,我的单元格视图中的 NSSegmentedControl
无需先选择行即可更改其值.
By comparison, a NSSegmentedControl
in my cell view changes its value without first selecting the row.
以下是根据已接受的回复改编的工作解决方案:
Here's the working solution adapted from the accepted response:
在大纲视图子类中:
-(void)mouseDown:(NSEvent *)theEvent {
[super mouseDown:theEvent];
// Forward the click to the row's cell view
NSPoint selfPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];
NSInteger row = [self rowAtPoint:selfPoint];
if (row>=0) [(CellViewSubclass *)[self viewAtColumn:0 row:row makeIfNecessary:NO]
mouseDownForTextFields:theEvent];
}
在表格单元格视图子类中:
In table cell view subclass:
// Respond to clicks within text fields only, because other clicks will be duplicates of events passed to mouseDown
- (void)mouseDownForTextFields:(NSEvent *)theEvent {
// If shift or command are being held, we're selecting rows, so ignore
if ((NSCommandKeyMask | NSShiftKeyMask) & [theEvent modifierFlags]) return;
NSPoint selfPoint = [self convertPoint:theEvent.locationInWindow fromView:nil];
for (NSView *subview in [self subviews])
if ([subview isKindOfClass:[NSTextField class]])
if (NSPointInRect(selfPoint, [subview frame]))
[[self window] makeFirstResponder:subview];
}
推荐答案
我会尽量返回 favor... 子类 NSOutlineView
并覆盖 -mouseDown:
像这样:
I'll try to return the favor... Subclass NSOutlineView
and override -mouseDown:
like so:
- (void)mouseDown:(NSEvent *)theEvent {
[super mouseDown:theEvent];
// Only take effect for double clicks; remove to allow for single clicks
if (theEvent.clickCount < 2) {
return;
}
// Get the row on which the user clicked
NSPoint localPoint = [self convertPoint:theEvent.locationInWindow
fromView:nil];
NSInteger row = [self rowAtPoint:localPoint];
// If the user didn't click on a row, we're done
if (row < 0) {
return;
}
// Get the view clicked on
NSTableCellView *view = [self viewAtColumn:0 row:row makeIfNecessary:NO];
// If the field can be edited, pop the editor into edit mode
if (view.textField.isEditable) {
[[view window] makeFirstResponder:view.textField];
}
}
这篇关于在基于视图的表视图中响应文本字段中的鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!