总结一下我的问题:当我有很多子视图,其宽度等于其父级的宽度,其中父级的宽度等于其父级的宽度时,会有很大的性能影响。窗口水平调整大小。
我正在从API中检索大量评论,并决定为每条评论创建一个单独的NSView
,然后在NSScrollView
内将它们全部垂直分隔。每个单独的注释都会增长到注释文本的高度,并与容器的宽度相匹配。当没有多个加载的注释时,这种方法很好,但是当注释通常超过100时,当窗口水平调整大小时会有很大的性能损失。
我创建了每条评论的观点:
var lastComment:NSView = documentView // The last view to vertically position around
for (index, comment) in commentsArray.enumerate() {
var data = comment
data["attributedString"] = attributedString
let commentView = NSCommentView(data: data)
documentView.addSubview(commentView)
let verticalSpacing = (index == 0) ? 0 : 10 // Position the first comment without any top spacing
let secondAttribute = (index == 0) ? NSLayoutAttribute.Top : NSLayoutAttribute.Bottom
let widthConstraint = NSLayoutConstraint(item: commentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: documentView, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0)
let topConstraint = NSLayoutConstraint(item: commentView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: lastComment, attribute: secondAttribute, multiplier: 1, constant: verticalSpacing)
documentView.addConstraints([widthConstraint, topConstraint])
lastComment = commentView
if index == commentsArray.count - 1{
let bottom = NSLayoutConstraint(item: commentView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: documentView, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0)
documentView.addConstraint(bottom)
}
}
NSCommentView
定义为:
class NSCommentView: NSView {
func setupFrame(){
self.wantsLayer = true
self.translatesAutoresizingMaskIntoConstraints = false
self.layer?.backgroundColor = NSColor.redColor().CGColor
// Set height of comment, fixed for testing
let heightConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 50)
self.addConstraint(heightConstraint)
}
func setupTextView(attributedString: NSAttributedString){
let textView = NSTextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.verticallyResizable = true
textView.textStorage?.setAttributedString(attributedString)
self.addSubview(textView)
let heightConstraint = NSLayoutConstraint(item: textView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 50)
textView.addConstraint(heightConstraint)
// The performance hit occurs when I set a width equal to the parent width:
let widthConstraint = NSLayoutConstraint(item: textView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Width, multiplier: 1, constant: 0)
self.addConstraint(widthConstraint)
}
convenience init(data:[String: AnyObject?]){
self.init()
setupFrame()
if data["isComment"] as! Bool {
let attributedString = data["attributedString"] as! NSAttributedString
setupTextView(attributedString)
}
}
}
正如您从代码中看到的那样,问题是指我尝试将NSTextView
的宽度设置为NSCommentView
的宽度时。如果我只是将其设置为常量,则不会出现真正的性能下降。
我的视图层次结构设置不正确,还是我忽略了导致此性能问题的某些内容?
答案 0 :(得分:2)
我同意肯,你正在重新发明表格视图(及其所有相关的优化)。有没有使用表视图或集合视图的最重要原因?
性能提升是因为在水平调整大小时,您需要重新计算每个子视图的大小!不只是那些可见的。
如果你必须这样做的话。一些优化尝试将是:
我还注意到您现在正在修复评论视图的高度。一旦启用flex,性能就会受到影响,因为视图必须实时调整两个维度,影响页面下面的所有视图。
TL; DR - 为自己省去很多麻烦。使用表格或集合视图。