0

我試圖在UICollectionView中創建一個警報列表,其中「on」警報具有圖像(alarmImg)和時間標籤(alarmLbl),而「關閉」警報具有圖像和空白時間標籤。我希望「關閉」警報圖像居中,而「開啓」警報圖像有一個偏移量來解釋標籤。Swift:出現神祕約束條件

這是我的代碼cellForItemAtIndexPath,其中cell是出隊單元,alarmLbls是警報時間的字符串數組。

cell.alarmLbl.text = alarmLbls[indexPath.row]  

if alarmLbls[indexPath.row] == "" { 
    cell.alarmImg.image = UIImage(named: "alarm_off") 
    let alarmImgYConstraintOff = NSLayoutConstraint(item: cell.alarmImg, attribute: .CenterY, relatedBy: .Equal, toItem: cell.mainView, attribute: .CenterY, multiplier: 1, constant: 0) 
    alarmImgYConstraintOff.active = true 
    cell.layoutIfNeeded() 
} 
else { 
    cell.alarmImg.image = UIImage(named: "alarm_on") 
    let alarmImgYConstraintOn = NSLayoutConstraint(item: cell.alarmImg, attribute: .CenterY, relatedBy: .Equal, toItem: cell.mainView, attribute: .CenterY, multiplier: 0.75, constant: 0) 
    alarmImgYConstraintOn.active = true 
    cell.layoutIfNeeded() 
} 

初始佈局看起來不錯,但是當我打電話reloadItemsAtIndexPaths上的「在」報警含有細胞,我得到指示「關」約束施加約束錯誤,在這種情況下,「上」約束休息和圖像轉移到中心。第一個if塊似乎沒有被這些單元調用,但是,根據打印測試(僅用於從屏幕外重新加載的「關閉」單元),這是我設置這些約束的唯一位置。

我已經試過幾乎每一個迭代的解決方案,我能想到的:

  1. 強制alarmImgYConstraintOff.active = false
  2. 通過IB設置一箇中心的約束,並將其關閉編程
  3. 切換「的」塊到if聲明
  4. 更改elseelse if

將「開啓」約束的優先級設置爲高於「關閉」約束的優先級時,只會使所有「關閉」圖像在重新加載時向上移位。但是,出於某種原因,在第四次重新加載時,圖像會移回原來的居中(正確)位置。

任何想法,我在做什麼錯在這裏?

編輯:用於車削不需要約束關閉

cell.alarmLbl.text = alarmLbls[indexPath.row] 

let alarmImgYConstraintOff = NSLayoutConstraint(item: cell.alarmImg, attribute: .CenterY, relatedBy: .Equal, toItem: cell.mainView, attribute: .CenterY, multiplier: 1, constant: 0) 
let alarmImgYConstraintOn = NSLayoutConstraint(item: cell.alarmImg, attribute: .CenterY, relatedBy: .Equal, toItem: cell.mainView, attribute: .CenterY, multiplier: 0.75, constant: 0)  

if alarmLbls[indexPath.row] == "" { 
    cell.alarmImg.image = UIImage(named: "alarm_off") 
    alarmImgYConstraintOn.active = false 
    alarmImgYConstraintOff.active = true 
    cell.layoutIfNeeded() 
} 
else { 
    cell.alarmImg.image = UIImage(named: "alarm_on") 
    alarmImgYConstraintOff.active = false 
    alarmImgYConstraintOn.active = true 
    cell.layoutIfNeeded() 
} 

初始佈局看起來很不錯,和以前一樣,但我還是儘快讓佈局的假期,因爲我重裝「開」細胞(除第一次重新加載)。例如。第二次重新加載「開啓」單元會中斷,隨後重新加載所有「開啓」和「關閉」單元(雖然對於「關閉」單元沒有可見的差異);然而,如果我先重新加載一個「off」單元,那麼在我重新加載一個「on」單元之前,什麼都不會中斷。

+0

當你關閉一個約束時,應該關閉另一個約束。如果你嘗試過,但沒有成功,那麼你可能沒有正確地做。你可以發佈該嘗試的代碼嗎? – dan

+0

編輯的問題包括新的代碼和結果!不幸的是,仍然沒有骰子。 – bittersweetblue

回答

0

當您設置alarmImgYConstraintOff.active = true時,您只是爲已有的內容添加第二個約束。嘗試刪除不需要的約束,然後再應用一個新約束。這應該清除問題。

+0

我已經發布了我的代碼與您的建議,但我仍然看到問題(請參閱編輯的問題)。 – bittersweetblue

+0

我最近在涉及移動視圖的應用中做了類似的事情。我通過改變約束的值來做到這一點。常數而不是添加和移除限制,並且沒有問題。也許給一個嘗試? – livtay

+0

我剛剛試過一個約束,在「off」塊中創建.constant = 0,在「on」塊中創建-10。 「On」單元格會重新加載佈局中斷,儘管圖像仍然保留在應有的位置。 「關閉」單元重新加載,並將佈局中斷移至-10位置。看起來問題在我重新加載「開啓」單元格後再次啓動。有趣的是,對於「關閉」單元中的一個(但不是全部),圖像在第四次重新加載時移回到正確位置? – bittersweetblue

0

嘗試保存對相同約束的引用,只需將.multiplier更改爲1或0.75,不必爲了更改而更改整個約束。

+0

它看起來像約束乘法器是隻讀屬性,所以你不能通過將.multiplier設置爲不同的東西來修改它們。 – bittersweetblue