On tableView\'s cells, I\'m trying to define a gradient with the following Swift code:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: N
I had a similar problem, my mistake was inserting the new layer with gradient directly in the cell, try inserting the new layer to the backgroundView something like this
let gradient = CAGradientLayer()
// layer setup...
cell.backgroundView = UIView()
cell.backgroundView?.layer.insertSublayer(gradientLayer, atIndex: 0)
Hope this helps.
The gradient is a visual ornamentation. It is specific to the cell class. How the cell looks is the responsibility of the cell. It should be defined in the cell class then. It absolutely does not belong to the cellForRowAtIndexPath which should be solely about choosing the right cell for the right row. But you are configuring the internals of the cell in that method and this, combined with the way how queueing works, causes all the issues.
1) Create a subclass of UITableViewCell (programatically, IB..it doesn't really matter)
2) Add the layer in awakeFromNib or layoutSubviews to the backroundView property.
3) register the cell in viewDidLoad in your tableViewController.
Further expanding Earl Grey, and hidra Answer,
when you add a gradient to a specific view then you need to set the actual frame for the gradient layer.
if your view on which you have added gradient layer loaded initially on view did load then you have to put it in then it will not resize as expected, you can resolve this problem in two ways.
first : Give frame manually by calculating the size of the view, but this is very hectic as you have to calculate for each iPhone variation you can calculate the width and height ratio BY.
let bounds = UIScreen.main.bounds
let deviceheight = bounds.size.height
let deviceWidth = bounds.size.width
Then you calculate and give the width size
another way you can do it by doing no calculation just by adding the layer after view has been loaded which can be done with:
override func viewDidAppear(_ animated: Bool) {
Your gradient code //you can create a method for adding a gradient layer
}
Now in Tableview or collection view the same problem exists and we don't have any view did appear method in the cell. we have two scenarios in this.
- data is static.
- data is coming from the server
coming up to the first scenario when data is static you all have to do it as create a variable of boolean type and make it false till once the view is loaded. then make it true in view did appear method for row at index method and again reload cell.
class VC: UIViewController {
var isCellLoaded : Bool = false
override func viewDidAppear(_ animated: Bool) {
isCellLoaded = true
self.aTable.reloadData()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "youcellidentifier", for: indexPath) as! youcell
if isCellLoaded {
cell.gradientView.setGradient(cornerRadius: 5, gradientLeftColor: .notificationViewLeftColor, gradientRightColor: .notificationViewRightColor)
if let gradient = cell.gradientView.layer.sublayers?[0] as? CAGradientLayer {
gradient.frame = cell.gradientView.bounds
}
}
return cell
}
Coming to the second scenario when the data is coming from API
Hurray!! you don't need to do anything as for the first time there is no data in the till api has not given any response and when the response comes you have to reload data. and things will work perfectly. Blockquote