从UIColor创建UIImage以用作UIButton的背景图片

160

我正在创建一个像这样的彩色图像:

CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context,
                                   [[UIColor redColor] CGColor]);
//  [[UIColor colorWithRed:222./255 green:227./255 blue: 229./255 alpha:1] CGColor]) ;
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

然后将其用作按钮的背景图像:

[resultButton setBackgroundImage:img forState:UIControlStateNormal];

使用redColor时很好用,但是我想使用RGB颜色(如注释行所示)。当我使用RGB颜色时,按钮的背景色没有改变。

我错过了什么?


如果您只是为按钮设置背景颜色,为什么不直接使用setBackgroundColor:方法呢? - Chance Hudson
1
设置backgroundColor只会改变圆角的外部,而不是按钮本身的实际区域。 - Thorsten
你的代码在我的环境中(xcode501,iPhoneSimulator703)运行良好,请仔细查看,该按钮很可能是带有浅白色图像的按钮。 - oxromantic
应该更新为使用 UIGraphicsImageRenderer - twodayslate
7个回答

150

我创建了一个基于UIButton的类别(Category),可以设置按钮的背景颜色和状态。您可能会发现这很有用。

@implementation  UIButton (ButtonMagic)

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state {
    [self setBackgroundImage:[UIButton imageFromColor:backgroundColor] forState:state];
}

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

这将是我本月开源的一组辅助类别的一部分。

Swift 2.2

extension UIImage {
static func fromColor(color: UIColor) -> UIImage {
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()
    CGContextSetFillColorWithColor(context, color.CGColor)
    CGContextFillRect(context, rect)
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return img
  }
}

Swift 3.0

extension UIImage {
    static func from(color: UIColor) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        context!.fill(rect)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }
}

用作

let img = UIImage.from(color: .black)

2
不如在UIButton上创建一个类别,虽然现在在Swift中我们使用扩展而不是类别,但您认为最好在UIImage上创建一个初始化器的扩展,而不是在UIButton上。 - SwiftMatt
我能用这个工具创建特定尺寸的图像吗?怎么做呢?如果我的问题看起来很幼稚,对不起.. :-/ - Shyam
如果你只是想创建一个具有特定尺寸的矩形,那么请将宽度和高度更改为任何你想要的值。 - ScottWasserman

14

Xamarin.iOS解决方案

 public UIImage CreateImageFromColor()
 {
     var imageSize = new CGSize(30, 30);
     var imageSizeRectF = new CGRect(0, 0, 30, 30);
     UIGraphics.BeginImageContextWithOptions(imageSize, false, 0);
     var context = UIGraphics.GetCurrentContext();
     var red = new CGColor(255, 0, 0);
     context.SetFillColor(red);
     context.FillRect(imageSizeRectF);
     var image = UIGraphics.GetImageFromCurrentImageContext();
     UIGraphics.EndImageContext();
     return image;
 }

这对我在C# Xamarin中有效。有什么建议可以让这个UIImage变成圆形的吗? - stepheaw

6
你是否正在使用ARC?问题在于你没有引用你尝试应用的UIColor对象;CGColor由该UIColor支持,但是ARC将在你有机会使用CGColor之前释放UIColor
最清晰的解决方案是使用带有objc_precise_lifetime属性的本地变量指向你的UIColor
你可以在关于UIColor和短ARC生命周期的这篇文章中阅读更多关于这个确切情况的内容,或者获取有关objc_precise_lifetime属性的更多详细信息

一个有效的观察,但这将导致崩溃,听起来像是OP没有观察到。 - Justin Spahr-Summers
不一定;这取决于CGColor和CGContextFillRect之间的交互细节,更不用说可能会因操作系统版本而发生变化的其他细节了。当然,它可能是其他问题,但由于代码在编写时已经出现错误(如果使用ARC),因此至少可以作为第一步。 - Jesse Rusak
我的代码来自于ARC之前的时代。 - Thorsten

5

将所有值添加小数点:

[[UIColor colorWithRed:222./255. green:227./255. blue: 229./255. alpha:1] CGColor]) ;

否则,您正在将浮点数除以整数。

5
不正确-在表达式求值之前,整数参数会自动提升为浮点值(在这种情况下为double类型),因为左操作数是double类型。有关详细解释,请参见此答案。 - Jan Holecek

4
CGContextSetFillColorWithColor(context,[[UIColor colorWithRed:(255/255.f) green:(0/255.f) blue: (0/255.f) alpha:1] CGColor]);

不确定你的回答是什么意思...我并没有试图用RGB值替换colorRed,而是想使用自己的值 - 但似乎不起作用。 - Thorsten

4

我认为227./255中的255被视为整数,因此除法运算总是返回0。


感谢这个想法(也是由一个已删除答案的人建议的)。除法运算正常工作,即使从正确设置的浮点数构建颜色(在调试器中声明虚拟变量并检查其值),设置背景图像也不起作用。 - Thorsten

4

您的代码运行正常。您可以使用Iconfactory's xScope验证RGB颜色。只需将其与[UIColor whiteColor]进行比较即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接