如何在iPhone上设置按钮背景颜色?

时间:2008-12-16 21:11:00

标签: iphone cocoa-touch

如何设置按钮的自定义背景颜色?

Interface Builder似乎没有接口来执行此操作。

仅以编程方式提供吗? 如果是的话,你能提供一个例子吗?

19 个答案:

答案 0 :(得分:20)

我将您的问题读到要求(就像我一样)程序化方式来设置按钮颜色。这是UIKit的一个明显的遗漏,我无法使无证件的UIGlassButton工作。

我已使用单个细分UISegmentedControl 解决这个问题,您可以设置tintColor

UISegmentedControl * btn = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:name]];
btn.momentary = YES;
btn.segmentedControlStyle = UISegmentedControlStyleBar;
btn.tintColor = color;
[btn addTarget:self action:@selector(action:) forControlEvents:UIControlEventValueChanged];

请注意,momentarysegmentedControlStyle属性很重要,并且可以使用图片代替NSString *名称。

如果您可以使用一组有限的固定图像,带有端盖的可伸缩图像可以正常工作,但这不符合要求!如,

buttonImage   = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:26 topCapHeight:16];

答案 1 :(得分:16)

我发现我需要使用可伸缩的图像来实现这一目标。 Apple的UICatalog示例有一个或多个以这种方式绘制的彩色按钮。您可以使用他们的模板图像并重新着色以满足您的按钮需求。

我不确定在Interface Builder中这样做,但我能够使用以下代码创建一个按钮并使用图像作为其内容:

downloadButton = [[UIButton alloc] initWithFrame:CGRectMake(36, 212, 247, 37)];

downloadButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
downloadButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

[downloadButton setTitle:NSLocalizedStringFromTable(@"Download", @"Localized", nil) forState:UIControlStateNormal]; 
[downloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[downloadButton setFont:[UIFont boldSystemFontOfSize:14.0]];

UIImage *newImage = [[UIImage imageNamed:@"greenButton.png"] stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[downloadButton setBackgroundImage:newImage forState:UIControlStateNormal];

[downloadButton addTarget:self action:@selector(downloadNewItem) forControlEvents:UIControlEventTouchDown];

downloadButton.backgroundColor = [UIColor clearColor];
[downloadDisplayView addSubview:downloadButton];

答案 2 :(得分:15)

为圆角矩形按钮设置视图的背景颜色不会更改按钮的背景颜色。尝试将按钮设置为自定义按钮(检查器中的第一个下拉菜单),然后设置背景颜色。你会得到预期的效果:)

答案 3 :(得分:10)

看来,按钮颜色仍然是一个问题。以下类别通过采用UIColor参数的实例方法以编程方式完全设置按钮的backgroundimage。无需创建按钮backgroundimage文件。它保留基于UIControlState的按钮行为。它保持圆角。

头文件UIButton + ColoredBackground.h

#import <UIKit/UIKit.h>

@interface UIButton (ColoredBackground)

- (void)setBackgroundImageByColor:(UIColor *)backgroundColor forState:(UIControlState)state;

@end

和UIButton + ColoredBackground.m

的内容
#import "UIButton+ColoredBackground.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIButton (ColoredBackground)

- (void)setBackgroundImageByColor:(UIColor *)backgroundColor forState:(UIControlState)state{

    // tcv - temporary colored view
    UIView *tcv = [[UIView alloc] initWithFrame:self.frame];
    [tcv setBackgroundColor:backgroundColor];

    // set up a graphics context of button's size
    CGSize gcSize = tcv.frame.size;
    UIGraphicsBeginImageContext(gcSize);
    // add tcv's layer to context
    [tcv.layer renderInContext:UIGraphicsGetCurrentContext()];
    // create background image now
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    // set image as button's background image for the given state
    [self setBackgroundImage:image forState:state];
    UIGraphicsEndImageContext();

    // ensure rounded button
    self.clipsToBounds = YES;
    self.layer.cornerRadius = 8.0;

    [tcv release];

}

@end

在每个UIButton实例上调用新方法,如:

[myButton setBackgroundImageByColor:[UIColor greenColor] forState:UIControlStateNormal];

答案 4 :(得分:9)

http://github.com/dermdaly/ButtonMaker

您可以使用此应用程序生成UI按钮图像...并可将其设置为按钮的背景图像

答案 5 :(得分:5)

此链接为您的问题提供了一个优雅的解决方案...... http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/

答案 6 :(得分:5)

在按钮属性选项板中将按钮类型设置为“自定义”。这将为您提供一个方形按钮,其中包含您为背景选择的任何颜色。

如果你想要一个看起来更像传统按钮但有不同颜色的按钮,你需要进入某种图像编辑软件并创建它(我使用photoshop进行自定义按钮)。

答案 7 :(得分:4)

要保持按钮四舍五入,请使用

view.layer.cornerRadius = 8;

这里描述

How do I create a round cornered UILabel on the iPhone?

答案 8 :(得分:2)

我稍微修改了@Patch的代码版本。对我来说问题是旧版本在从纵向模式切换到横向模式时延伸了角落半径。所以我用这个版本使用了stretchableImageWithLeftCapWidth:topCapHeight方法。

#import "UIButton+ColoredBackground.h"
#import <QuartzCore/QuartzCore.h>

#define kCornerRadius 8.0f
#define kStrokeColor [UIColor blackColor]
#define kStrokeWidth 1.0f

@implementation UIButton (ColoredBackground)

- (void)setBackgroundImageByColor:(UIColor *)backgroundColor forState:(UIControlState)state{


CGSize gcSize = CGSizeMake(2*kCornerRadius +1, self.bounds.size.height);
UIGraphicsBeginImageContext(gcSize);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeOverlay);



CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

UIColor *gradientStart = [UIColor colorWithRed:0.80 green:0.80 blue:0.80 alpha:0.2];
UIColor * gradientEnd = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.2];
NSArray *colors = [NSArray arrayWithObjects:(id)gradientStart.CGColor, (id)gradientEnd.CGColor, nil];
CGFloat locations[2] = { 0.0f, 1.0f };
CGGradientRef _gradient = CGGradientCreateWithColors(rgb, (__bridge CFArrayRef)colors, locations);
CGColorSpaceRelease(rgb);
CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(), _gradient, CGPointMake(0.0, kStrokeWidth), CGPointMake(0.0, self.bounds.size.height-kStrokeWidth), 0);

