实现拖动;好好放下图像

时间:2012-10-26 10:39:54

标签: objective-c macos events

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

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

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

我已阅读过这篇Mac开发者库文章:https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DragandDrop/DragandDrop.html,但我无法理解它。

如果有人能给我一个如何实现这一目标的例子,我将非常感激。

非常感谢您的期待。

3 个答案:

答案 0 :(得分:1)

在你的nib init函数中,例如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
   }
}

就是这样。

答案 1 :(得分:1)

如果您只想在井上放下图像时发生事件:

连接选定的'在出口面板上发送了动作。这会将操作发送到您的关联控制器。 selected outlet

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

- (IBAction)selector:(id)sender {

}

如果您要查找文件名

然后你需要创建一个NSImageView的子类,如in this gist

头:

#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 {

}

答案 2 :(得分: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
    } 

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

相关问题