在基于视图的表视图中的文本字段中响应鼠标事件 [英] 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
flyweight模式似乎不适用于基于视图的表视图,其中单元格视图都是从nibs实例化。 / li>
- 我尝试子类化
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];
}
推荐答案
偏好 ...子类 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屋!