摘要:
使用Cocoa的内置用户界面保存机制保存/恢复NSSearchField我的状态的正确方法是什么NSViewController?
细节:
我正在开发我的第一个macOS应用程序,我的用户界面状态恢复有点麻烦.到目前为止,我已经将它工作到了我的子类中调用encodeRestorableState(with:)和restoreState(with:)方法的地步NSViewController.
我有一个NSSearchField在我的视图控制器中,我想保存/恢复搜索字段的状态,包括其文本,任何选择,光标位置,以及它当前是否处于焦点.
如果我使用以下代码,则正确保存和恢复文本:
override func encodeRestorableState(with coder: NSCoder) {
super.encodeRestorableState(with: coder)
coder.encode(searchField.stringValue, forKey: "searchText")
}
override func restoreState(with coder: NSCoder) {
super.restoreState(with: coder)
if let searchText = coder.decodeObject(forKey: "searchText") as? String {
searchField.stringValue = searchText
}
}
Run Code Online (Sandbox Code Playgroud)
显然我可以添加更多代码来保存/恢复搜索字段的选择和光标位置等.
我真正的问题是,是否有更好,更正确,更自动的方式来保存和恢复搜索字段的状态?或者我是否需要为我希望保存的搜索字段的每个属性编写自己的代码?
我试过用:
searchField.encodeRestorableState(with: coder)
Run Code Online (Sandbox Code Playgroud)
和:
searchField.restoreState(with: coder)
Run Code Online (Sandbox Code Playgroud)
在上述两种方法中,但在我的应用重新启动时,搜索字段中没有出现任何内容.
我还实施了:
override class func restorableStateKeyPaths() -> [String] {
var keys = super.restorableStateKeyPaths()
keys.append("searchField.stringValue")
return keys
}
Run Code Online (Sandbox Code Playgroud)
这里"searchField"是名 …
Presentation选项(在Attribute Inspector中)究竟在StoryBoard for Cocoa中做了什么.

