长按按键时NSTextView触发布局约束冲突问题排查
在macOS开发中,将NSTextView嵌入NSScrollView后,正常输入文本无异常,但长按按键进行重复输入时,程序会暂停并弹出调试器警告,该问题几乎每次长按都会触发(并非100%出现)。
完整实现代码
self.suggestionTextView = NSTextView() self.suggestionTextView.isEditable = true self.suggestionTextView.font = UNIFont(name: ENAppFontFamilies.defaultFont.rawValue, size: 14) self.suggestionTextView.isVerticallyResizable = true self.suggestionTextView.maxSize = NSSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude) self.suggestionTextView.autoresizingMask = .width self.suggestionTextView.textContainer?.widthTracksTextView = true self.suggestionTextView.backgroundColor = .yellow self.suggestionTextView.textColor = NSColor.red self.suggestionTextView.string = "Why is this so complicated..." self.suggestionTextView.delegate = self let suggestionScrollView = NSTextView.scrollableTextView() // makeSuggestionViewContainer 是一个普通NSView实例 self.makeSuggestionViewContainer.addSubview(suggestionScrollView) suggestionScrollView.translatesAutoresizingMaskIntoConstraints = false // titleLabel 和 bottomLabel 是 makeSuggestionViewContainer 内的视图 // topBottomBuffer 是一个CGFloat常量 suggestionScrollView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: topBottomBuffer).isActive = true suggestionScrollView.bottomAnchor.constraint(equalTo: bottomLabel.topAnchor, constant: -topBottomBuffer).isActive = true suggestionScrollView.leadingAnchor.constraint(equalTo: self.makeSuggestionViewContainer.leadingAnchor, constant: 0).isActive = true suggestionScrollView.trailingAnchor.constraint(equalTo: self.makeSuggestionViewContainer.trailingAnchor, constant: 0).isActive = true suggestionScrollView.documentView = self.suggestionTextView suggestionScrollView.verticalScrollElasticity = .none
最简复现代码
即使简化为仅在视图控制器中添加scroll view,问题依然存在:
let suggestionScrollView = NSTextView.scrollableTextView() self.view.addSubview(suggestionScrollView) suggestionScrollView.translatesAutoresizingMaskIntoConstraints = false suggestionScrollView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10).isActive = true suggestionScrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -10).isActive = true suggestionScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 10).isActive = true suggestionScrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -10).isActive = true
调试器警告内容
Conflicting constraints detected: <decode: bad range for [%@] got [offs:398 len:810 within:0]>.
Will attempt to recover by breaking <decode: bad range for [%@] got [offs:1208 len:77 within:0]>. Unable to simultaneously satisfy constraints: (
"<NSLayoutConstraint:0x11ffb5450 _NSFunctionRowRootView:0x1283fb0e0.width == 0 (active)>",
"<NSLayoutConstraint:0x11eaa09e0 H:|-(0)-_NSTouchBarItemOverlayTouchInterceptionView:0x1283f2010 (active, names: '|':_NSFunctionRowRootView:0x1283fb0e0 )>",
"<NSLayoutConstraint:0x11ea95390 _NSTouchBarItemOverlayTouchInterceptionView:0x1283f2010.right == _NSFunctionRowRootView:0x1283fb0e0.right (active)>",
"<NSLayoutConstraint:0x1283faec0 _NSTouchBarItemOverlayTouchInterceptionView:0x1283f2010.left <= NSButton:0x1283f4e60.left (active)>",
"<NSLayoutConstraint:0x1283faf70 H:[NSButton:0x1283f4e60]-(>=0)-|(LTR) (active, names: '|':_NSTouchBarItemOverlayTouchInterceptionView:0x1283f2010 )>",
"<NSLayoutConstraint:0x1283f7840 NSButton:0x1283f4e60.width == 64 (active)> )Will attempt to recover by breaking constraint <NSLayoutConstraint:0x1283f7840 NSButton:0x1283f4e60.width == 64 (active)>
恳请帮忙排查该问题的原因。
内容的提问来源于stack exchange,提问作者Marco

