在单元格内设置视角半径的问题?

Tec*_*ain 12 cornerradius uitableview tableviewcell ios

我有一个自定义单元UITableView格.我设置它的左下角和右下角半径.我正在设置角半径cellForAtindexPath.Below是代码

  if indexPath.row == 9 {

    recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
    recipeInfoCell.layoutSubviews()
    recipeInfoCell.layoutIfNeeded()
  }
  else  {

    recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
    recipeInfoCell.layoutSubviews()


  }
Run Code Online (Sandbox Code Playgroud)

现在,当我第一次启动tableview时,它没有设置任何角半径.但是当我再次滚动时,它正在设置角半径.

我创建了一个扩展,UIView其中有一个功能是设置角半径

  func roundCorners(corners:UIRectCorner, radius: CGFloat) {

    let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask
  }
Run Code Online (Sandbox Code Playgroud)

请告诉我该如何解决这个问题?

ker*_*rry 13

我不认为在cellForRow atIndexPath中设置角半径是个好主意.原因是,在UITableView的生命周期中多次调用此函数,您只需要设置一次角半径,并且在初始化单元时也是如此.基于indexPath更改角半径也会影响UITableView的性能.

更好的方法是创建两个单元格,一个角半径为0,另一个为10,并使用基于indexPath的单元格.

然后,您可以将cornerRadius设置逻辑放在自定义单元格中的layoutSubview函数中.

如果你只想在tableView方法中这样做,正确的方法是在willDisplayCell中执行它,因为在调用之后,单元格的layoutSubviews函数被调用.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if indexPath.row % 2 == 0 {
            let path = UIBezierPath(roundedRect: cell.contentView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            cell.contentView.layer.mask = mask
        } else {
            let path = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 0, height: 0))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            cell.contentView.layer.mask = mask
        }
    }
Run Code Online (Sandbox Code Playgroud)

更新:2017年5月19日

当您要舍入并放置阴影的视图与单元格的内容视图的大小相同时,上述概念将正常工作.但如果它与此不同,它就行不通.

上述声明的原因是,在调用willDisplayCell时,上面的代码正在使用cell.contentView.bounds,其他视图尚未计算.因此,当我们将使用另一个视图时,我们将不得不使用该视图的界限来计算掩码的帧,我们将与实际的帧不同.

在阅读了这一点后,我发现,做这种事情是通过覆盖draw(_ rect: CGRect)UITableViewCell的功能.因为此时,视图的大小已经正确计算,我们可以创建一个正确的框架.

以下是自定义UITableViewCell类的代码:

override func draw(_ rect: CGRect) {
        let path = UIBezierPath(roundedRect: self.outerView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.outerView.layer.mask = mask

        let shadowLayer = CAShapeLayer()
        shadowLayer.shadowPath = path.cgPath
        shadowLayer.frame = self.outerView.layer.frame
        print(shadowLayer.frame)
        shadowLayer.shadowOffset = CGSize(width: 0, height: 0)
        shadowLayer.shadowColor = UIColor.black.cgColor
        shadowLayer.shadowOpacity = 0.9
        self.contentView.layer.insertSublayer(shadowLayer, below: self.outerView.layer)
        super.draw(rect)
    }
Run Code Online (Sandbox Code Playgroud)


小智 8

把圆角代码放在主队列中,如下所示:

if indexPath.row == 9 { dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
   })} else{
 dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
}) }
Run Code Online (Sandbox Code Playgroud)


Him*_*shu 6

尝试在Custom UITableViewCell的layoutSubviews()中编写这些代码行

override func layoutSubviews() {
super.layoutSubviews()
self.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
}
Run Code Online (Sandbox Code Playgroud)