iOS - How to apply gradient color to UICollectionViewCell backgroundView?












1















I have been able to apply the gradient I want to the backgroundView of my UICollectionViewCell. But every time I reload the cell, it applies again my gradient, accumulating all the gradient.



First of all here is my method for the gradient :



static func setGradientWhite(uiView: UIView) {

let colorBottomWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.30).cgColor
let colorTopWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0).cgColor

let gradientLayer = CAGradientLayer()
gradientLayer.colors = [ colorTopWhite, colorBottomWhite]
gradientLayer.locations = [ 0.0, 1.0]
gradientLayer.frame = uiView.bounds

uiView.layer.insertSublayer(gradientLayer, at: 0)
}


I know I can do it in a more generic way, and change the way I am handling the colors, but it's not the point, it is for testing purpose for now.



I tried to call it like this :



override func awakeFromNib() {
super.awakeFromNib()
UIUtils.setGradientWhite(uiView: self)
}


The gradients do not accumulate this way, in the awakeFromNib, BUT, the animation isn't finish and I only have half of my cell with gradient applied.



And if I do it in this method :



override func layoutSubviews() {
super.layoutSubviews()

CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}


The gradient animation is properly finished, applying to the whole view, but when the cell is reloading, it applies a new gradient on top of the previous one, until I cannot see my cell anymore (in this case too much white here).



Any ideas on how can I solve this issue?










share|improve this question


















  • 3





    It's accumulating because of the reuse. Instead, keep the code in awakFromNib(), but in override func layoutSubviews(), instead do guard if let gradientLayer = self.layers.first as? CAGradientLayer() { gradientLayer.bounds = self.bounds }.

    – Larme
    Nov 20 '18 at 13:23






  • 1





    Any reason why not to have a variable,didSetupGradient = false, set it to true once you add the gradient, and put the gradient adding code in if !didSetupGradient

    – Daniel
    Nov 20 '18 at 13:23






  • 1





    By default function parameters are passed by value, not the reference. Hence it is not reflecting with the actual outside object. try to add "inout" keyword before "(uiView: inout UIView)'. or add return type and set updated object with existing one.

    – Anand Kore
    Nov 20 '18 at 13:34
















1















I have been able to apply the gradient I want to the backgroundView of my UICollectionViewCell. But every time I reload the cell, it applies again my gradient, accumulating all the gradient.



First of all here is my method for the gradient :



static func setGradientWhite(uiView: UIView) {

let colorBottomWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.30).cgColor
let colorTopWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0).cgColor

let gradientLayer = CAGradientLayer()
gradientLayer.colors = [ colorTopWhite, colorBottomWhite]
gradientLayer.locations = [ 0.0, 1.0]
gradientLayer.frame = uiView.bounds

uiView.layer.insertSublayer(gradientLayer, at: 0)
}


I know I can do it in a more generic way, and change the way I am handling the colors, but it's not the point, it is for testing purpose for now.



I tried to call it like this :



override func awakeFromNib() {
super.awakeFromNib()
UIUtils.setGradientWhite(uiView: self)
}


The gradients do not accumulate this way, in the awakeFromNib, BUT, the animation isn't finish and I only have half of my cell with gradient applied.



And if I do it in this method :



override func layoutSubviews() {
super.layoutSubviews()

CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}


The gradient animation is properly finished, applying to the whole view, but when the cell is reloading, it applies a new gradient on top of the previous one, until I cannot see my cell anymore (in this case too much white here).



Any ideas on how can I solve this issue?










share|improve this question


















  • 3





    It's accumulating because of the reuse. Instead, keep the code in awakFromNib(), but in override func layoutSubviews(), instead do guard if let gradientLayer = self.layers.first as? CAGradientLayer() { gradientLayer.bounds = self.bounds }.

    – Larme
    Nov 20 '18 at 13:23






  • 1





    Any reason why not to have a variable,didSetupGradient = false, set it to true once you add the gradient, and put the gradient adding code in if !didSetupGradient

    – Daniel
    Nov 20 '18 at 13:23






  • 1





    By default function parameters are passed by value, not the reference. Hence it is not reflecting with the actual outside object. try to add "inout" keyword before "(uiView: inout UIView)'. or add return type and set updated object with existing one.

    – Anand Kore
    Nov 20 '18 at 13:34














