各位同事,
我开发了一个自定义键盘。键盘类型(字母、数字、特殊字符)之间的切换速度存在问题。这是由于每次重新绘制按钮时的事实。 NSLayoutConstraint我设置如下:
有一个类KeyboardViewController。他添加到他的 KeyboardView
let left = NSLayoutConstraint(item: self.keyboardView, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1.0, constant: 0.0) let top = NSLayoutConstraint(item: self.keyboardView, attribute: .Top, relatedBy: .Equal, toItem: placeForSuggestion!, attribute: .Bottom, multiplier: 1.0, constant: 0.0) let right = NSLayoutConstraint(item: self.keyboardView, attribute: .Right, relatedBy: .Equal, toItem: self.view, attribute: .Right, multiplier: 1.0, constant: 0.0) let bottom = NSLayoutConstraint(item: self.keyboardView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1.0, constant: 0.0) let height = NSLayoutConstraint(item: self.keyboardView, attribute: .Height, relatedBy: .Equal, toItem: self.view, attribute: .Height, multiplier: 1.0, constant: 216) left.priority = 999 right.priority = 999 bottom.priority = 999 top.priority = 999 height.priority = 999 self.view.addConstraints([left, right, top, bottom, height])
在KeyboardView类中,添加按钮如下:
super.updateConstraints() if !layoutConstrained { var lastRowView: UIView? = nil for (rowIndex, keyRow) in keyRows.enumerate() { var lastKeyView: UIView? = nil for (keyIndex, key) in keyRow.enumerate() { var relativeWidth: CGFloat = 0.0; switch key.type! { case .ModeChange: relativeWidth = 0.92/8 case .KeyboardChange: relativeWidth = 0.92/8 case .Space: relativeWidth = 3.92/8 case .Return: relativeWidth = 1.84/8 default: relativeWidth = 0.0 } key.translatesAutoresizingMaskIntoConstraints = false if let lastView = lastKeyView { let left: NSLayoutConstraint! if (key.keyCap == "Z" || (key.keyCap == "backspace" && keyRow[keyIndex - 1].keyCap == "M")) { left = NSLayoutConstraint(item: key, attribute: .Left, relatedBy: .Equal, toItem: lastView, attribute: .Right, multiplier: 1.0, constant: englishMZSpace) } else { left = NSLayoutConstraint(item: key, attribute: .Left, relatedBy: .Equal, toItem: lastView, attribute: .Right, multiplier: 1.0, constant: distanceBetweenKeys) } let top = NSLayoutConstraint(item: key, attribute: .Top, relatedBy: .Equal, toItem: lastView, attribute: .Top, multiplier: 1.0, constant: 0.0) let bottom = NSLayoutConstraint(item: key, attribute: .Bottom, relatedBy: .Equal, toItem: lastView, attribute: .Bottom, multiplier: 1.0, constant: 0.0) var width: NSLayoutConstraint? if relativeWidth == 0.0 { width = NSLayoutConstraint(item: key, attribute: .Width, relatedBy: .Equal, toItem: lastView, attribute: .Width, multiplier: 1.0, constant: 0.0) } else { width = NSLayoutConstraint(item: key, attribute: .Width, relatedBy: .Equal, toItem: self, attribute: .Width, multiplier: relativeWidth, constant: 0.0) } self.addConstraints([left, top, bottom, width!]) } else { let leftEdge: NSLayoutConstraint if key.keyCap == "A" { leftEdge = NSLayoutConstraint(item: key, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1.0, constant: englishALSpace) } else { leftEdge = NSLayoutConstraint(item: key, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1.0, constant: leftRightSpace) } self.addConstraint(leftEdge) if let lastRow = lastRowView { let top = NSLayoutConstraint(item: key, attribute: .Top, relatedBy:.Equal, toItem: lastRow, attribute: .Bottom, multiplier: 1.0, constant: rowTopInset) let height = NSLayoutConstraint(item: key, attribute: .Height, relatedBy: .Equal, toItem: lastRow, attribute: .Height, multiplier: 1.0, constant: 0.0) self.addConstraints([top, height]) } else { let topEdge = NSLayoutConstraint(item: key, attribute: .Top, relatedBy:.Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: rowTopInset) self.addConstraint(topEdge) } if rowIndex == keyRows.count - 1 { let bottomEdge = NSLayoutConstraint(item: key, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: -rowBottomInset) self.addConstraint(bottomEdge) } lastRowView = key } if keyIndex == keyRow.count - 1 { let rightEdge: NSLayoutConstraint if key.keyCap == "L" { rightEdge = NSLayoutConstraint(item: key, attribute: .Right, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1.0, constant: -englishALSpace) } else { rightEdge = NSLayoutConstraint(item: key, attribute: .Right, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1.0, constant: -leftRightSpace) } self.addConstraint(rightEdge) } lastKeyView = key } } layoutConstrained = true }
我看到了两种优化变体:
- 第一次运行后缓存所有 NSLayoutConstraint
- 使用 CGRectMake 代替 NSLayoutConstraint
您可以提供更多相关选项吗?
在此视频中,我尝试切换键盘并快速打印 https://yadi.sk/i/36YxEwgtmHJVd
最佳答案
在视频中我觉得速度相当快。
但是,我建议不要每次都重新创建布局约束,而是创建每种键盘类型一次,然后在现有键盘之间切换。对于不应该是内存问题的小 View ,这比一直重新创建和删除约束要好得多。
或者,如果关键数量保持(几乎)相同,您可以只更改约束的值,甚至为关键位置的变化设置动画,以获得可能不错的效果。
关于ios - 如何最好地优化 NSLayoutConstraint?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34323926/