簡體   English   中英

如何最好地優化NSLayoutConstraint?

[英]How best to optimize NSLayoutConstraint?

同事,

我開發了一個自定義鍵盤。 鍵盤類型(字母,數字,特殊字符)之間的切換速度存在問題。 這是由於每次重新繪制按鈕的事實。 我將NSLayoutConstraint設置如下:

  1. 有一個類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]) 
  2. 在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 } 

我看到了2種優化變體:

  1. 第一次運行后要緩存所有NSLayoutConstraint
  2. 使用CGRectMake代替NSLayoutConstraint

您也許可以提供更多相關選項?

在此視頻中,我嘗試切換鍵盤並快速打印https://yadi.sk/i/36YxEwgtmHJVd

在影片中我覺得很快。

但是,與其建議每次都創建一次每種鍵盤類型,然后在現有鍵盤之間進行切換,不建議每次都重新創建布局約束。 關於那些不應該是內存問題的小視圖,它比一直重新創建和刪除約束要好得多。

或者,如果關鍵點數量(幾乎)保持不變,則可以更改約束的值,甚至可以動畫化關鍵點位置的變化,以獲得更好的效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM