I am attempting to round the top corners of my table view using a mask. I added an extension to the UITableView to do so.
extension UITableView {
func roundCorners(corners:UIRectCorner, radius: CGFloat) {
DispatchQueue.main.async {
let path = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = self.bounds
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
}
}
}
In the ViewDidLoad function, I call,
tableView.roundCorners(corners: [.topRight,.topLeft], radius: 15)
However, the while the Table View's top are rounded, the mask seems to be the incorrect size. The content of the table view is dynamic, as cells are added and removed. The first cell shows up properly, but when I scroll the the correct amount of cells show but they can't be seen. I think that the mask is being drawn to the table view size before cells are added - I have tried moving the function to
func viewWillLayoutSubviews() {
But that does not change anything. Also, I have tried adding the function to after the data is loaded, which still does not do anything.
Try this, working
class ViewController: UIViewController, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.reloadData()
tableView.addObserver(self, forKeyPath: "contentSize", options: [NSKeyValueObservingOptions.new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
tableView.roundCorners(corners: [.topRight,.topLeft, .bottomRight, .bottomLeft], radius: 15)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 30
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
return cell
}
}
extension UITableView {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let rect = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height)
let path = UIBezierPath(roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = rect
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
}
}