#swift #uitableview #constraints #snapkit
#swift #uitableview #ограничения #snapkit
Вопрос:
Мои ограничения нарушаются, когда я открываю VC. У меня есть табличное представление, когда я сначала нажимаю табличное представление, ограничения работают отлично, но после повторного нажатия и нажатия они нарушаются. Первое изображение работает хорошо, но во втором они сломаны, возможно, проблема в didSet, после нарушения ограничений xcode говорит удалить ширину, но пользовательский интерфейс будет плохим
Это мой код ячейки
var isIncoming: Bool! {
didSet {
bubbleBackgroundView.backgroundColor = isIncoming ? Constants.Color.inComingMessages : Constants.Color.outComingMessages
messageLabel.textColor = isIncoming ? .black : .white
if isIncoming {
bubbleBackgroundView.snp.makeConstraints { (make) in
make.leading.equalTo(16)
make.width.equalTo(180)
}
messageLabel.snp.makeConstraints { (make) in
make.leading.equalTo(16)
}
addSubview(inComingImgTail)
inComingImgTail.snp.makeConstraints { (make) in
make.trailing.equalTo(bubbleBackgroundView.snp.leading).offset(12)
make.top.equalTo(bubbleBackgroundView.snp.top).offset(1)
make.width.equalTo(15)
make.height.equalTo(36)
}
}
else if !isIncoming{
bubbleBackgroundView.snp.makeConstraints { (make) in
make.trailing.equalTo(self).offset(-16)
make.width.equalTo(180)
}
messageLabel.snp.makeConstraints { (make) in
make.leading.equalTo(16)
make.trailing.equalTo(-16)
}
addSubview(OutComingImgTail)
OutComingImgTail.snp.makeConstraints { (make) in
make.trailing.equalTo(bubbleBackgroundView.snp.trailing).offset(4)
make.top.equalTo(bubbleBackgroundView.snp.top).offset(1)
make.width.equalTo(15)
make.height.equalTo(36)
}
}
}
}
Это мой источник данных и код делегирования
extension ChatVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ChatVC.messagesList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MessagesCell.reuseIdentifier, for: indexPath) as! MessagesCell
let messages = ChatVC.messagesList[indexPath.row]
let sorted = ChatVC.messagesList.sorted { (first, second) -> Bool in
return first.pk < second.pk
}
cell.messagesLists = messages
cell.messageLabel.text = sorted[indexPath.row].text
if sorted[indexPath.row].from_user == userID {
cell.isIncoming = false
}
else if sorted[indexPath.row].from_user != userID {
cell.isIncoming = true
}
return cell
}
}
Ответ №1:
Ячейки используются повторно каждый раз, и для переключения режимов с .sent на .received необходимо деактивировать предыдущие ограничения. Добавьте два массива ограничений для обоих состояний, деактивируйте предыдущий массив и активируйте новый. В вашем случае вы просто добавляете ограничения, но не удаляете их
var receivedConstraints = [NSLayoutConstraint]()
var sentConstraints = [NSLayoutConstraint]()
...
final func changeCellMode(to mode: SNKMessage.Mode, didChangeMessageMode: (Bool) -> ()) {
if let _previousMode = previousMessageMode, _previousMode == mode {
didChangeMessageMode(false)
messageBackground.setNeedsDisplay()
return
}
didChangeMessageMode(true)
if mode == .outgoing {
NSLayoutConstraint.deactivate(receivedConstraints)
NSLayoutConstraint.activate(sentConstraints)
} else {
NSLayoutConstraint.deactivate(sentConstraints)
NSLayoutConstraint.activate(receivedConstraints)
}
messageBackground.messageMode = mode
previousMessageMode = mode
setNeedsLayout()
}
Ответ №2:
Прежде всего, я рекомендую вам использовать collectionview для такого вида представления. В этой части исходного кода вы не должны устанавливать ограничения каждый раз. Кстати, пожалуйста, посмотрите ссылку ниже. 🙂
Комментарии:
1. Я смотрел это видео, мне понравилось, что он показывает, но с TableView)