简体   繁体   English

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

[英]How can I set a button background color on iPhone?

How can I set a custom background color of a button? 如何设置按钮的自定义背景颜色?

Interface Builder doesn't seem to have an interface to do this. Interface Builder似乎没有用于执行此操作的界面。

Is it only available programmatically? 它只能以编程方式提供吗? If so, can you provide an example, please? 如果是的话,你能提供一个例子吗?

I read your question to require (as I do) a programmatic way to set button color. 我读了你的问题, 要求 (像我一样)以编程方式设置按钮颜色。 It's a glaring omission from the UIKit, and I couldn't get the undocumented UIGlassButton to work. 这是UIKit的一个明显的遗漏,我无法让无证的UIGlassButton工作。

I've solved this with a single segment UISegmentedControl , which allows you to set the tintColor : 我用单个段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];

Note please that the momentary and segmentedControlStyle properties do matter, and that an image can be used instead of a NSString * name. 请注意, momentarysegmentedControlStyle属性很重要,并且可以使用图像而不是NSString *名称。

A stretchable image with end caps works fine if you can use a finite set of canned images, but that doesn't fit the requirement! 如果您可以使用一组有限的固定图像,带有端盖的可伸缩图像可以正常工作,但这不符合要求! Eg, 例如,

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

I found that I needed to use a stretchable image to accomplish this. 我发现我需要使用可伸缩的图像来实现这一目标。 Apple's UICatalog example has one or more colored buttons that are drawn in this fashion. Apple的UICatalog示例有一个或多个以这种方式绘制的彩色按钮。 You could use their template image and recolor it to suit your button needs. 您可以使用他们的模板图像并重新着色以满足您的按钮需求。

I'm not sure about doing this in Interface Builder, but I was able to create a button and use an image for its contents using the following code: 我不确定在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];

Setting the background color of the view for a rounded-rect button will not change the background color of the button. 为圆角矩形按钮设置视图的背景颜色不会更改按钮的背景颜色。 Try making the button a custom button (the first drop-down in the inspector) and then setting the background color. 尝试将按钮设置为自定义按钮(检查器中的第一个下拉菜单),然后设置背景颜色。 You will get the desired effect :) 你会得到想要的效果:)

It seems, that button color still is an issue. 看来,按钮颜色仍然是一个问题。 The following category sets a button's backgroundimage completely programmatically via an instance method that takes a UIColor parameter. 以下类别通过采用UIColor参数的实例方法以编程方式完全设置按钮的backgroundimage。 There is no need to create button backgroundimage files. 无需创建按钮backgroundimage文件。 It preserves button behavior based on UIControlState. 它保留基于UIControlState的按钮行为。 And it keeps the rounded corners. 它保持圆角。

The header file UIButton+ColoredBackground.h 头文件UIButton + ColoredBackground.h

#import <UIKit/UIKit.h>

@interface UIButton (ColoredBackground)

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

@end

and the content of UIButton+ColoredBackground.m 以及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

The new method is justed called on every UIButton instance like: 在每个UIButton实例上调用新方法,如:

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

http://github.com/dermdaly/ButtonMaker http://github.com/dermdaly/ButtonMaker

You can generate UIbutton image using this application...and can set it as background image of your button 您可以使用此应用程序生成UI按钮图像...并可以将其设置为按钮的背景图像

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

Set your button type to "custom" in the button attributes palette. 在按钮属性选项板中将按钮类型设置为“自定义”。 This will give you a square button with whatever color you picked for the background. 这将为您提供一个方形按钮,其中包含您为背景选择的任何颜色。

If you want a button that looks more like a traditional button, but has a different color your going to need to go into some kind of image editing software and create it (I use photoshop for custom buttons). 如果你想要一个看起来更像传统按钮但有不同颜色的按钮,你需要进入某种图像编辑软件并创建它(我使用photoshop进行自定义按钮)。

To keep the button rounded, what about using 要保持按钮四舍五入,请使用

view.layer.cornerRadius = 8;

described here 这里描述

How do I create a round cornered UILabel on the iPhone? 如何在iPhone上创建圆角UILabel?

i have a little modified the code version of @Patch. 我稍微修改了@Patch的代码版本。 The problem for me was that the old version stretched the corner radius kind of dirty when switching from portrait to landscape mode. 对我来说问题是旧版本在从纵向模式切换到横向模式时延伸了角落半径。 So i made this version use stretchableImageWithLeftCapWidth:topCapHeight Method. 所以我用这个版本使用了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

The usage didn't changed. 用法没有改变。 It looks clearer now on the edges, and i also aded a gradient to make more plastic. 它现在在边缘看起来更清晰,而且我还使用渐变来制作更多塑料。 but you can remove this as well. 但你也可以删除它。

Tim James' solution (a single-segment segmented control) worked for me when I wanted a simple 'Save' button with a decent blue gradient background. 蒂姆詹姆斯的解决方案(单段分段控制)为我工作时,我想要一个简单的“保存”按钮,具有不错的蓝色渐变背景。 I simply created a 2 segment control in the nib, set up the first segment as I wanted it and then programatically removed the second segment under -viewWillAppear using [mySegmentedControl removeSegmentAtIndex:1 animated:NO]. 我只是在笔尖中创建了一个2段控件,按照我的意愿设置了第一个段,然后使用[mySegmentedControl removeSegmentAtIndex:1 animated:NO]以编程方式删除-viewWillAppear下的第二个段。 For my purposes 'Momentary' needed to be active (ticked) for the Segmented Control's first segment in the nib and 'Selected' was not active for either segment. 为了我的目的,需要为分段控件的笔尖中的第一个段激活(勾选)“瞬间”,并且“已选中”对于任一段都不活动。 'Value Changed' is the Segmented Control's Action to connect up. 'Value Changed'是分段控制的连接动作。

