我曾经使用并喜欢RBSplitView,但是由于某个版本的xcode不再支持IB插件,我无法以编程方式重新实现它.
因此我回到使用NSSplitView.NSSplitView适合我需要的东西,就是NSSplitView的autoSave被打破了.所以我决定自己实施它.
我目前正在做的事情是调整NSSplitView的1个子视图的大小.
调整NSSplitView大小的正确方法是什么? - setPositionOfDivider:itIndex:应该是要走的路(没试过),但是我不知道如何获得分频器的当前位置.
- 提前致谢
我正在构建一个Mac应用程序,它只位于菜单栏中,没有停靠项,没有关键窗口,也没有主菜单(它LSUIElement位于info.plist中YES).当我第一次启动应用程序时applicationDidBecomeActive:,就像我预期的那样被调用.然而,一旦另一个应用程序获得焦点,applicationDidBecomeActive:永远不会再次调用.
这可以防止我的应用程序中的文本字段成为第一个响应者.当我第一次打开应用程序时,文本字段是可编辑的:

但是在另一个应用程序到达前台后,文本字段不可编辑:

打开菜单时,menuWillOpen:会在代理上调用NSMenu.我试过放下以下内容但没有成功:
[NSApp unhide];
[NSApp arrangeInFront:self];
[NSApp activateIgnoringOtherApps:YES];
[NSApp requestUserAttention:NSCriticalRequest];
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
[[NSRunningApplication currentApplication] unhide];
Run Code Online (Sandbox Code Playgroud)
我认为问题可能与没有任何窗户带到前面有关.我觉得我在这里抓住稻草.任何帮助将不胜感激.
我有一个大纲视图,我不想要缩进顶部的几个级别(他们有一个独特的外观反正),但我也想缩进后面的水平.我怎样才能做到这一点?
我已经尝试重写-levelForRow:并-levelForItem:从返回值中减去2,但这没有帮助.我也尝试重写-frameOfOutlineCellAtRow:从帧的宽度中减去2*indentationPerLevel,但这也没有帮助,可能是因为我没有显示透露三角形.有关如何解决此问题的任何想法?
大纲视图绑定到a NSTreeController,这使得难以展平底层数据结构,但我确实有一个大纲视图委托设置.
我有一个将文件复制到剪贴板的应用程序.以下是相关代码(参数是包含文件路径的NSStrings数组):
NSMutableArray *filesToCopy = [[NSMutableArray alloc] init];
int i;
for (i=1; i < [arguments count]; i++) {
NSString* pathToFile = [arguments objectAtIndex:i];
NSURL* fileURL = [[NSURL alloc] initFileURLWithPath:pathToFile];
[filesToCopy addObject:fileURL];
}
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
NSInteger changeCount = [pasteboard clearContents];
BOOL OK = [pasteboard writeObjects:filesToCopy];
Run Code Online (Sandbox Code Playgroud)
但是,在尝试将程序复制到剪贴板的文件粘贴到Mail中的空电子邮件时进行测试时,通常该文件显示为零字节,并且控制台上显示以下错误:
11/13/13 6:27:12.173 AM邮件[627]:无法从粘贴板获取有效的项目:[789514]:[public.file-url]的沙箱扩展名.11/13/13 6:27:12.174 AM邮件[627]:无法获得itemIdentifier(789514)的沙箱扩展.沙箱扩展的数据为NULL
然后在控制台上出现以下错误:
11/13/13 8:24:41.947 AM sandboxd [172] :( [627])邮件(627)拒绝file-read-xattr [文件的完整路径]
奇怪的是,如果我从Finder复制文件,那么每次粘贴都没有错误.换句话说,Finder以某种方式将文件复制到剪贴板,其信息与我的方式不同.为了验证这一点,我做了一个简单的AppleScript来返回剪贴板信息.将文件复制到剪贴板后返回以下内容:
{{«class furl»,115},{«class utf8»,115},{«class ut16»,232},{string,115},{Unicode text,230}}
使用Finder将同一文件复制到剪贴板后,Applescript将返回以下内容:
{{«class furl»,33},{«class icns»,795020},{«class ut16»,112},{«class utf8»,55},{«class 8BPS»,1630436},{«class BMP »,4194358},{«class TPIC»,1059291},{TIFF picture,4197954},{«class PNGf»,392648},{«class jp2»,213480},{GIF …
自动布局使用-符号指示约束应使用默认间距.有没有办法在不必明确设置度量值的情况下设置该间距的优先级?
例如,以下可视格式将在myView其superview 之间创建一个等于默认Cocoa/CocoaTouch值的前导约束.但是这种约束具有优先权required.
@"H:|-[myView]"
以下将创建具有较低优先级的前导约束,但必须指定显式度量值:
@"H:|-(10@750)-[myView]"
我希望能够为前导约束赋予优先级,但不是明确的度量.理由是1)我不想猜测Apple的价值是什么,以及2)如果Apple改变了这个价值,那么将来会证明这一点.
理想情况下,我喜欢以下内容:
@"H:|-(@750)-[myView]" 要么 @"H:|-(-@750)-[myView]"
但这两种语法都不被接受.是否有一个秘密格式字符串可以实现这一目标?
(我不认为iOS和MacOS之间有这样的差异,但如果有,我的目标是MacOS.)
我正在尝试编写一个自定义的NSMenu,它能够列出键输入并拦截必要的事件.这是为我的开源剪贴板管理器提供简单的搜索功能.
看起来这样做的唯一方法是安装一个自定义Carbon事件处理程序,它将侦听键事件并相应地处理它们,但似乎这样的自定义处理程序存在问题.
通常情况下,我可以传播下探至其他处理的事件(例如,系统的),他们应该被正常处理.这可以通过简单的回调来完成:
let eventHandlerCallback: EventHandlerUPP = { eventHandlerCallRef, eventRef, userData in
let response = CallNextEventHandler(eventHandlerCallRef, eventRef!)
print("Response \(response)")
return response
}
Run Code Online (Sandbox Code Playgroud)
此回调功能完美,并Response 0始终打印.此响应意味着事件处理正确.
但是,一旦我们在键盘事件之前发送鼠标事件,事情会变得奇怪.在这种情况下,回调失败并打印.此响应表示事件未正确处理.Response -9874
看起来事件无法在我的自定义视图下面的某个地方处理,我不知道究竟在哪里或如何克服这个问题.
为了重现,我已经将代码上传到Gist,可以将其添加到XCode playground并运行.一旦你看到弹出菜单,按某些键(最好是方向键,因为它们不会关闭菜单),然后观察Response 0在控制台中.之后,将光标移动到菜单内并按下更多箭头键.你Response -9874现在应该在控制台中看到.
是否有可靠/官方的方法来完全禁用用户与视图的交互?类似的SO问题仅建议拦截鼠标事件,但我正在寻找一个完整的解决方案,它将禁用视图及其后代中的所有交互,包括:
一旦交互被禁用,视图(及其后代)也应该立即失去键盘/鼠标焦点。
这应该与transitionFromViewController:toViewController:options:completionHandler:没有NSViewControllerTransitionAllowUserInteraction标志的情况类似,但我找不到在动画之外做到这一点的方法。
更新: 描述我正在寻找的内容的另一种方法是:视图必须完全像隐藏的一样,但仍然绘制在屏幕上。
我有以下可可形式:
struct Canvas: PreviewProvider {
static var previews: some View {
VStack {
HStack(alignment: .firstTextBaseline) {
Text("Endpoint:")
TextField("https://localhost:8080/api", text: .constant(""))
}
Divider()
HStack(alignment: .firstTextBaseline) {
Text("Path:")
TextField("/todos", text: .constant(""))
}
Spacer()
}
.padding()
.previewLayout(.fixed(width: 280, height: 200))
}
}
Run Code Online (Sandbox Code Playgroud)
该面板看起来不错,但我想右对齐“ Endpoint:”和“ Path:”标签:

