本文是Apple Documentation Archive Window Programming Guide的学习笔记。
设置窗口集合的行为
Setting Window Collection Behavior
窗口服务器支持若干个窗口集合,比如Spaces, Exposé和“Cycle Through Windows” 。通过setCollectionBehavior:
,一个窗口可以在某种程度上决定自己在窗口集合中的行为。
对于Spaces集合(虚拟桌面),默认的行为是NSWindowCollectionBehaviorDefault
,也就是窗口只在某个Space中显示。如果把行为修改成NSWindowCollectionBehaviorCanJoinAllSpaces
,则窗口会在所有的Spaces显示。第三个选项是NSWindowCollectionBehaviorMoveToActiveSpace
,这会把窗口永远显示在激活的Space上。
isOnActiveSpace
告知窗口所在的Space是否是激活的。通过 windowNumbersWithOptions:
可以获取一组Space中和窗口相关的属性,具体的选项在NSWindowNumberListOptions
中列举。
对于Exposé集合,对于正常等级(NSNormalWindowLevel
)的窗口,其默认行为是NSWindowCollectionBehaviorManaged
,窗口会同时在Spaces和Exposé中。如果不是正常等级的窗口,默认行为是NSWindowCollectionBehaviorTransient
,不会在Exposé中显示。最后一个选项是 NSWindowCollectionBehaviorStationary
,具有这个选项的窗口不受Exposé影响。
对于“Cycle Through Windows”集合(Cmd+~),有两个选项可以控制其行为:NSWindowCollectionBehaviorParticipatesInCycle
和NSWindowCollectionBehaviorIgnoresCycle
。前一个选项使窗口参与“Cycle Through Windows”,具有后一个选项的窗口则不参与。
设置窗口大小的位置
如果窗口时一片纸,而屏幕是一个矩形平面,窗口需要决定自己在这平面上的位置。使用center
方法可以把窗口放置在屏幕的中央。可以通过setFrame:display:
或者setFrame:display:animate:
来调整窗口自身的大小和位置。前面的第二个方法会在窗口变化的过程中采用一定的动画效果,动画的持续时间可以用animationResizeTime:
获取。
用户可以通过拖曳等方式主动改变窗口大小。在用户做次操作的过程中,inLiveResize
会返回YES。如果用户想移动窗口,他可以拖动窗口的标题栏。也可以通过自定义mouseDownCanMoveWindow
来允许用户拖动标题栏以外的视图区域。如果想禁止用户拖动窗口,可以setMovable:
。isMovable
返回setMovable:
的结果。
如果使用setFrame:
去更新窗口大小,窗口的委任不会收到windowWillResize:toSize:
通知,但是可以收到windowDidResize:
通知。注意,windowDidResize:
本身不区分是用户在调整窗口大小还是程序自身在调整窗口大小。
对于文档窗口,可以通过NSWindowController
的setShouldCascadeWindows:
方法来设置文档窗口之间是否级联显示。默认是采用级联显示的,也就是说老的窗口的标题栏不会被新窗口遮蔽。对于非文档窗口,可以使用NSWindow
的cascadeTopLeftFromPoint:
来手动进行级联显示,这个方法会告知下一个窗口如何摆放才不会遮蔽当前窗口的标题栏。
zoom:
可以在程序默认的窗口大小和用户调整后的窗口大小之间切换。
setContentMinSize:
可以设置窗口内容区域的最小值,setContentMaxSize:
可以设置窗口内容区域的最大值, setContentAspectRatio:
可以限制窗口内容区域的长宽比。 setContentResizeIncrements:
可以限定窗口调整大小时候的步长(默认是1像素)。如果想直接设置窗口大小,可以使用setAspectRatio:
, setMaxSize:
等。
constrainFrameRect:toScreen:
可以给窗口设置一个屏幕区域,窗口只能在这个屏幕区域内调整大小。对于有标题栏的窗口,默认的可调整大小的区域在整个屏幕之内,不会超出屏幕范围。
保存窗口的位置信息
Saving a Window’s Position into the User’s Defaults
一个窗口的位置信息是可以存储到硬盘上用户相关的配置中的。saveFrameUsingName:
会把当前窗口的位置信息保存,setFrameUsingName:
从保存的信息中恢复窗口位置。setFrameAutosaveName:
可以自动保存当前窗口的位置信息。值得注意的是,上述操作和窗口级联有冲突,需要使用setShouldCascadeWindows:NO
来关闭窗口控制器相关的功能。removeFrameUsingName:
可以从硬盘上删除已经保存的窗口位置信息。
最小化窗口
通过miniaturize:
可以把窗口最小化到Dock,deminiaturize:
会恢复窗口。performMiniaturize:
会模拟用户最小化窗口的行为(视觉上?)。最小化后的窗口的图标可以通过setMiniwindowImage:
设置,标题可以通过setMiniwindowTitle:
设置。这些都是NSWindow的方法。
使用Window菜单
标准的Cocoa应用(macOS的GUI应用)都有带有一个Window菜单,可以用来对应用的窗口们做一些操作。通常情况下你不需要去修改此菜单的行为。
需要的话,有一些方法可以干预Window菜单的行为。setExcludedFromWindowsMenu:YES
可以避免一个窗口被列在Window菜单之下。面板类型的窗口不会出现在Window菜单下,因为它们不能成为应用的主窗口。但是NSPanel的派生类可以对面板的默认行为做一些修改,比如在isExcludedFromWindowsMenu
中返回NO,可以让此派生类在Window菜单中显示;canBecomeMainWindow
返回YES可以让此派生类成为主窗口。
此外,如果原先一个窗口不能被添加到Window菜单,随后又被修改成可以的,这个窗口可能不会自动出现在Window菜单中。可以使用addWindowsItem:title:filename:
主动添加此窗口到Window菜单,使用removeWindowsItem:
可以主动从Window菜单中移除那些已经不能被列举在Window菜单的窗口。
设置窗口的显示效果
窗口的风格是由窗口的周遭元素决定的,比如标题栏、状态栏等。这些,你的应用是无法直接访问和修改的。但是可以在窗口初始化的时候指定所需要添加的周遭元素,比如:
- NSTitledWindowMask,添加标题栏
- NSClosableWindowMask,添加关闭按键
- NSMiniaturizableWindowMask,添加最小化按键
- NSResizableWindowMask,添加窗口大小调整相关的元素
如果指定的是NSBorderlessWindowMask,那么上面的元素都不会有,你将得到一个完全空白的窗口。
如果在窗口初始化的时候禁用了某个按键,比如关闭按键,但是后来又想启用它,可以通过standardWindowButton:
来获取这个按键,然后改变它的显示状态。
NSButton *closeButton = [window standardWindowButton:NSWindowCloseButton];
[closeButton setEnabled:YES];
setOpaque
可以用来设置窗口的透光性。窗口的背景可以通过setBackgroundColor:
修改。注意,上述操作可以使窗口透明,但是窗口的标题栏不受影响,并且窗口中的那些不透光的视图也不收影响。如果想影响整个窗口,可以通过setAlphaValue:
修改。
通过setColorSpace:
可以设置窗口的颜色区域。具体参考:NSColorSpace Class Reference
.
setContentBorderThickness:forEdge:
可以设置内容边框的厚度。setAutorecalculatesContentBorderThickness:forEdge:
可以设置是否在重回窗口梯度背景的时候对边框产生影响。(OS X 10.5引进的功能)。
设置窗口的标题栏和其所代表的文件
Setting a Window’s Title and Represented File
窗口的标题可以通过setTitle:
设置成任何值。但是对于文档型的窗口,让标题栏显示当前文档对应的文件是一个不错的主意。 setTitleWithRepresentedFilename:
把一个文件路径作为窗口的标题。setRepresentedFilename:
可以修改标题栏关联的文件路径。通过 setDocumentEdited:
可以在标题栏上示意文件有改动(提示用户需要保存)。
从OS X 10.5开始,可以把标题栏和一个URL关联,setRepresentedURL:
。representedURL
可以获取关联的URL。
标题栏可以显示一个文档图标,可以通过下面的方式修改图标的内容:
[[NSWindow standardWindowButton:NSWindowDocumentIconButton] setImage:customImage].
默认情况下按住Cmd或者Control然后点击文档图标会弹出显示文件的路径。此行为受窗口代理的window:shouldPopUpDocumentPathMenu:
控制,返回NO表示禁止这个行为。此外,在窗口代理的window:shouldDragDocumentWithEvent:from:withPasteboard:
返回NO,会禁止文档图标的拖动。
(本篇完)