Here is a free app I created that creates UIGlassButton images. 这是我创建的免费应用程序,用于创建UIGlassButton图像。 Set the button type to custom. 将按钮类型设置为自定义。 http://itunes.apple.com/us/app/uibutton-builder/id408204223?mt=8 http://itunes.apple.com/us/app/uibutton-builder/id408204223?mt=8

i did it as follows to create button like system delete button as in uitableview 我按照以下方式创建按钮,如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];

release all objects and import QuartzCore/QuartzCore.h and add this framework to your project. 释放所有对象并导入QuartzCore / QuartzCore.h并将此框架添加到您的项目中。

I solved this problem by creating my own button in Fireworks. 我通过在Fireworks中创建自己的按钮解决了这个问题。 I drew a rounded rectangle of about the size I wanted, with the fill color and border color I wanted. 我绘制了一个大小与我想要的大小相同的圆角矩形,带有我想要的填充颜色和边框颜色。 Trim the canvas, and save as a PNG. 修剪画布,并保存为PNG。 In XCode, add the file to the Resources folder. 在XCode中,将文件添加到Resources文件夹中。 You can use a Custom button in Interface Builder and specify the image as that PNG. 您可以在Interface Builder中使用“自定义”按钮,并将图像指定为PNG。 It will resize it as needed, put the text on top, etc. The curve of the corners may distort if you have to resize it much from the original. 它将根据需要调整大小,将文本放在顶部等。如果您必须从原始大小调整大小,角落的曲线可能会扭曲。

Here's a variation on @user200212's solution (http://stackoverflow.com/a/8547424). 以下是@ user200212解决方案的变体(http://stackoverflow.com/a/8547424)。 It uses the UIBezierCurve class to fill the button and draw a 1px black border around it: 它使用UIBezierCurve类来填充按钮并在其周围绘制1px黑色边框:

UIButton+ColoredBackground.h 的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

//  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

Usage: 用法:

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

Building further on @Denny1989 I've solved a problem getting errors (invalid context 0x0) when setting up the button in viewDidLoad. 在@ Denny1989上进一步构建我在viewDidLoad中设置按钮时解决了获取错误(无效上下文0x0)的问题。 The button needs to be laid out before it has a size and thus cannot be depended on until after the view appears. 按钮需要在具有大小之前进行布局,因此在视图出现之前不能依赖该按钮。 This category adds a color for UIControlStateNormal. 此类别为UIControlStateNormal添加颜色。 If other control states are necessary for your app you need to add them similarly to the category. 如果您的应用需要其他控制状态,则需要将其类似地添加到类别中。

//  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

and

//  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

usage 用法

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

Be sure to make the button type custom or drawRect may not be called. 务必使按钮类型为custom或drawRect可能不会被调用。

So, I found an incredibly simple solution using categories. 所以,我找到了一个使用类别的非常简单的解决方案。 (So simple that I think I must be doing something hacky, but I don't see it!) (这么简单,我认为我必须做一些hacky,但我没有看到它!)

Define a category (if you don't know what that is, in summary: it is a way to "extend" a class minimally; that is, to add methods to a class but no properties) for UIButton, and create a method "setBackgroundColor" that calls UIButton's super class' (UIControl) setBackgroundColor method. 定义一个类别(如果你不知道它是什么,总结一下:它是一种最小化“扩展”类的方法;也就是说,为UIButton添加方法但没有属性),并创建一个方法“ setBackgroundColor“调用UIButton的超类'(UIControl)setBackgroundColor方法。

@implementation UIButton (coloredBackgroundButton)

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

Wherever you use UIButtons, as long as you import the header file in which this category is declared, in this case, 无论您在何处使用UIButtons,只要您导入声明此类别的头文件,在这种情况下,

#import "coloredBackgroundButton.h" 

you can call setBackgroundColor on them. 你可以在它们上面调用setBackgroundColor。

keremk was right when he said to change the 'view' background color when you have clicked on the button and gone into the inspector. 当keremk点击按钮并进入检查员时,他说要更改“视图”背景颜色是正确的。 This changes the little corners into whatever colour you picked. 这会将小角落变成您选择的任何颜色。

彩色UIButton

If you are not wanting to use images, and want it to look exactly like the Rounded Rect style, try this. 如果您不想使用图像,并希望它看起来与圆角矩形样式完全相同,请尝试此操作。 Just place a UIView over the UIButton, with an identical frame and auto resize mask, set the alpha to 0.3, and set the background to a color. 只需在UIButton上放置UIView,使用相同的框架和自动调整大小的蒙版,将alpha设置为0.3,并将背景设置为颜色。 Then use the snippet below to clip the rounded edges off the colored overlay view. 然后使用下面的代码片段从彩色叠加视图中剪切圆角边缘。 Also, uncheck the 'User Interaction Enabled' checkbox in IB on the UIView to allow touch events to cascade down to the UIButton underneath. 此外,取消选中UIView上IB中的“User Interaction Enabled”复选框,以允许触摸事件级联到下面的UIButton。

One side effect is that your text will also be colorized. 一个副作用是你的文字也会着色。

#import <QuartzCore/QuartzCore.h>

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM