Maray97
Maray97

Reputation: 172

UITableView corner radius doesn't work correctly

I've a tableview and I'd like to make the cells rounded. Every cell has a textfield inside. On "cellForRowAtIndexPath" I wrote:

cell.layer.cornerRadius = cell.frame.size.height/2;
cell.layer.masksToBounds = true;
cell.clipsToBounds = true;

but I can't understand why, but on one line cells sometimes the corner radius doesn't work causing to be like "pointed". P.s. the content mode is set to be Aspect fit

Can someone help me?

Upvotes: 1

Views: 2179

Answers (5)

Maray97
Maray97

Reputation: 172

As andym said, I'm relying on the frame property that haven't been defined yet. The best way to accomplish my goal is to put my code inside willDisplayCell method like this:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    cell.layer.cornerRadius = cell.layer.bounds.size.height/2;
}

Upvotes: 2

andym
andym

Reputation: 67

You are relying on the frame property of the cell, which is actually being managed by UIKit and the table view. In the place you refer to the frame, it might not actually be what you expect because it hasn’t been displayed yet. (For example if your cells have dynamic heights and you are recycling an old cell with a different height then it will still have the old frame.)

You could try rounding inside the cell’s implementation code itself. If you override the bounds property and use a didSet property observer you can set the corner radius there (use bounds instead of frame). This way even if the bounds changes 100 times you will always have the corner radius you expect.

Upvotes: 1

Fabio
Fabio

Reputation: 5648

I advise you to add a comtainer view to your cell controller, you will be able to manage the cell padding better with Auto Layout:

let containerView = UIView() 

set property of it:

containerView.backgroundColor = .red
containerView.clipsToBounds = true
containerView.translatesAutoresizingMaskIntoConstraints = false

Now add UIView and set constraints:

addSubview(containerView)
containerView.topAnchor.constraint(equalTo: topAnchor, constant: 0).isActive = true //change the constant to add padding (right and bottom are negative value)
containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0).isActive = true
containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0).isActive = true
containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0).isActive = true 

After that in cellForRowAt set yuor cell backgroundColor to clear

cell.backgoundColor = .clear
cell.containerView.layer.cornerRadius = cell.bounds.size.height/2;

This is the result with your corner radius applied to containerView:

enter image description here

Or set your tableView and cell like this:

class DummyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

let tableView = UITableView()

override func viewDidLoad() {
    super.viewDidLoad()
    
    tableView.delegate = self
    tableView.dataSource = self
    tableView.translatesAutoresizingMaskIntoConstraints = false
    tableView.register(MyCell.self, forCellReuseIdentifier: "cellId")

    view.addSubview(tableView)
    tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    10
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    300
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! MyCell
    cell.layer.cornerRadius = cell.frame.size.height / 2;
    return cell
  }
}

Your cell:

class MyCell: UITableViewCell {

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    
    backgroundColor = .blue
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
 }
}

This is the result with your corner radius applied:

enter image description here

Upvotes: 3

Ramires Nascimento
Ramires Nascimento

Reputation: 243

You should configure the content view instead a cell it self

cell.contentView.layer.cornerRadius = 5 // or the value that you want
cell.contentView.layer.masksToBounds = true

Upvotes: 0

cora
cora

Reputation: 2102

clipsToBounds needs to be set to true on the superview, which is a tableview in your case.

Upvotes: 0

Related Questions