我正在改变UITableViewCell的宽度,以便单元格更小,但用户仍然可以沿着tableview的边缘滚动。
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的回答
这个问题来得很愉快!我自己也完全解决了同样的问题。
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
,并将属性观察器添加到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.main.scale
}
}
1-创建自定义TableViewCell类。将以下代码粘贴到创建IBOutlets的类级别。 exerciseView是要在其中舍入的ContentView内部的视图。
@IBOutlet weak var exerciseView: UIView! {
didSet {
self.exerciseView.layer.cornerRadius = 15
self.exerciseView.layer.masksToBounds = true
}
}
didSet基本上是变量观察者。您可以在awakeFromNib函数中执行此操作以及:
self.exerciseView.layer.cornerRadius = 15
self.exerciseView.layer.masksToBounds = true
接受的答案有效,但添加额外的子视图以获得此效果几乎没有任何意义。这是有效的解决方案。
第1步:添加阴影和角半径
// do this in one of the init methods
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// add shadow on cell
backgroundColor = .clear // very important
layer.masksToBounds = false
layer.shadowOpacity = 0.23
layer.shadowRadius = 4
layer.shadowOffset = CGSize(width: 0, height: 0)
layer.shadowColor = UIColor.blackColor().CGColor
// add corner radius on `contentView`
contentView.backgroundColor = .white
contentView.layer.cornerRadius = 8
}
第二步:掩盖在willDisplay
的界限
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// this will turn on `masksToBounds` just before showing the cell
cell.contentView.layer.masksToBounds = true
}
额外奖励:平滑滚动
// if you do not set `shadowPath` you'll notice laggy scrolling
// add this in `willDisplay` method
let radius = cell.contentView.layer.cornerRadius
cell.layer.shadowPath = UIBezierPath(roundedRect: cell.bounds, cornerRadius: radius).cgPath
cell.layer.cornerRadius = 10
cell.layer.masksToBounds = true
要为单元格创建阴影和角落,您只需要一个backView。请参阅下面的示例。
你必须添加backView
并设置leading
,trailing
,top
,bottom
约束等于Content view
。把你的内容放到backView
有适当的限制,但要确保你的内容不超过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
}
不要忘记为Back View
创建IBOutlet。
结果如下:
我使用下面的代码实现了相同的功能。但是你将它放在TableViewCell子类的layoutSubviews()方法中。
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;
您可以尝试一种替代方法,在UIView
中使用UITableViewCell
。设置UITableViewCell
的背景颜色以清除颜色。现在,你可以制作圆角并在UIVIew
上添加阴影。这将显示为单元格宽度减小,用户可以沿tableView的边缘滚动。
永远不要使用UIBezierPath,bezierPathWithRect:shadowFrame等,因为它非常重,并且在视图顶部绘制一个图层,并且需要再次重新加载表视图以确保单元格以正确的方式呈现,有时甚至重新加载可能没有帮助。而是使用一个部分页眉和页脚,它根据需要具有圆形边缘,并且也在故事板内部,这将使表格视图的滚动和加载非常平滑而没有任何渲染问题(有时称为丢失单元格并出现在滚动上)
在这里参考如何设置圆角的不同整数值:Setting masked corners in Interface Builder
只需为节标题和页脚使用上述值即可。
试试这个,它对我有用。
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
它的工作没有额外的意见!
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
}