UIBezierPath *outsideEdge = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0, 0.0, gcSize.width, gcSize.height) cornerRadius:kCornerRadius];
[backgroundColor setFill];
[kStrokeColor setStroke];
outsideEdge.lineWidth = kStrokeWidth;
[outsideEdge stroke];
[outsideEdge fill];

// Create the background image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();    
UIGraphicsEndImageContext(); 

// Set image as button's background image (stretchable) for the given state
[self setBackgroundImage:[image stretchableImageWithLeftCapWidth:kCornerRadius topCapHeight:0.0] forState:state];

// Ensure rounded button
self.clipsToBounds = YES;
self.layer.cornerRadius = kCornerRadius;



}

@end

用法没有改变。它现在在边缘看起来更清晰,而且我还使用渐变来制作更多塑料。但你也可以删除它。

答案 9 :(得分:1)

我通过在Fireworks中创建自己的按钮解决了这个问题。我绘制了一个大小与我想要的大小相同的圆角矩形,带有我想要的填充颜色和边框颜色。修剪画布,并保存为PNG。在XCode中,将文件添加到Resources文件夹中。您可以在Interface Builder中使用“自定义”按钮,并将图像指定为PNG。它会根据需要调整大小,将文本放在顶部等等。如果你必须从原始大小调整大小,角落的曲线可能会扭曲。

答案 10 :(得分:1)

当我想要一个带有蓝色渐变背景的简单“保存”按钮时,Tim James的解决方案(单段细分控制)对我有用。我只是在笔尖中创建了一个2段控件,按照我的意愿设置了第一个段,然后使用[mySegmentedControl removeSegmentAtIndex:1 animated:NO]以编程方式删除-viewWillAppear下的第二个段。 为了我的目的,需要为分段控件的笔尖中的第一个段激活(勾选)“瞬间”,并且“已选中”对于任一段都不活动。 'Value Changed'是分段控制的连接动作。

答案 11 :(得分:1)

