2

我是一个新手,正在开发我的第一个 Mac 应用程序,其功能的一个元素是它允许用户将图像很好地放入图像中,然后应用程序需要对放置的图像执行某些操作。

我已经很好地创建了我的图像,并使其可编辑,因此我可以将图像很好地拖放到我的图像上,并且它出现在我的应用程序中。

我遇到麻烦的地方是实现事件处理程序,以便在将图像很好地拖放到图像上时执行操作。具体来说,我需要将图像加载到 NSImage 对象中。

我已经阅读了这篇 Mac 开发人员库文章:https ://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DragandDrop/DragandDrop.html但我无法完全理解它。

如果有人能给我一个例子来说明我将如何实现这一目标,我将不胜感激。

非常感谢期待。

4

3 回答 3

1

在您的 nib 初始化函数中,例如 awakeFromNib 或 windowControllerDidLoadNib,添加一个Observer

[self.imageView addObserver:self forKeyPath:@"image" options:NSKeyValueObservingOptionNew context:nil];

并实现一个委托功能:

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context
{
   if(object == self.imageView && [keyPath isEqualToString:@"image"])
   {
      // image changed, do anything your want
   }
}

而已。

于 2014-01-09T01:41:19.767 回答
1

如果您只想在图像掉落到井上时发生事件:

连接出口面板上的“选定”发送操作。这会将操作发送到您关联的控制器。 选定的出口

如果将 imagewell 连接为控制器上的插座,则可以访问它切换到的图像。或者,您可以访问生成方法的 'sender' 参数,即 NSImageView。

- (IBAction)selector:(id)sender {

}

如果您正在寻找文件名

然后你需要像这个要点一样创建一个 NSImageView 的子类

标题:

#import <Cocoa/Cocoa.h>

@interface KSImageView : NSImageView

@end

执行:

#import "KSImageView.h"

@implementation KSImageView

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
  BOOL acceptsDrag = [super performDragOperation:sender];

    if (acceptsDrag) {
        NSPasteboard *pboard = [sender draggingPasteboard];
        NSString *plist = [pboard stringForType:NSFilenamesPboardType];

        if (plist) {

            NSArray *files = [NSPropertyListSerialization propertyListFromData:[plist dataUsingEncoding:NSUTF8StringEncoding]
                                                              mutabilityOption:NSPropertyListImmutable
                                                                        format:nil
                                                              errorDescription:nil];

            if ([files count] == 1) {
                NSDictionary *userInfo = @{@"imageFileName" : [[files objectAtIndex: 0] lastPathComponent]};

                [[NSNotificationCenter defaultCenter] postNotificationName:@"KSImageDroppedNotification"
                                                                    object:nil
                                                                  userInfo:userInfo];
            }
        }
    }

    return acceptsDrag;
}

- (void) delete:(id)sender {
}

- (void) cut:(id)sender {
}

@end

注册通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imageSelected:) name:@"KSImageDroppedNotification" object:nil];

在这里处理:

- (void)imageSelected:(NSNotification *)notification {

}
于 2015-08-23T04:44:40.973 回答
0

(这解决了上面seanmakesgames解决的问题,仅在 Swift 4.2 中更直接。)

import Cocoa

class PathImageWell: NSImageView {

    var draggedFileURL: URL? = nil

    override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        let dragSucceeded = super.performDragOperation(sender)
        if dragSucceeded == true {
            let filenameURL = NSURL(from: sender.draggingPasteboard) as URL?
            draggedFileURL = filenameURL
            return true
        }
        return false

    }
}

通过 NSURL 很重要,因为 URL 没有 init(NSPasteboard) 方法;您可以使用从 URL 中检索文件名

func imageNameFromURL(_ url: URL) -> String {
        return url.deletingPathExtension().lastPathComponent
    } 

如果要将图像名称与图像一起存储,则需要将其包装到具有“名称”属性的不同结构/类中:不要尝试使用 NSImage.name,这是严格与 NSImage 一起使用的属性(命名:) 并显示出特殊的行为。

于 2019-02-18T01:02:47.253 回答