我找不到如何使用NSTextField在适当位置编辑其内容的简单示例。

就像在Finder中一样,您可以单击,并且在很短的延迟时间内该文本字段变为可编辑状态。

好像是textField,单元格和fieldEditor的某种组合?问题是我找不到最基本的示例。

我试过用几个不同的测试对NSTextField进行子类化,但是它没有用:

#import "GWTextField.h"
@implementation GWTextField
- (id) initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    return self;
}
- (void) mouseDown:(NSEvent *)theEvent {
    [super mouseDown:theEvent];
    [self.cell editWithFrame:self.frame inView:self.superview editor:[self.cell fieldEditorForView:self] delegate:self event:theEvent];
    //[self setEditable:TRUE];
    //[self setSelectable:TRUE];
    //[self selectText:nil];
    [NSTimer scheduledTimerWithTimeInterval:.3 target:self selector:@selector(edit:) userInfo:nil repeats:FALSE];
}
- (void) edit:(id) sende {
    NSLog(@"edit");
    [[NSApplication sharedApplication].mainWindow makeFirstResponder:self];
    [self selectText:nil];
}
@end


有任何想法吗?

最佳答案

这是没有NSCell的另一种解决方案-一位用户指出NSCell已过时,并将在某个时候消失。

#import <Cocoa/Cocoa.h>

@interface EditTextField : NSTextField <NSTextDelegate,NSTextViewDelegate,NSTextFieldDelegate>

@property BOOL isEditing;
@property BOOL commitChangesOnEscapeKey;
@property BOOL editAfterDelay;
@property CGFloat delay;

@end

----


#import "EditTextField.h"

@interface EditTextField ()
@property NSObject <NSTextFieldDelegate,NSTextViewDelegate> * userDelegate;
@property NSString * originalStringValue;
@property NSTimer * editTimer;
@property NSTrackingArea * editTrackingArea;
@end

@implementation EditTextField

- (id) initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    [self defaultInit];
    return self;
}

- (id) initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    [self defaultInit];
    return self;
}

- (id) init {
    self = [super init];
    [self defaultInit];
    return self;
}

- (void) defaultInit {
    self.delay = .8;
}

- (void) mouseDown:(NSEvent *) theEvent {
    if(theEvent.clickCount == 2) {
        [self startEditing];
    } else {
        [super mouseDown:theEvent];
        if(self.editAfterDelay) {
            [self startTracking];
            self.editTimer = [NSTimer scheduledTimerWithTimeInterval:.8 target:self selector:@selector(startEditing) userInfo:nil repeats:FALSE];
        }
    }
}

- (void) startTracking {
    if(!self.editTrackingArea) {
        self.editTrackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited|NSTrackingMouseMoved|NSTrackingActiveInActiveApp|NSTrackingAssumeInside|NSTrackingInVisibleRect owner:self userInfo:nil];
    }
    [self addTrackingArea:self.editTrackingArea];
}

- (void) mouseExited:(NSEvent *)theEvent {
    [self.editTimer invalidate];
    self.editTimer = nil;
}

- (void) mouseMoved:(NSEvent *) theEvent {
    [self.editTimer invalidate];
    self.editTimer = nil;
}

- (void) startEditing {
    id firstResponder = self.window.firstResponder;
    if([firstResponder isKindOfClass:[NSTextView class]]) {
        NSTextView * tv = (NSTextView *)firstResponder;
        if(tv.delegate && [tv.delegate isKindOfClass:[EditTextField class]]) {
            EditTextField * fr = (EditTextField *)tv.delegate;
            [fr stopEditingCommitChanges:FALSE clearFirstResponder:FALSE];
        }
    }
    if(self.delegate != self) {
        self.userDelegate = (NSObject <NSTextFieldDelegate,NSTextViewDelegate> *)self.delegate;
    }
    self.isEditing = TRUE;
    self.delegate = self;
    self.editable = TRUE;
    self.originalStringValue = self.stringValue;
    [self.window makeFirstResponder:self];
}

- (void) stopEditingCommitChanges:(BOOL) commitChanges clearFirstResponder:(BOOL) clearFirstResponder {
    self.editable = FALSE;
    self.isEditing = FALSE;
    self.delegate = nil;
    [self removeTrackingArea:self.editTrackingArea];
    if(!commitChanges) {
        self.stringValue = self.originalStringValue;
    }
    if(clearFirstResponder) {
        [self.window makeFirstResponder:nil];
    }
}

- (void) cancelOperation:(id) sender {
    if(self.commitChangesOnEscapeKey) {
        [self stopEditingCommitChanges:TRUE clearFirstResponder:TRUE];
    } else {
        [self stopEditingCommitChanges:FALSE clearFirstResponder:TRUE];
    }
}

- (BOOL) textView:(NSTextView *) textView doCommandBySelector:(SEL) commandSelector {
    BOOL handlesCommand = FALSE;
    NSString * selector = NSStringFromSelector(commandSelector);

    if(self.userDelegate) {

        if([self.userDelegate respondsToSelector:@selector(control:textView:doCommandBySelector:)]) {
            handlesCommand = [self.userDelegate control:self textView:textView doCommandBySelector:commandSelector];
        } else if([self.userDelegate respondsToSelector:@selector(textView:doCommandBySelector:)]) {
            handlesCommand = [self.userDelegate textView:textView doCommandBySelector:commandSelector];
        }

        if(!handlesCommand) {

            if([selector isEqualToString:@"insertNewline:"]) {
                [self stopEditingCommitChanges:TRUE clearFirstResponder:TRUE];
                handlesCommand = TRUE;
            }

            if([selector isEqualToString:@"insertTab:"]) {
                [self stopEditingCommitChanges:TRUE clearFirstResponder:FALSE];
                handlesCommand = FALSE;
            }
        }

    } else {

        if([selector isEqualToString:@"insertNewline:"]) {
            [self stopEditingCommitChanges:TRUE clearFirstResponder:TRUE];
            handlesCommand = TRUE;
        }

        if([selector isEqualToString:@"insertTab:"]) {
            [self stopEditingCommitChanges:TRUE clearFirstResponder:FALSE];
            handlesCommand = FALSE;
        }
    }

    return handlesCommand;
}

@end

关于macos - cocoa :单击和短暂延迟(例如在Finder中重命名)后,使NSTextField可编辑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23172049/

10-16 11:47