所以我应用了一个自定义的水平对齐方式:
struct Canvas: PreviewProvider {
static var previews: some View {
VStack(alignment: .label) {
HStack(alignment: .firstTextBaseline) {
Text("Endpoint:").alignmentGuide(.label) { $0[.trailing] }
TextField("https://localhost:8080/api", text: .constant(""))
}
Divider()
HStack(alignment: .firstTextBaseline) {
Text("Path:").alignmentGuide(.label) { $0[.trailing] }
TextField("/todos", text: .constant(""))
}
Spacer() …Run Code Online (Sandbox Code Playgroud) 我使用自定义mouseMove事件将NSTextView光标设置为位于内容插图之外的指针。当它位于可编辑区域内时,我调用[super mouseMove]:
- (void)mouseMoved:(NSEvent*)event {
NSPoint point = [self convertPoint:event.locationInWindow fromView:nil];
if ((point.x > self.textContainerInset.width &&
point.x < self.frame.size.width - self.textContainerInset.width)
) {
[super mouseMoved:event];
} else if (point.x > 10) {
[NSCursor.arrowCursor set];
}
}
Run Code Online (Sandbox Code Playgroud)
当在文本中选择换行符(意味着行末尾的空白部分)并将鼠标悬停在所选内容上时,[super mouseMoved:event]鼠标移动的每个像素都会生成以下消息:
Appname[29357:853497] [Framework] Shared items array is empty
Appname[29357:853497] [Framework] No shared items can be accessed
Run Code Online (Sandbox Code Playgroud)
我很困惑为什么会发生这种情况,原因可能是什么?
编辑:
即使没有子类化,这似乎也会发生NSTextView。这可能是 macOS Catalina 中的一个错误。对我来说,它似乎不会造成任何其他问题。
我希望 macOS 菜单栏中有一个项目占据菜单栏的整个高度。例如,可以在 FaceTime 的 UI 中看到这一点:
在我的尝试中,我只能让该项目从菜单栏的 y 边缘延伸到 1pt:
(请注意,在带有凹口的菜单栏中,即使 FaceTime 也不会延伸到边缘,但它仍然比我的版本进一步延伸 1pt top)bottom。
我已经尝试过NSStatusItem button和 (不赞成)view来让事情正常工作。我也尝试过 SwiftUIMenuBarExtra
导致上面第二个屏幕截图的简单示例:
final class StatusItemManager: ObservableObject {
var statusButtonItem: NSStatusItem?
var statusViewItem: NSStatusItem?
/// Note that this uses deprecated APIs -- I'd prefer to stay away from these if possible
func showViewStatusItem() {
statusViewItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
guard let statusViewItem else { return }
let iconView = NSHostingView(rootView: ItemView(title: "View"))
statusViewItem.view = iconView …Run Code Online (Sandbox Code Playgroud) appkit ×10
cocoa ×8
macos ×7
objective-c ×5
swift ×2
autolayout ×1
cocoa-touch ×1
forms ×1
macos-carbon ×1
menubar ×1
nssplitview ×1
nsstatusitem ×1
nstextview ×1
swiftui ×1
uikit ×1
xcode ×1