#ios #swift #uitableview #calayer #shadow
#iOS #swift #uitableview #calayer #тень
Вопрос:
Я пытаюсь добавить тень к одной UITableViewCell. Я использую этот код в своем пользовательском подклассе cell:
override func layoutSubviews() {
super.layoutSubviews()
layer.masksToBounds = false
layer.shadowOffset = CGSize(width: 0, height: 1)
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.9
layer.shadowRadius = 10
layer.shadowPath = CGPath(rect: bounds, transform: nil)
}
Но тень обычно появляется только на нижнем / верхнем краю ячейки и меняется во время прокрутки.
Кто-нибудь может мне помочь?
Комментарии:
1. Ваш теневой путь должен находиться в пределах вашей ячейки. Вы устанавливаете
shadowRadius
значение 10, но путь тени — это ваша cell.bounds, тогда тень выходит за пределы вашей ячейки, следовательно, вы получаете такое поведение.
Ответ №1:
Вы не видите тень, потому что ячейка выше / ниже находится выше в иерархии представлений в зависимости от того, была ли она удалена из очереди до или после вашей пользовательской ячейки. Проверьте View-Hierarchy-Debugger в Xcode, чтобы определить проблему.
У вас есть несколько возможных решений, но я изложу 2 из них здесь:
- Вы можете использовать
bringSubviewToFront
в своемtableView
, чтобы убедиться, что ваша пользовательская ячейка всегда находится сверху.
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.isKind(of: MyCustomShadowCell.self) {
tableView.bringSubviewToFront(cell)
}
}
- Другим решением было бы установить
layer.zPosition
значение ячейки на что-то высокое, чтобы оно всегда было сверху. Имо, это немного халтурно, но если вы хотите попробовать :layer.zPosition = CGFloat.greatestFiniteMagnitude
.
Комментарии:
1. Большое вам спасибо :),
bringSubviewToFront
решил мою проблему. Я боролся с этим в течение нескольких часов.
Ответ №2:
layoutSubviews()
это неподходящее место для такой настройки пользовательского интерфейса. Поскольку вам нужно добавить тень только в какую-то определенную ячейку, примените или удалите ее при заполнении ячейки данными. Не забудьте удалить ненужные тени, иначе при повторном использовании ячейки тень останется.
Комментарии:
1. Я пытался добавить тень при заполнении ячейки данными, как вы говорите. Поведение было таким же. Другие ячейки имеют другой класс и идентификатор повторного использования, мне нужна тень только для этого конкретного. Я попытался очистить тень в prepareForReuse()
Ответ №3:
Ваша тень должна находиться в пределах границ вашей ячейки. Происходит то, что ваша тень фактически выходит за пределы вашей ячейки, и когда ячейка используется повторно и помещается в табличное представление, следующая ячейка покрывает вашу тень. При прокрутке вверх и вниз ячейки снова используются повторно в другом порядке, и в зависимости от этого ваша тень может появиться или нет.
Попробуйте изменить эту строку кода
layer.shadowPath = CGPath(rect: bounds, transform: nil)
к этому
layer.shadowPath = CGPath(rect: .init(x: 0,
y: 10,
width: contentView.bounds.width,
height: contentView.bounds.height - 20),
transform: nil)
Это поместит вашу тень внутри границ, но я не думаю, что это будет выглядеть так же хорошо, как мое следующее предложение.
Мое второе предложение для вас — создать другое родительское представление для хранения вложенных представлений ячеек. Затем добавьте это в качестве подвида вашей ячейки contentView
и примените тень к слою родительского представления вместо ячейки contentView
. Убедитесь, что родительский вид имеет отступ 10 сверху и снизу, и вы добьетесь того, чего хотите.