【问题标题】:iTunes-style NSWindow subclass?iTunes 风格的 NSWindow 子类?
【发布时间】:2011-05-17 07:02:36
【问题描述】:

是否有一个开源库供 Cocoa 创建一个遵循 iTunes 风格的窗口?那就是窗口控件是垂直而不是水平布局的:

我发现它节省空间,适合不需要窗口标题的实用型应用程序。

【问题讨论】:

  • 我觉得这很烦人并且违反了 Apple 设计指南。我真希望他们不要继续这样做。它树立了一个坏榜样。

标签: cocoa macos user-interface itunes nswindow


【解决方案1】:

这个快速破解的 NSWindow 委托应该可以帮助您入门:

//VerticalTrafficLightsWindowDelegate.h

#import <Cocoa/Cocoa.h>

@interface VerticalTrafficLightsWindowDelegate : NSObject <NSWindowDelegate> {
    NSWindow *window;
}

@property (assign) IBOutlet NSWindow *window;

- (void)verticalizeButtonsForWindow:(NSWindow *)aWindow;

@end

//VerticalTrafficLightsWindowDelegate.m

#import "VerticalTrafficLightsWindowDelegate.h"

@implementation VerticalTrafficLightsWindowDelegate

@synthesize window;

- (void)awakeFromNib {
    [self verticalizeButtonsForWindow:window];
}

- (void)windowDidResize:(NSNotification *)notification {
    [self verticalizeButtonsForWindow:window];
}

- (void)verticalizeButtonsForWindow:(NSWindow *)aWindow {
    NSArray *contentSuperViews = [[[aWindow contentView] superview] subviews];

    NSView *closeButton = [contentSuperViews objectAtIndex:0];
    NSRect closeButtonFrame = [closeButton frame];

    NSView *minimizeButton = [contentSuperViews objectAtIndex:2];
    NSRect minimizeButtonFrame = [minimizeButton frame];

    NSView *zoomButton = [contentSuperViews objectAtIndex:1];
    NSRect zoomButtonFrame = [zoomButton frame];

    [minimizeButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y - 20.0, minimizeButtonFrame.size.width, minimizeButtonFrame.size.height)];
    [zoomButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y - 40.0, zoomButtonFrame.size.width, zoomButtonFrame.size.height)];
}

@end

但是我不得不说,就像 JeremyP 一样,我只能希望 Apple 不会在 OS X 中更广泛地传播它。

【讨论】:

  • 确实,我也希望如此。那些控件很丑。
  • 这确实有效,但相当难看。您还必须扩展标题栏的大小,但我怀疑 iTunes 只是使用 NSToolbar 的 Cocoa 等效项来完成它的工作。但是我们也需要小尺寸的红绿灯;)
  • 要在视觉上匹配 iTunes,您显然必须使用统一的纹理窗口。此外,如果您查看 iTunes 的窗口 UI 是如何设置的(UI 浏览器),您会发现 iTunes 根本不使用任何工具栏!无论如何,这些交通按钮不应该是工具栏的元素,恕我直言。这些是窗口的上级功能,与它的内容无关(相对于工具栏图标)。 (好吧,缩放是一种与内容相关的,但你明白这一点,不是吗?;))
【解决方案2】:

只是一个基于 @Regexident 的新 macOS 的修改版本。新 macOS UI 的视图层次结构发生了变化,因此原始版本不起作用。修改后的代码如下(适用于macOS 10.13):

- (void)verticalizeButtonsForWindow:(NSWindow *)aWindow {
    // New view hierarchy.
    NSView *titleBarContainerView = aWindow.contentView.superview.subviews[1];
    titleBarContainerView.frame = NSMakeRect(titleBarContainerView.frame.origin.x, titleBarContainerView.frame.origin.y - 60.0 + titleBarContainerView.frame.size.height, titleBarContainerView.frame.size.width, 60.0);
    NSView *titleBarView = titleBarContainerView.subviews[0];
    titleBarView.frame = NSMakeRect(0.0, 0.0, titleBarView.frame.size.width, 60.0);
    NSArray *titleBarSubviews = titleBarView.subviews;

    NSView *closeButton = [titleBarSubviews objectAtIndex:0];
    NSRect closeButtonFrame = [closeButton frame];

    NSView *minimizeButton = [titleBarSubviews objectAtIndex:2];
    NSRect minimizeButtonFrame = [minimizeButton frame];

    NSView *zoomButton = [titleBarSubviews objectAtIndex:1];
    NSRect zoomButtonFrame = [zoomButton frame];

    // Coordinate changed: add instead of minus.
    [minimizeButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y + 20.0, minimizeButtonFrame.size.width, minimizeButtonFrame.size.height)];
    [zoomButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y + 40.0, zoomButtonFrame.size.width, zoomButtonFrame.size.height)];
}

结果截图:

【讨论】:

    【解决方案3】:

    您可能必须继承 NSWindow、NSView 并自己绘制窗口和按钮。

    哦,只是想补充一点,您在进行自定义绘图时会丢失一些非常重要的细节。由于绘图是在主线程中完成的,并且您的主线程可能会忙于执行一些繁重的重要任务,从而阻塞主线程执行一段时间,用户将无法移动窗口,并且他们将鼠标悬停在动画上将不起作用.

    当然,除非您在另一个线程中实现鼠标监听事件,在那里进行绘图,锁定焦点...我的意思是 - 不要打扰,除非您真的认为这会使您的应用程序变得更好:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多