I have a UITableView within a UIView, and it is made up of custom cells defined by the following class:
class CustomAddFriendTableViewCell: UITableViewCell {
@IBOutlet weak var UsernameLbl: UILabel!
@IBOutlet weak var ProfileImg: UIImageView!
@IBOutlet weak var AddFriendBtn: UIButton!
}
Within the ViewController's tableview(_:cellForRowAt:)
method I call the following function to layout the cell's ProfileImg:
private func layoutProfilePics(with cell:CustomAddFriendTableViewCell) {
//create gradient
let gradient = CAGradientLayer()
gradient.frame = CGRect(origin: CGPoint.zero, size: cell.ProfileImg.frame.size)
gradient.colors = [Colors.blueGreen.cgColor, Colors.yellow.cgColor]
//create gradient mask
let shape = CAShapeLayer()
shape.lineWidth = 3
shape.path = UIBezierPath(ovalIn: cell.ProfileImg.bounds).cgPath // commenting this out makes lag go away
shape.strokeColor = UIColor.black.cgColor // commenting this out makes lag go away
shape.fillColor = UIColor.clear.cgColor
gradient.mask = shape
cell.ProfileImg.layoutIfNeeded()
cell.ProfileImg.clipsToBounds = true
cell.ProfileImg.layer.masksToBounds = true
cell.ProfileImg.layer.cornerRadius = cell.ProfileImg.bounds.size.width/2.0
cell.ProfileImg.layer.addSublayer(gradient)
}
This code causes ProfileImg
to be a circle and have a border with a blue-green gradient.
The two lines with comments next to them make the scrolling very smooth (meaning the gradient is not what is causing the lag), so I assume that rendering the CAShapeLayer (specifically the stroke) is causing the problem (hence the question title). What can I do to improve the tableview's scrolling performance?
Also, I am not sure if this is an XCode bug or if it has something to do with my problem, but in the Project Navigator's Instruments pane, when I run the app and scroll the laggy UITableView, the FPS does not reflect the lag, even though I can clearly tell that it is very laggy. In fact, there are no noticeable differences in any of the components in the pane (CPU, Memory, Energy Impact, etc.).
Update:
I tried moving the layoutProfilePics(with:)
function into the CustomAddFriendTableViewCell
's prepareForReuse()
function and I also tried putting layoutProfilePics(with:)
in its layoutSubviews()
function but neither of them improved the scrolling.
That code is meant to be called once for each cell and for that, it shouldn't be called in tableView(_:cellForRowAt:)
. Try moving that code to awakeFromNib()
and if you're using a nib for your custom cell, use the following code in viewDidLoad()
to load the the outlets:
let addFriendCellNib = UINib(nibName: "CustomAddFriendTableViewCell", bundle: nil)
tableView.register(addFriendCellNib, forCellReuseIdentifier: "addFriendCell")
I hope that works for you.