拖动文本在NSTextView中生成2个插入点,并且无法将其删除

问题描述 投票:0回答:2

this is the error picturemy类是NSTextView的子类,它支持拖动。但是当我将文本拖到以前的位置时,会有一个粘贴的插入点。

然后我点击其他地方,正常的插入点出现在文本的末尾(这是正确的),

但是第一点并没有自动消失,即使我删除整个字符串。

NSTextView中只有3个与插入点相关的方法或属性。

@property (readonly) BOOL shouldDrawInsertionPoint;
@property (copy) NSColor *insertionPointColor;

- (void)updateInsertionPointStateAndRestartTimer:(BOOL)restartFlag;
- (void)drawInsertionPointInRect:(NSRect)rect color:(NSColor *)color turnedOn:(BOOL)flag;

第一个是readonly,我尝试了第二个,我设置了白色,拖动时和dragActionEnded后的原始颜色。我没工作。

等待你的决议。谢谢!

以下是我写的拖动代理代码。 #pragma mark - 目标操作

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender

{/ ------------------------------------------------ ------每当拖拽进入我们的放置区时调用的方法----------------------------------- --------------------- /

// Check if the pasteboard contains image data and source/user wants it copied
if ([sender draggingSourceOperationMask] & NSDragOperationCopy )
{
    //accept data as a copy operation
    return NSDragOperationCopy;
}

return NSDragOperationNone;

}

- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender

{

//check to see if we can accept the data
NSURL *fileURL=[NSURL URLFromPasteboard: [sender draggingPasteboard]];
if (fileURL == nil) {
return NO;}
NSString *filePathAndName = [[NSString alloc] initWithUTF8String:[fileURL fileSystemRepresentation]];
if (filePathAndName == nil)
{
    return NO;
}

NSString *fileExtension = [[filePathAndName pathExtension] uppercaseString];
if (fileExtension == nil)
{
    return NO;
}

if ([fileExtension isEqualToString:@"JPG"] ||
    [fileExtension isEqualToString:@"JPEG"] ||
    [fileExtension isEqualToString:@"PNG"] ||
    [fileExtension isEqualToString:@"GIF"] ||
    [fileExtension isEqualToString:@"BMP"])
{
    return YES;
}
else
{
    return NO;
}

}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender{

if ( [sender draggingSource] != self )
{

if ( [[[sender draggingPasteboard] types] containsObject:NSFilenamesPboardType] ) {
NSURL* fileURL=[NSURL URLFromPasteboard: [sender draggingPasteboard]];
        NSArray *files = [[sender draggingPasteboard] propertyListForType:NSFilenamesPboardType];
        [[NSNotificationCenter defaultCenter] postNotificationName:ZayhuSendPicToPeer object:self userInfo:@{@"filesArray":files}];
    }
}

return YES;

}

- (NSString *)preferredPasteboardTypeFromArray:(NSArray *)availableTypes restrictedToTypesFromArray:(NSArray *)allowedTypes{
if ([availableTypes containsObject:NSPasteboardTypeString])
{
    return NSPasteboardTypeString;
}
return [super preferredPasteboardTypeFromArray:availableTypes restrictedToTypesFromArray:allowedTypes];

}

objective-c macos cocoa
2个回答
0
投票

我遇到了你的问题。

我解决这个问题的方法不是将NSTextView子类化为执行所有拖放任务,而是将NSTextView放在自定义视图上,让自定义视图执行作业的主要部分。

如果我将NSTextView子类化为拖动目标,我遇到了一些其他UI问题,例如当文本视图由CALayer支持时消失插入点。

以下代码是用Swift编写的,但它仍然传达了解决方案的想法。

首先,对于文本拖放。您可以继承NSTextView并仅覆盖acceptableDragTypes

    override var acceptableDragTypes : [String] {
        return [NSStringPboardType]
    }

对于其他类型的拖放,让自定义视图处理它们。以拖动文件为例,

class MyCustomView: NSView {

    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        commonInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    func commonInit() {
        registerForDraggedTypes([NSFilenamesPboardType])
    }

    override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
        if sender.draggingSource() === self {
            return .None
        }
        return sender.draggingSourceOperationMask()
    }

    override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool {
        //add your custom logic here
        return true
    }

    override func performDragOperation(sender: NSDraggingInfo) -> Bool {
        //add your custom logic here
        return true
    }

 }  

0
投票

由于其他一些原因,我需要对NSTextView进行子类化,并且需要添加一些自定义对象拖动。我遇到了与插入点怪异相同的事情。

在我的情况下,我没有添加另一个视图来处理自定义对象逻辑,而是覆盖了performDragOperation,并且在它不是我的特定类型的情况下调用了super。这看起来很完美。

这允许以其自然方式默认处理String案例并且插入UI内容全部清除。

© www.soinside.com 2019 - 2024. All rights reserved.