这是我创建的免费应用程序,用于创建UIGlassButton图像。将按钮类型设置为自定义。 http://itunes.apple.com/us/app/uibutton-builder/id408204223?mt=8

答案 12 :(得分:1)

我按照以下方式创建按钮,如uitableview

中的系统删除按钮

UIButton *h=[[UIButton  alloc]init];
[[h layer] setCornerRadius:8.0f];
[[h layer] setMasksToBounds:YES];
[[h layer] setBorderWidth:1.0f];
CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init];
[gradientLayer setBounds:[h bounds]];
[gradientLayer setPosition:CGPointMake([h bounds].size.width/2, [h bounds].size.height/2)];
[gradientLayer setColors:[NSArray arrayWithObjects:
(id)[[UIColor darkGrayColor]CGColor],(id)[[UIColor blackColor] CGColor], nil]];
[[h layer] insertSublayer:gradientLayer atIndex:0];

释放所有对象和 导入QuartzCore / QuartzCore.h和 将此框架添加到您的项目中。

答案 13 :(得分:1)

以下是@ user200212解决方案的变体(http://stackoverflow.com/a/8547424)。它使用UIBezierCurve类填充按钮并在其周围绘制1px黑色边框:

的UIButton + ColoredBackground.h

//  UIButton+ColoredBackground.h

#import <UIKit/UIKit.h>

@interface UIButton (ColoredBackground)

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;
+ (UIColor *) silverColor;

@end

的UIButton + ColoredBackground.m

//  UIButton+ColoredBackground.m
#import "UIButton+ColoredBackground.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIButton (UIButton_ColoredBackground)

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state{

    CGSize gcSize = self.bounds.size;
    UIGraphicsBeginImageContext(gcSize);

    // Create a Bezier Path around the button, and fill it with the background color
    UIBezierPath *outsideEdge = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:8.0f];
    [backgroundColor setFill];
    [[UIColor blackColor] setStroke];
    outsideEdge.lineWidth = 1.0;
    [outsideEdge fill];
    [outsideEdge stroke];

    // Create the background image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();    

    UIGraphicsEndImageContext(); 

    // Set image as button's background image for the given state
    [self setBackgroundImage:image forState:state];

    // Ensure rounded button
    self.clipsToBounds = YES;
    self.layer.cornerRadius = 8.0;
}

@end

用法:

[myButton setBackgroundImageByColor:[UIColor greenColor] forState:UIControlStateNormal];

答案 14 :(得分:0)

当你点击按钮并进入检查员时,keremk说要更改“视图”背景颜色是正确的。这会将小角落变成您选择的任何颜色。

答案 15 :(得分:0)

colored UIButton

如果您不想使用图像,并希望它看起来与圆角矩形样式完全相同,请尝试此操作。只需在UIButton上放置UIView,使用相同的框架和自动调整大小的蒙版,将alpha设置为0.3,并将背景设置为颜色。然后使用下面的代码片段从彩色叠加视图中剪切圆角边缘。此外,取消选中UIView上IB中的“User Interaction Enabled”复选框,以允许触摸事件级联到下面的UIButton。

一个副作用是你的文字也会着色。

#import <QuartzCore/QuartzCore.h>

colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;

答案 16 :(得分:0)

在@ Denny1989上进一步构建我在viewDidLoad中设置按钮时解决了出错(无效上下文0x0)的问题。按钮需要在具有大小之前进行布局,因此在视图出现之前不能依赖该按钮。此类别为UIControlStateNormal添加颜色。如果您的应用需要其他控制状态,则需要将其添加到类别中。

//  UIButton+ColoredBackground.h

#import <UIKit/UIKit.h>

@interface UIButton (ColoredBackground)

@property (nonatomic, retain) UIColor *buttonColorNormal;

@property (nonatomic, retain) NSNumber *madeBackgroundImages;

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;

- (void)drawRect:(CGRect)rect;

- (void)awakeFromNib;

@end

//  UIButton+ColoredBackground.m

#import "UIButton+ColoredBackground.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h>

#define kCornerRadius 8.0f
#define kStrokeColor [UIColor darkGrayColor]
#define kStrokeWidth 1.0f



@implementation UIButton (ColoredBackground)

static char UIB_ButtonColorNormal_KEY;
static char UIB_MadeBackgroundImages_KEY;

