【问题标题】:dragging text produces 2 insertion points in NSTextView, and can not remove it拖动文本在 NSTextView 中产生 2 个插入点,并且无法将其删除
【发布时间】:2016-08-31 11:35:43
【问题描述】:

这是错误图片:

我的类是 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;

第一个是只读的,我尝试了第二个,我设置了白色,拖动时设置为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];

}

【问题讨论】:

  • 我试过你的代码。我得到一个例外,并且拖放文本不起作用。修复它,插入点就可以了。
  • if (fileURL == nil) { return NO; } 对不起,我没有检查它,现在,我添加了这一行。它会工作,但问题仍然存在。
  • 拖放有效吗?
  • 可以拖动,文件类型禁止放置。

标签: objective-c macos cocoa


【解决方案1】:

我遇到了你的问题。

我解决这个问题的方法不是继承 NSTextView 来完成所有拖放任务,而是将 NSTextView 放在自定义视图上,让自定义视图完成主要工作。

如果我将 NSTextView 子类化为拖动目标,我会遇到一些其他 UI 问题,例如当 textview 由 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
    }

 }  

【讨论】:

  • 谢谢,我会试试的。
【解决方案2】:

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

在我的例子中,我没有添加另一个视图来处理自定义对象逻辑,而是覆盖了performDragOperation,并在它不是我的特定类型的情况下调用了super。这似乎工作得很好。

这允许默认以自然方式处理 String 案例,并且所有插入 UI 的东西都被清除了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    相关资源
    最近更新 更多