斯威夫特:神秘的约束出现了

时间:2017-02-13 18:50:57

标签: ios swift uicollectionview uicollectionviewcell nslayoutconstraint

我正在尝试在UICollectionView中创建一个警报列表,其中“on”警报具有图像(alarmImg)和时间标签(alarmLbl),而“off”警报具有图像和空白时间标签。我希望“关闭”报警图像居中,而“开启”报警图像有一个偏移量来说明标签。

这是cellForItemAtIndexPath中的代码,其中cell是一个出队的单元格,alarmLbls是一个警报时间的String数组。

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()
}

初始布局看起来很好,但是当我在包含“on”警报的单元格上调用reloadItemsAtIndexPaths时,我得到一个约束错误,指示正在应用“off”约束,在这种情况下“on”约束休息,图像转移到中心。但是,根据打印测试(仅用于从屏幕上重新加载的“关闭”单元格),第一个if块似乎没有被调用这些单元格,这是我设置的唯一地方这些限制。

我已经尝试了几乎所有我能想到的解决方案:

  1. 强制alarmImgYConstraintOff.active = false
  2. 通过IB设置中心约束并以编程方式将其关闭
  3. 将“on”块切换为if语句
  4. else更改为else if
  5. 将“on”约束的优先级设置为高于“off”约束的优先级,只会使所有“off”图像在重新加载时向上移动。但是出于某种原因,在第四次重新加载时,图像会移回原来的中心(正确)位置。

    关于我在这里做错了什么想法?

    编辑:关闭不需要的约束的代码

    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()
    }
    

    初始布局看起来很好,和以前一样,但是一旦我重新加载“on”单元格,我仍然会得到布局中断(除了第一次重新加载)。例如。 “on”单元的第二次重新加载中断,所有“on”和“off”单元的后续重新加载(尽管“off”单元看不到明显的差异);但是,如果我先重新加载一个“关闭”单元格,那么在重新加载“on”单元格之前不会有任何破坏。

2 个答案:

答案 0 :(得分:0)

当您设置alarmImgYConstraintOff.active = true时,您只是在已有的内容中添加第二个约束。尝试在应用新约束之前先删除不需要的约束。这应该可以解决这个问题。

答案 1 :(得分:0)

尝试保存对同一约束的引用,只需将.multiplier更改为1或0.75,就不必更改整个约束来更改它。