@dynamic buttonColorNormal;

-(void)setButtonColorNormal:(NSObject *)buttonColorNormal
{
    objc_setAssociatedObject(self, &UIB_ButtonColorNormal_KEY, buttonColorNormal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSObject*)buttonColorNormal
{
    return (NSObject*)objc_getAssociatedObject(self, &UIB_ButtonColorNormal_KEY);
}

@dynamic madeBackgroundImages;

-(void)setMadeBackgroundImages:(NSObject *)madeBackgroundImages
{
    objc_setAssociatedObject(self, &UIB_MadeBackgroundImages_KEY, madeBackgroundImages, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(NSObject*)madeBackgroundImages
{
    return (NSObject*)objc_getAssociatedObject(self, &UIB_MadeBackgroundImages_KEY);
}
- (void)awakeFromNib {
    [self setMadeBackgroundImages:[NSNumber numberWithBool:FALSE]];
    [super awakeFromNib];
}

- (void)drawRect:(CGRect)rect {
    // if background images were not created from color do so here
    // if self.buttonColorNormal is not set behaves like normal button
    if ((self.buttonColorNormal)&&(![[self madeBackgroundImages] boolValue])) {
        [self setBackgroundColor:[self buttonColorNormal] forState:UIControlStateNormal];
        [self setMadeBackgroundImages:[NSNumber numberWithBool:TRUE]];
    }
    [super drawRect:rect];
}

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state {

    gcSize = CGSizeMake(2*kCornerRadius +1, self.bounds.size.height);
    UIGraphicsBeginImageContext(gcSize);

    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

    UIColor *gradientStart = [UIColor colorWithRed:0.80 green:0.80 blue:0.80 alpha:0.2];
    UIColor * gradientEnd = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
    NSArray *colors = [NSArray arrayWithObjects:(id)gradientStart.CGColor, (id)gradientEnd.CGColor, nil];
    CGFloat locations[2] = { 0.0f, 1.0f };
    CGGradientRef _gradient = CGGradientCreateWithColors(rgb, (__bridge CFArrayRef)colors, locations);
    CGColorSpaceRelease(rgb);
    CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeOverlay);
    CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(), _gradient, CGPointMake(0.0, kStrokeWidth), CGPointMake(0.0, self.bounds.size.height-kStrokeWidth), 0);

    UIBezierPath *outsideEdge = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0, 0.0, gcSize.width, gcSize.height) cornerRadius:kCornerRadius];
    [backgroundColor setFill];
    [kStrokeColor setStroke];
    outsideEdge.lineWidth = kStrokeWidth;
    [outsideEdge stroke];
    [outsideEdge fill];
    CFRelease(_gradient);

    // Create the background image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Set image as button's background image (stretchable) for the given state
    [self setBackgroundImage:[image stretchableImageWithLeftCapWidth:kCornerRadius topCapHeight:0.0] forState:state];

    // Ensure rounded button
    self.clipsToBounds = YES;
    self.layer.cornerRadius = kCornerRadius;

    // add colored border
    self.layer.borderColor = kStrokeColor.CGColor;
    self.layer.borderWidth = kStrokeWidth;
}

@end

使用

- (void)viewDidLoad
{
        [myButton setButtonColorNormal:[UIColor redColor]];
}

确保按钮类型为custom或drawRect可能无法调用。

答案 17 :(得分:0)

所以,我找到了一个使用类别的非常简单的解决方案。 (这么简单,我认为我必须做一些hacky,但我不会看到它!)

定义一个类别(如果你不知道那是什么,总结一下:它是一种方法,可以最小化一个类;也就是说,向一个类添加方法但是没有属性)用于UIButton,并创建一个方法&#34; setBackgroundColor&#34;这叫UIButton的超级班级&#39; (UIControl)setBackgroundColor方法。

@implementation UIButton (coloredBackgroundButton)

-(void)setBackgroundColor:(UIColor *)backgroundColor {
    [super setBackgroundColor:backgroundColor];
}

只要您导入声明此类别的头文件,只要您使用UIButton,在这种情况下,

#import "coloredBackgroundButton.h" 

你可以在它们上面调用setBackgroundColor。

答案 18 :(得分:-2)

可能是我误解了你的问题,但下面不适合你吗?