Nico Nico - 24 days ago 10
Swift Question

Simple way to show to the user that he pressed a button by changing the background color?

I would like, when the user presses a button, give him a feedback that he pressed the button such as a quick animated change of background color (lighter color than the one for the button's background for example).

We can use the

shows touch on highlight
from the Interface builder but it doesn't really do what I'm looking for.

On my table view I was doing this by calling
tableView.deselectRowAtIndexPath(indexPath, animated: true)
in
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)


Is there a similar simple way to do it or do I have to change the background color of the button through
button.layer.backgroundColor
with an animation?

Answer

Continuing my comment — when you initialize your button make sure its type is UIButtonTypeSystem.

Then, you could change the button’s background color with the help of this class method you could add to UIImage category:

+ (UIImage *)imageWithColor:(UIColor *)color {    
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0, 1.0);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

Then, do this to your button:

[button setBackgroundImage:[UIImage imageWithColor:[UIColor greenColor]]
                  forState:UIControlStateHighlighted];

Swift 3:

extension UIImage {
    public class func imageFromColor(_ color: UIColor) -> UIImage? {
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        if let context = UIGraphicsGetCurrentContext() {
            context.setFillColor(color.cgColor)
            context.fill(rect)
        }
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
Comments