它提供了两个选项供您选择
PS用Google搜索标题时,结果与powerpoint演示文稿有关
我很难用Interface Builder和NSViewController来加载视图.
我的目标是拥有一个符合以下描述的视图:顶部的顶部栏(如工具栏但不完全)跨越整个视图宽度,下面是第二个"内容视图".该复合视图由我的NSViewController子类拥有.
为此使用Interface Builder是有意义的.我创建了一个视图笔尖,并在其中添加了两个子视图,将它们正确放置(使用顶部栏和内容视图).我已经准备File's Owner好MyViewController,并连接插座等.
我希望加载的视图(条形图和内容)也在它们自己的笔尖中(这可能是让我沮丧的),并且这些笔尖将其自定义类设置为适用的相应NSView子类.我不确定要设置什么File's Owner(我猜MyController它应该是他们的主人).
唉,当我初始化一个MyViewController实际上没有我的笔尖的实例时.我已经正确地将它添加到我的Window的contentView(我已经检查过了),实际上,有些东西是加载的.也就是说,awakeFromNib会被发送到条形图,但它不会显示在窗口中.我想我肯定有一些电线穿过某处.也许有人可以帮助减轻我的一些挫败感?
编辑一些代码来显示我正在做的事情
当应用程序完成启动时,从应用程序委托中加载控制器:
MyController *controller = [[MyController alloc] initWithNibName:@"MyController" bundle:nil];
[window setContentView:[controller view]];
Run Code Online (Sandbox Code Playgroud)
然后在我的initWithNibName中,我现在不做任何事情,而是打电话给super.
我想改变我的视图的背景颜色.View Controller类是NSViewController类型.
怎么做到这一点?在iOS UIKit(UIViewController)中有self.view.backgroundColor,但NSViewController没有.
第二个问题是如何更改应用程序标题栏的颜色?我认为背景颜色不会对此产生影响.
Mac应用程序,语言Swift.XCode 6.1.
经过长时间的iPhone工作后,我回到Mac上的Cocoa开发中.我之前在Mac上使用Cocoa的经历只是一些小巧的工具.我想要建立一些严肃的东西.
查看像iPhoto(或Mail或Things或......)这样的现代Cocoa应用程序,许多应用程序使用基于单窗口,源列表的方法.我试图尽我所能地绕过那个,因为它似乎提供了一个很好的体验.但是,我有点麻烦.这是我认为应该如何看待,但我想知道其他人是如何做到的,以及最好的方法是什么:
应用程序的起点是一个AppDelegate对象,在启动后,从一个笔尖创建一个Window [Controller?],同时设置其数据(来自CoreData)
WindowController加载一个基本上只有NSSplitView的窗口.
splitview的左侧有一个NSTableView或NSOutlineView,它被设置为具有SourceList样式.
右侧具有应用程序的主要内容,具体取决于选择的表视图的哪个项目.
我会假设某处(哪里?)有NSViewControllers管理将出现在右侧的每个不同视图(想想iPhoto如何拥有所有照片,事件,面孔,地方等等,我想他们都可以出现在不同的笔尖中... 它是否正确?).
那些视图控制器可能绑定到左侧的源列表..这是如何工作的(源列表由NSViewControllers的NSArrayController支持?).
无论如何,那些是我的想法,我是完全偏离基础还是......?我环顾网络,在这里发现这篇文章,我看了一些Apple的源代码,但我似乎无法绕过它.欢迎任何指导.
architecture cocoa interface-builder cocoa-bindings nsviewcontroller
我制作了以下示例应用来说明我的问题.
左视图是占位符视图(在Interface Builder中添加).当App加载时,我添加了一个由NSViewController管理的子视图.NSViewController绘制不同颜色的矩形,每个矩形都是NSView,这些彩色视图的布局由编程创建的约束管理并添加到-loadView控制器的方法中.
右视图是NSTableView(在Interface Builder中添加).当App加载时,我使用相同的NSViewController类为表视图提供视图(仅添加一行).
当我添加子视图的占位符视图时,我还添加了两个附加约束,
[_placeholderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[CTRL_VIEW]|" options:0 metrics:nil views:views]];
[_placeholderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[CTRL_VIEW]|" options:0 metrics:nil views:views]];
Run Code Online (Sandbox Code Playgroud)
这些约束将子视图的框架设置为等于超视图的边界.一切都很好.
但是,当我使用委托方法提供NSTableView -tableView:viewForTableColumn:row:的视图时,视图尚未添加到表中.因此它没有superview,因此不能(还)将约束添加到视图中.这就是表视图中的视图与表视图单元格的边界不同的原因.
所以我的问题是如何在我提供给表视图的视图中添加约束?在表视图添加后,我可以再次访问该视图吗?这似乎有点黑客攻击.

AppDelegate.h的源代码,
#import <Cocoa/Cocoa.h>
@class BlahViewController;
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate>
@property (assign) IBOutlet NSWindow *window;
/* Left view controller and place holding view */
@property (strong) BlahViewController *viewController;
@property (weak) IBOutlet NSView *placeholderView;
/* Right view (which is an NSTableView) */
@property (weak) IBOutlet NSTableView *tableView;
@end
Run Code Online (Sandbox Code Playgroud)
和AppDelegate.m,
#import "AppDelegate.h"
#import "BlahViewController.h"
@interface …Run Code Online (Sandbox Code Playgroud) 我有一个使用XCode 7.2在Swift中开发的小型原型应用程序.该应用程序是作为带有故事板的Cocoa基于文档的应用程序创建的.因此,项目包含AppDelegate.swift,Document.swift并且Main.storyboard所有这些都与XCode生成的内容保持不变,并且ViewController.swift包含:
import Cocoa
import WebKit
class ViewController: NSViewController {
var webView: WKWebView {
return view as! WKWebView
}
override func loadView() {
view = WKWebView(/*frame: CGRect(x: 0, y: 0, width: 200, height: 200)*/)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
webView.loadHTMLString("<html><body><p>Hello, World!</p></body></html>", baseURL: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
我已覆盖loadView()直接创建a WKWebView并将其作为根视图分配给view属性ViewController,而不是加载故事板中定义的视图.
请注意,可以对该frame参数WKWebView进行评论,以证明该问题根源的不同行为.
甲WKWebView …
我很难理解和查找有关如何使NSViewController接受键和鼠标事件的信息.我在某处读到,为了在NSViewController中注册这些事件,它应该被添加到响应者链中,但我找不到如何正确执行此操作的答案.
任何形式的帮助都非常感谢!
我在QuickLook从一个表中实现功能时遇到一些问题NSView.有限的文档QuickLook确实没有任何帮助.
在阅读了Apple Docs(主要面向自定义生成器和插件)后,我最终查看了QuickLookDownloader示例代码.这段代码基于一个基于文档的应用程序,但对我来说似乎是正确的方法(毕竟它是Apple的代码,它确实在他们的项目中工作).
在我的实现中QuickLook panel,我可以让它显示得很好,我可以轻松地解雇它.但是,面板本身从不在我的内部调用委托方法NSViewController.结果我甚至都没有显示对象,只是写着"没有选择项目".我很难过.
我试着打电话给setDelegate,但如果我继续沿着那条路走下去,就会被警告即将到来的厄运......
[QL] QLError(): - [QLPreviewPanel setDelegate:]在面板没有控制器的情况下调用 - 修复此问题,否则很快就会引发此问题.请参阅QLPreviewPanel.h中的注释-acceptsPreviewPanelControl:/ - beginPreviewPanelControl:/ - endPreviewPanelControl:.
然后在尝试响应其中一个委托方法时,使用dealloc发生厄运.
是的,我确实阅读了标题,确认我应该在赢得小组后设置代表(参见下面的代码).
所以这里是我的代码,它几乎与示例代码匹配,但a)我获取数据(我从中获取NSArrayController)和b)我从中获取预览项目(我直接来自我的模型对象) - 或者无论如何)
@interface MyViewController : NSViewController
<QLPreviewPanelDataSource, QLPreviewPanelDelegate> {
QLPreviewPanel * previewPanel;
NSArrayController * myArrayController;
NSTableView * myTable;
// [...] Other instance vars
}
@implementation MyViewController
// [...] all the other methods, init, dealloc etc...
-(IBAction)togglePreviewPanel:(id)previewPanel {
if ([QLPreviewPanel sharedPreviewPanelExists] …Run Code Online (Sandbox Code Playgroud) 在我的应用程序的几个部分中,我需要一个用户可以输入密码的控件.密码字段是安全的,但我希望用户能够将字段切换为纯文本并检查拼写错误等.
密码字段本身没问题.我将NSSecureTextField子类化以获得我想要的行为.我使它可绑定,所以我可以从另一个控件(比如一个Checkbox)切换显示.

现在,我想在我的应用程序中的多个位置重用它.我可以在我需要的任何地方使用我的自定义安全文本字段旁边的复选框.但我更愿意将这些部分组合成一个可重用的组件.
所以我使用界面构建器创建一个:

现在,我如何在不同的窗口中使用它?我在窗口中添加了"自定义视图"组件,并正确设置了它的类型:

但在运行时,我只是得到一个空的空间.
1 - 大概是因为我的视图是在.xib中定义的 - 我需要在代码中做一些事情来从.xib加载我的PasswordView实例; 但究竟我需要做什么?我无法解决这个问题.
特别:
从.xib加载我的视图实例的进程/ API是什么?我很难找到关于此的文档.
一旦我加载了我的视图实例,如何将其插入到我的自定义视图'占位符'的位置?据推测,我需要一个出口到我的自定义视图,但那么呢?我只是将加载的实例分配给插座吗?我是否应该将其添加为插座的子视图?
这个逻辑应该在哪里发生?在init里面,在AwakeFromNib里面?
2 - 我知道我可以使用NSViewController作为我的自定义视图(示例),并以这种方式加载它.但我真的需要一个视图控制器吗?看来我应该能够创建独立的视图并轻松实例化它们......但也许这不是Cocoa的"方式"?在我看来,应该有一种直接的方法来组合来自多个.xibs的视图,而不需要每个子视图的控制器(可能只是一个文本字段或按钮),但我只是找不到它. ..
先感谢您.
nsviewcontroller ×10
cocoa ×8
macos ×4
swift ×3
objective-c ×2
appkit ×1
architecture ×1
autolayout ×1
background ×1
colors ×1
delegates ×1
nib ×1
nsresponder ×1
nstableview ×1
nstextfield ×1
nsview ×1
quicklook ×1
storyboard ×1
wkwebview ×1