UITableViewCell: закругленные углы и тени
Я меняю ширину UITableViewCell, так что ячейка меньше, но пользователь все еще может прокручивать по краям таблицы.
override func layoutSubviews() {
// Set the width of the cell
self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width - 40, self.bounds.size.height)
super.layoutSubviews()
}
Затем я закругляю углы:
cell.layer.cornerRadius = 8
cell.layer.masksToBounds = true
Все до сих пор. Проблема возникает с тенью. Границы маскируются, поэтому тень, очевидно, не появится. Я искал другие ответы, но не могу понять, как обогнуть углы вдоль границ и показать тень.
cell.layer.shadowOffset = CGSizeMake(0, 0)
cell.layer.shadowColor = UIColor.blackColor().CGColor
cell.layer.shadowOpacity = 0.23
cell.layer.shadowRadius = 4
Итак, мой вопрос: как уменьшить ширину, по углам и одновременно добавить тень в UITableViewCell?
Обновление: Попытка ответить R Moyer
![Попытка ответа R Мойера]()
Ответы
Ответ 1
Этот вопрос приходит вовремя! Я буквально просто решил эту проблему сам.
- Создайте
UIView
(дайте ссылку на него как mainBackground
) внутри своего содержимого. Это будет содержать все содержимое вашей ячейки. Расположите его и примените необходимые ограничения в раскадровке.
- Создайте еще один
UIView
. Это будет тот, у кого есть тень (давайте обозначим его как shadowLayer
). Поместите его точно так же, как вы сделали mainBackground
, но за ним, и примените те же ограничения.
-
Теперь вы можете установить закругленные углы и тени следующим образом:
cell.mainBackground.layer.cornerRadius = 8
cell.mainBackground.layer.masksToBounds = true
cell.shadowLayer.layer.masksToBounds = false
cell.shadowLayer.layer.shadowOffset = CGSizeMake(0, 0)
cell.shadowLayer.layer.shadowColor = UIColor.blackColor().CGColor
cell.shadowLayer.layer.shadowOpacity = 0.23
cell.shadowLayer.layer.shadowRadius = 4
Однако проблема заключается в следующем: вычисление тени для каждой отдельной ячейки является медленной задачей. Вы заметите серьезную задержку при прокрутке стола. Лучший способ исправить это - определить UIBezierPath
для тени, а затем растрировать его. Поэтому вы можете сделать это:
cell.shadowLayer.layer.shadowPath = UIBezierPath(roundedRect: cell.shadowLayer.bounds, byRoundingCorners: .AllCorners, cornerRadii: CGSize(width: 8, height: 8)).CGPath
cell.shadowLayer.layer.shouldRasterize = true
cell.shadowLayer.layer.rasterizationScale = UIScreen.mainScreen().scale
Но это создает новую проблему! Форма UIBezierPath
зависит от границ shadowLayer
, но границы не установлены должным образом на время, когда вызывается cellForRowAtIndexPath
. Итак, вам нужно настроить shadowPath
на основе ограничений shadowLayer
. Лучший способ сделать это - подкласс UIView
и добавить свойство observer в свойство bounds. Затем задайте все свойства тени в didSet
. Не забудьте изменить класс вашего shadowLayer
в раскадровке, чтобы он соответствовал вашему новому подклассу.
class ShadowView: UIView {
override var bounds: CGRect {
didSet {
setupShadow()
}
}
private func setupShadow() {
self.layer.cornerRadius = 8
self.layer.shadowOffset = CGSize(width: 0, height: 3)
self.layer.shadowRadius = 3
self.layer.shadowOpacity = 0.3
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: .AllCorners, cornerRadii: CGSize(width: 8, height: 8)).CGPath
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.mainScreen().scale
}
}
Ответ 2
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true
Ответ 3
Чтобы создать тень и угол для ячейки, вам нужен только один backView. См. Мой пример ниже.
![введите описание изображения здесь]()
Вам нужно добавить backView
и установить ограничения leading
, trailing
, top
, bottom
, равные Content view
.
Поместите контент в backView
с соответствующими ограничениями, но убедитесь, что ваш контент не находится над бухтой r backView
.
После этого в коде инициализации вашей ячейки добавьте следующие строки:
override func awakeFromNib() {
super.awakeFromNib()
backgroundColor = Colors.colorClear
self.backView.layer.borderWidth = 1
self.backView.layer.cornerRadius = 3
self.backView.layer.borderColor = Colors.colorClear.cgColor
self.backView.layer.masksToBounds = true
self.layer.shadowOpacity = 0.18
self.layer.shadowOffset = CGSize(width: 0, height: 2)
self.layer.shadowRadius = 2
self.layer.shadowColor = Colors.colorBlack.cgColor
self.layer.masksToBounds = false
}
Не забудьте создать IBOutlet для Back View
.
И вот результат:
![введите описание изображения здесь]()
Ответ 4
Один альтернативный подход, который вы можете попробовать, возьмите UIView
в UITableViewCell
. Установите цвет фона UITableViewCell
, чтобы очистить цвет. Теперь вы можете сделать круглые углы и добавить тень на UIView
. Это будет выглядеть так, как если бы ширина ячейки была уменьшена, и пользователь мог прокручивать по краям таблицыView.
Ответ 5
Я получил то же самое, используя следующий код. Но вы разместили его в методе layoutSubviews() вашего подкласса TableViewCell.
self.contentView.backgroundColor = [UIColor whiteColor];
self.contentView.layer.cornerRadius = 5;
self.contentView.layer.shadowOffset = CGSizeMake(1, 0);
self.contentView.layer.shadowColor = [[UIColor blackColor] CGColor];
self.contentView.layer.shadowRadius = 5;
self.contentView.layer.shadowOpacity = .25;
CGRect shadowFrame = self.contentView.layer.bounds;
CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;
self.contentView.layer.shadowPath = shadowPath;
Ответ 6
Попробуй, это сработало для меня.
cell.contentView.layer.cornerRadius = 5.0
cell.contentView.layer.borderColor = UIColor.gray.withAlphaComponent(0.5).cgColor
cell.contentView.layer.borderWidth = 0.5
let border = CALayer()
let width = CGFloat(2.0)
border.borderColor = UIColor.darkGray.cgColor
border.frame = CGRect(x: 0, y: cell.contentView.frame.size.height - width, width: cell.contentView.frame.size.width, height: cell.contentView.frame.size.height)
border.borderWidth = width
cell.contentView.layer.addSublayer(border)
cell.contentView.layer.masksToBounds = true
cell.contentView.clipsToBounds = true
Ответ 7
Он работает без дополнительных просмотров!
override func awakeFromNib() {
super.awakeFromNib()
layer.masksToBounds = false
layer.cornerRadius = Constants.cornerRadius
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
let layer = cell.layer
layer.shadowOffset = CGSize(width: 0, height: 1)
layer.shadowRadius = 2
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOpacity = 0.2
layer.frame = cell.frame
cell.tagLabel.text = tagItems[indexPath.row].text
return cell
}