既然现在是2016年了,我们正在使用具有全尺寸内容视图的充满活力的标题栏,我会将自己的想法添加到某人可能实现的目标中。希望这能帮助任何来这里寻求帮助的人,因为这对我有帮助。
这回答了关于在标题栏下滚动的问题,但您可以轻松修改此技巧以使用插页和插入位置在其他事物下滚动。
为了得到一个滚动视图(有或没有的它内部的NSTextView)一个标题栏背后滚动,你可以使用:
// For transparent title.
window.titlebarAppearsTransparent = true
window.styleMask = window.styleMask | NSFullSizeContentViewWindowMask
window.appearance = NSAppearance(named: NSAppearanceNameVibrantLight)
这有效地覆盖了NSWindow的标题栏到窗口的内容查看。
要限制一些东西到窗口的顶部不知道标题栏的高度:
// Make a constraint for SOMEVIEW to the top layout guide of the window:
let topEdgeConstraint = NSLayoutConstraint(
item: SOMEVIEW, attribute: NSLayoutAttribute.Top,
relatedBy: NSLayoutRelation.Equal,
toItem: window.contentLayoutGuide,
attribute: NSLayoutAttribute.Top, multiplier: 1.0, constant: 0.0)
// Turn the constraint on automatically:
topEdgeConstraint.active = true
这可以让你的元素的顶部约束到标题栏的底部(和或工具栏+任何它可能有配件)。这表现在WWDC 2015年:https://developer.apple.com/videos/play/wwdc2014/220/
要获得滚动视图的标题栏下滚动,但显示窗口的遮掩部分内的滚动条,其固定在内容鉴于IB或通过代码的顶部,这将导致它在标题栏下。然后,告诉它自动更新它的插图:
scrollView.automaticallyAdjustsContentInsets = true
最后,你也可以继承你的窗口和处理光标/插入位置。有一个假设的错误(或我的部分开发人员错误),它不会使滚动视图始终滚动到光标/插入符号,当它超出或低于滚动视图的内容插入。
要解决此问题,您必须手动查找插入位置并在选择更改时滚动以查看它。原谅我糟糕的代码,但它似乎完成了工作。此代码属于NSWindow子类,因此self
指的是窗口。
// MARK: NSTextViewDelegate
func textViewDidChangeSelection(notification: NSNotification) {
scrollIfCaretIsObscured()
textView.needsDisplay = true // Prevents a selection rendering glitch from sticking around
}
// MARK: My Scrolling Functions
func scrollIfCaretIsObscured() {
let rect = caretRectInWindow()
let y: CGFloat = caretYPositionInWindow() - rect.height
// Todo: Make this consider the text view's ruler height, if present:
let tbHeight: CGFloat
if textView.rulerVisible {
// Ruler is shown:
tbHeight = (try! titlebarHeight()) + textViewRulerHeight
} else {
// Ruler is hidden
tbHeight = try! titlebarHeight()
}
if y <= tbHeight {
scrollToCursor()
}
}
func caretYPositionInWindow() -> CGFloat {
let caretRectInWin: NSRect = caretRectInWindow()
let caretYPosInWin: CGFloat = self.contentView!.frame.height - caretRectInWin.origin.y
return caretYPosInWin
}
func caretRectInWindow() -> CGRect {
// My own version of something based off of an old, outdated
// answer on stack overflow.
// Credit: http://stackoverflow.com/questions/6948914/nspopover-below-caret-in-nstextview
let caretRect: NSRect = textView.firstRectForCharacterRange(textView.selectedRange(), actualRange: nil)
let caretRectInWin: NSRect = self.convertRectFromScreen(caretRect)
return caretRectInWin
}
/// Scrolls to the current caret position inside the text view.
/// - Parameter textView: The specified text view to work with.
func scrollToCursor() {
let caretRectInScreenCoords = textView.firstRectForCharacterRange(textView.selectedRange(), actualRange: nil)
let caretRectInWindowCoords = self.convertRectFromScreen(caretRectInScreenCoords)
let caretRectInTextView = textView.convertRect(caretRectInWindowCoords, fromView: nil)
textView.scrollRectToVisible(caretRectInTextView)
}
enum WindowErrors: ErrorType {
case CannotFindTitlebarHeight
}
/// Calculates the combined height of the titlebar and toolbar.
/// Don't try this at home.
func titlebarHeight() throws -> CGFloat {
// Try the official way first:
if self.titlebarAccessoryViewControllers.count > 0 {
let textViewInspectorBar = self.titlebarAccessoryViewControllers[0].view
if let titlebarAccessoryClipView = textViewInspectorBar.superview {
if let view = titlebarAccessoryClipView.superview {
if let titleBarView = view.superview {
let titleBarHeight: CGFloat = titleBarView.frame.height
return titleBarHeight
}
}
}
}
throw WindowErrors.CannotFindTitlebarHeight
}
希望这有助于!
即使文档没有调整大小,我也想达到这个目的......例如,当用户输入很多滚动视图不应该剪辑其内容时。不适合滚动视图框架的文本应该出现在滚动视图边界之外。 – nacho4d 2011-04-25 09:14:51