Colleagues,
I develop a custom keyboard. There was a problem with the speed of switching between types of keyboards (letters, numbers, special characters). This is due to the fact that each time the button is re-drawn. NSLayoutConstraint I set up as follows:
There is a class KeyboardViewController. He adds to his 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])
In the class KeyboardView, buttons are added as follows:
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 }
I see 2 variants of optimization:
- After the first run to cache all NSLayoutConstraint
- Use CGRectMake instead NSLayoutConstraint
You may be able to offer more relevant options?
In this video I try to switch keyboard and print quickly https://yadi.sk/i/36YxEwgtmHJVd