NSTextView滚动视图文本被截断求助:内容尺寸异常无法滚动
解决NSTextView设置内容后滚动视图无法正确显示全部内容的问题
我之前也碰到过一模一样的情况!当你把API返回的格式化JSON字符串设置给IB拖入的NSTextView后,外层滚动视图经常没法自动识别内容的真实尺寸,导致没法滚动查看完整内容。这主要是因为直接设置string后,textView的布局没有完全触发,滚动视图的contentSize也没同步更新。
这里有几个亲测有效的解决步骤:
- 强制触发textView的布局计算:只设置
needsLayout = true有时候不够,我们可以主动让layoutManager完成内容布局,再强制刷新视图树:strongSelf.responseTextView.layoutManager?.ensureLayout(for: strongSelf.responseTextView.textContainer!) strongSelf.responseTextView.layoutSubtreeIfNeeded() - 手动同步滚动视图的contentSize:NSTextView的
intrinsicContentSize会根据内容计算真实尺寸,我们可以把这个值直接赋值给滚动视图的contentSize:if let scrollView = strongSelf.responseTextView.enclosingScrollView { scrollView.contentSize = strongSelf.responseTextView.intrinsicContentSize } - 检查textView的关键属性:确保你的NSTextView和它的textContainer配置正确:
- 勾选NSTextView的
Vertically Resizable(需要纵向滚动时)、Horizontally Resizable(JSON有超长行需要横向滚动时) - 将textContainer的
Width Tracks TextView设为false,这样textContainer会根据内容自动调整宽度,不会被textView的固定宽度限制
- 勾选NSTextView的
修改后的完整代码如下:
selectedEndpoint.refreshHandler({ [weak self] (result) in guard let strongSelf = self else { return } switch result { case .success(let responseString): strongSelf.responses[strongSelf.selectedTab] = responseString OperationQueue.main.addOperation { strongSelf.responseTextView.string = responseString // 强制完成内容布局并刷新视图 strongSelf.responseTextView.layoutManager?.ensureLayout(for: strongSelf.responseTextView.textContainer!) strongSelf.responseTextView.layoutSubtreeIfNeeded() // 更新滚动视图的内容尺寸 if let scrollView = strongSelf.responseTextView.enclosingScrollView { scrollView.contentSize = strongSelf.responseTextView.intrinsicContentSize } } break case .failure(_): OperationQueue.main.addOperation { strongSelf.responseTextView.string = "" // 清空内容后也要同步滚动视图尺寸 if let scrollView = strongSelf.responseTextView.enclosingScrollView { scrollView.contentSize = strongSelf.responseTextView.intrinsicContentSize } } break } })
还有个小细节:如果你的JSON格式化后有很多缩进,建议给NSTextView设置合适的lineFragmentPadding(比如设为8),这样内容不会紧贴边缘,滚动体验会更舒服。
内容的提问来源于stack exchange,提问作者simonthumper
相关产品推荐
相关产品推荐

