UIBezierPath not rendering properly

你离开我真会死。 提交于 2019-12-02 14:24:47

问题


I have a tablviewcell which has uiview in it. Based on some logic I change the background color and make the left and right corner rounded.

I make these view corner round from cellForRowat indexPath function.

Here is my extension.

extension UIView {
    func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}

and how I use it

cell?.myCustomView.roundCorners(corners: [.bottomRight,.bottomLeft], radius: 10.0)

Its working fine when width of iphones is 375, but it fails to update for device with width greater than 375.

And after scrolling the tableview, it again stretches back correctly to the desired width.

How to solve this problem ?


回答1:


You want to update the path when the view changes size. In cellForRowAt the cell has not yet been fully laid-out by auto-layout.

So...

Create a UIView subclass for your "rounded corners" view (simple example):

class RoundedCornersView: UIView {

    var corners: UIRectCorner = UIRectCorner()
    var radius: CGFloat = 0.0

    override func layoutSubviews() {
        super.layoutSubviews()
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}

Now, anytime the view changes size - such as on first use or device rotation, for example - the view will automatically update the path.

Here is how you would use it in a table cell. In Storyboard, set the class of the "background view" to RoundedCornersView

class RoundedCornersView: UIView {

    var corners: UIRectCorner = UIRectCorner()
    var radius: CGFloat = 0.0

    override func layoutSubviews() {
        super.layoutSubviews()
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        layer.mask = mask
    }
}

class MyTestCell: UITableViewCell {

    @IBOutlet var myCustomView: RoundedCornersView!

}

Then, in cellForRowAt:

        let cell = tableView.dequeueReusableCell(withIdentifier: "MyTestCell", for: indexPath) as! MyTestCell

        if shouldBeRounded {
            cell.myCustomView.corners = [.bottomRight, .bottomLeft]
            cell.myCustomView.radius = 10.0
            cell.myCustomView.backgroundColor = .green
        } else {
            cell.myCustomView.corners = []
            cell.myCustomView.radius = 0.0
            cell.myCustomView.backgroundColor = .white
        }

        return cell



回答2:


Use this:

override func draw(_ rect: CGRect) {
    super.draw(rect)
    selectedView.roundCorners(corners: [.topLeft, .topRight], radius: 12.0)
}


来源:https://stackoverflow.com/questions/57480352/uibezierpath-not-rendering-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!