Mac 应用程序 - 将文件拖放到菜单栏应用程序中

Posted

技术标签:

【中文标题】Mac 应用程序 - 将文件拖放到菜单栏应用程序中【英文标题】:Mac app - drag and drop files into a menubar application 【发布时间】:2012-07-08 03:33:57 【问题描述】:

我对这个项目的灵感来自 Droplr 和 CloudApp mac 菜单栏应用程序。我一直在尝试实现here 解释的代码。

但是,当我实现代码时,菜单栏图像消失了。这是我创建状态项的代码:

- (id)init 
self = [super init];
if (self != nil) 
  // Install status item into the menu bar
  NSStatusItem *statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:STATUS_ITEM_VIEW_WIDTH];
  _statusItemView = [[StatusItemView alloc] initWithStatusItem:statusItem];
  _statusItemView.image = [NSImage imageNamed:@"Status"];
  _statusItemView.alternateImage = [NSImage imageNamed:@"StatusHighlighted"];
  _statusItemView.action = @selector(togglePanel:);
  StatusItemView* dragView = [[StatusItemView alloc] initWithFrame:NSMakeRect(0, 0, 24, 24)];
  [statusItem setView:dragView];
  [dragView release];

return self;

这是我的视图文件:

#import "StatusItemView.h"
@implementation StatusItemView
@synthesize statusItem = _statusItem;
@synthesize image = _image;
@synthesize alternateImage = _alternateImage;
@synthesize isHighlighted = _isHighlighted;
@synthesize action = _action;
@synthesize target = _target;
#pragma mark -
- (id)initWithStatusItem:(NSStatusItem *)statusItem 
  CGFloat itemWidth = [statusItem length];
  CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
  NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
  self = [super initWithFrame:itemRect];
  if (self != nil) 
    _statusItem = statusItem;
    _statusItem.view = self;
  
return self;


#pragma mark -
- (id)initWithFrame:(NSRect)frame 
  self = [super initWithFrame:frame];
  if (self) 
    //register for drags
    [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
  
  return self;

//we want to copy the files
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender 
  return NSDragOperationCopy;


perform the drag and log the files that are dropped
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender 
  NSPasteboard *pboard;
  NSDragOperation sourceDragMask;
  sourceDragMask = [sender draggingSourceOperationMask];
  pboard = [sender draggingPasteboard];
  if( [[pboard types] containsObject:NSFilenamesPboardType] ) 
    NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
    NSLog(@"Files: %@",files);
  
  return YES;


#pragma mark -

- (void)drawRect:(NSRect)dirtyRect 
  [self.statusItem drawStatusBarBackgroundInRect:dirtyRect withHighlight:self.isHighlighted];
  NSImage *icon = self.isHighlighted ? self.alternateImage : self.image;
  NSSize iconSize = [icon size];
  NSRect bounds = self.bounds;
  CGFloat iconX = roundf((NSWidth(bounds) - iconSize.width) / 2);
  CGFloat iconY = roundf((NSHeight(bounds) - iconSize.height) / 2);
  NSPoint iconPoint = NSMakePoint(iconX, iconY);
  [icon compositeToPoint:iconPoint operation:NSCompositeSourceOver];


#pragma mark -
#pragma mark Mouse tracking

- (void)mouseDown:(NSEvent *)theEvent 
  [NSApp sendAction:self.action to:self.target from:self];


#pragma mark -
#pragma mark Accessors
- (void)setHighlighted:(BOOL)newFlag 
  if (_isHighlighted == newFlag) return;
  _isHighlighted = newFlag;
  [self setNeedsDisplay:YES];


#pragma mark -
- (void)setImage:(NSImage *)newImage 
  if (_image != newImage) 
    _image = newImage;
    [self setNeedsDisplay:YES];
  


- (void)setAlternateImage:(NSImage *)newImage 
  if (_alternateImage != newImage) 
    _alternateImage = newImage;
    if (self.isHighlighted) 
      [self setNeedsDisplay:YES];
    
  


#pragma mark -
- (NSRect)globalRect 
  NSRect frame = [self frame];
  frame.origin = [self.window convertBaseToScreen:frame.origin];
  return frame;


@end

谢谢大家!

【问题讨论】:

【参考方案1】:

我知道这是一个老问题,但也许这可能会有所帮助:

尝试将NSStatusItem *statusItem 设置为类的@propery。如果您有 ARC,则菜单栏可能会在 init 函数完成后立即被破坏。

【讨论】:

以上是关于Mac 应用程序 - 将文件拖放到菜单栏应用程序中的主要内容,如果未能解决你的问题,请参考以下文章

WPF:将文件拖放到整个窗口中(包括标题栏和窗口边框)

[Mac]如何重现系统栏菜单中cloudapp的拖拽?

如何在 Mac OS X 上获取拖放到应用程序二进制文件中的文件列表? [关闭]

如何实现从 qt 应用程序拖放到文件系统文件夹?

在沙盒 mac 中执行拖放

我的 Mac 应用程序是不是需要应用文件访问授权密钥来支持拖放?