1












1








1








I have been able to apply the gradient I want to the backgroundView of my UICollectionViewCell. But every time I reload the cell, it applies again my gradient, accumulating all the gradient.



First of all here is my method for the gradient :



static func setGradientWhite(uiView: UIView) {

let colorBottomWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.30).cgColor
let colorTopWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0).cgColor

let gradientLayer = CAGradientLayer()
gradientLayer.colors = [ colorTopWhite, colorBottomWhite]
gradientLayer.locations = [ 0.0, 1.0]
gradientLayer.frame = uiView.bounds

uiView.layer.insertSublayer(gradientLayer, at: 0)
}


I know I can do it in a more generic way, and change the way I am handling the colors, but it's not the point, it is for testing purpose for now.



I tried to call it like this :



override func awakeFromNib() {
super.awakeFromNib()
UIUtils.setGradientWhite(uiView: self)
}


The gradients do not accumulate this way, in the awakeFromNib, BUT, the animation isn't finish and I only have half of my cell with gradient applied.



And if I do it in this method :



override func layoutSubviews() {
super.layoutSubviews()

CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}


The gradient animation is properly finished, applying to the whole view, but when the cell is reloading, it applies a new gradient on top of the previous one, until I cannot see my cell anymore (in this case too much white here).



Any ideas on how can I solve this issue?










share|improve this question














I have been able to apply the gradient I want to the backgroundView of my UICollectionViewCell. But every time I reload the cell, it applies again my gradient, accumulating all the gradient.



First of all here is my method for the gradient :



static func setGradientWhite(uiView: UIView) {

let colorBottomWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.30).cgColor
let colorTopWhite = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0).cgColor

let gradientLayer = CAGradientLayer()
gradientLayer.colors = [ colorTopWhite, colorBottomWhite]
gradientLayer.locations = [ 0.0, 1.0]
gradientLayer.frame = uiView.bounds

uiView.layer.insertSublayer(gradientLayer, at: 0)
}


I know I can do it in a more generic way, and change the way I am handling the colors, but it's not the point, it is for testing purpose for now.



I tried to call it like this :



override func awakeFromNib() {
super.awakeFromNib()
UIUtils.setGradientWhite(uiView: self)
}


The gradients do not accumulate this way, in the awakeFromNib, BUT, the animation isn't finish and I only have half of my cell with gradient applied.



And if I do it in this method :



override func layoutSubviews() {
super.layoutSubviews()

CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}


The gradient animation is properly finished, applying to the whole view, but when the cell is reloading, it applies a new gradient on top of the previous one, until I cannot see my cell anymore (in this case too much white here).



Any ideas on how can I solve this issue?







ios swift uicollectionviewcell cagradientlayer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 13:20









BalancedBalanced

625728




625728








  • 3





    It's accumulating because of the reuse. Instead, keep the code in awakFromNib(), but in override func layoutSubviews(), instead do guard if let gradientLayer = self.layers.first as? CAGradientLayer() { gradientLayer.bounds = self.bounds }.

    – Larme
    Nov 20 '18 at 13:23






  • 1





    Any reason why not to have a variable,didSetupGradient = false, set it to true once you add the gradient, and put the gradient adding code in if !didSetupGradient

    – Daniel
    Nov 20 '18 at 13:23






  • 1





    By default function parameters are passed by value, not the reference. Hence it is not reflecting with the actual outside object. try to add "inout" keyword before "(uiView: inout UIView)'. or add return type and set updated object with existing one.

    – Anand Kore
    Nov 20 '18 at 13:34














  • 3





    It's accumulating because of the reuse. Instead, keep the code in awakFromNib(), but in override func layoutSubviews(), instead do guard if let gradientLayer = self.layers.first as? CAGradientLayer() { gradientLayer.bounds = self.bounds }.

    – Larme
    Nov 20 '18 at 13:23






  • 1





    Any reason why not to have a variable,didSetupGradient = false, set it to true once you add the gradient, and put the gradient adding code in if !didSetupGradient

    – Daniel
    Nov 20 '18 at 13:23






  • 1





    By default function parameters are passed by value, not the reference. Hence it is not reflecting with the actual outside object. try to add "inout" keyword before "(uiView: inout UIView)'. or add return type and set updated object with existing one.

    – Anand Kore
    Nov 20 '18 at 13:34








3




3





It's accumulating because of the reuse. Instead, keep the code in awakFromNib(), but in override func layoutSubviews(), instead do guard if let gradientLayer = self.layers.first as? CAGradientLayer() { gradientLayer.bounds = self.bounds }.

– Larme
Nov 20 '18 at 13:23





It's accumulating because of the reuse. Instead, keep the code in awakFromNib(), but in override func layoutSubviews(), instead do guard if let gradientLayer = self.layers.first as? CAGradientLayer() { gradientLayer.bounds = self.bounds }.

– Larme
Nov 20 '18 at 13:23




1




1





Any reason why not to have a variable,didSetupGradient = false, set it to true once you add the gradient, and put the gradient adding code in if !didSetupGradient

– Daniel
Nov 20 '18 at 13:23





Any reason why not to have a variable,didSetupGradient = false, set it to true once you add the gradient, and put the gradient adding code in if !didSetupGradient

– Daniel
Nov 20 '18 at 13:23




1




1





By default function parameters are passed by value, not the reference. Hence it is not reflecting with the actual outside object. try to add "inout" keyword before "(uiView: inout UIView)'. or add return type and set updated object with existing one.

– Anand Kore
Nov 20 '18 at 13:34





By default function parameters are passed by value, not the reference. Hence it is not reflecting with the actual outside object. try to add "inout" keyword before "(uiView: inout UIView)'. or add return type and set updated object with existing one.

– Anand Kore
Nov 20 '18 at 13:34












1 Answer
1






active

oldest

votes


















1














You can try



override func layoutSubviews() {
super.layoutSubviews()
if !(self.layer.sublayers?.first is CAGradientLayer) {
CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}
}





share|improve this answer



















  • 1





    This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

    – Balanced
    Nov 20 '18 at 13:36











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393925%2fios-how-to-apply-gradient-color-to-uicollectionviewcell-backgroundview%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














You can try



override func layoutSubviews() {
super.layoutSubviews()
if !(self.layer.sublayers?.first is CAGradientLayer) {
CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}
}





share|improve this answer



















  • 1





    This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

    – Balanced
    Nov 20 '18 at 13:36
















1














You can try



override func layoutSubviews() {
super.layoutSubviews()
if !(self.layer.sublayers?.first is CAGradientLayer) {
CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}
}





share|improve this answer



















  • 1





    This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

    – Balanced
    Nov 20 '18 at 13:36














1












1








1







You can try



override func layoutSubviews() {
super.layoutSubviews()
if !(self.layer.sublayers?.first is CAGradientLayer) {
CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}
}





share|improve this answer













You can try



override func layoutSubviews() {
super.layoutSubviews()
if !(self.layer.sublayers?.first is CAGradientLayer) {
CATransaction.begin()
CATransaction.setDisableActions(true)
UIUtils.setGradientWhite(uiView: self)
CATransaction.commit()
}
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 20 '18 at 13:29









Sh_KhanSh_Khan

43.7k51329




43.7k51329








  • 1





    This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

    – Balanced
    Nov 20 '18 at 13:36














  • 1





    This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

    – Balanced
    Nov 20 '18 at 13:36








1




1





This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

– Balanced
Nov 20 '18 at 13:36





This version is working. Thank you. As mentioned in the comment, I just needed to apply the gradient only once. Not multiple times in each reuse.

– Balanced
Nov 20 '18 at 13:36




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393925%2fios-how-to-apply-gradient-color-to-uicollectionviewcell-backgroundview%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()