代码之家  ›  专栏  ›  技术社区  ›  Alex

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

  •  37
  • Alex  · 技术社区  · 17 年前

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

    Interface Builder似乎没有这样的接口。

    它只以编程方式可用吗? 如果是这样,你能举个例子吗?

    18 回复  |  直到 17 年前
        1
  •  20
  •   Tim James    17 年前

    我读了你的问题 要求 (和我一样)a 计划的 设置按钮颜色的方法。这是UIKit中的一个明显遗漏,我无法让未记录的UIGlassButton工作。

    I have 的常用口语形式 解决 这个只有一个片段 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];
    

    请注意 momentary segmentedControlStyle 属性确实很重要,可以使用图像代替 NSString * 名字。

    如果你能使用一组有限的罐装图像,那么带有端盖的可拉伸图像效果很好,但这不符合要求!例如。,

    buttonImage   = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:26 topCapHeight:16];
    
        2
  •  16
  •   Brad Larson    17 年前

    我发现我需要使用可拉伸的图像来实现这一点。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];
    
        3
  •  15
  •   lostInTransit    17 年前

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

        4
  •  10
  •   alex    14 年前

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

    头文件UIButton+ColoredBackground。英语字母表的第8个字母

    #import <UIKit/UIKit.h>
    
    @interface UIButton (ColoredBackground)
    
    - (void)setBackgroundImageByColor:(UIColor *)backgroundColor forState:(UIControlState)state;
    
    @end
    

    以及UI按钮+彩色背景的内容。男性

    #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];
    
        5
  •  9
  •   S.P.    15 年前

    http://github.com/dermdaly/ButtonMaker

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

        6
  •  5
  •   acreek    17 年前

    在按钮属性调色板中将按钮类型设置为“自定义”。这将给你一个方形按钮,上面有你为背景选择的任何颜色。

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

        7
  •  4
  •   Community Mohan Dere    9 年前

    为了使按钮保持圆形,使用

    view.layer.cornerRadius = 8;
    

    此处描述

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

        8
  •  2
  •   Denny1989    14 年前

    我稍微修改了@Patch的代码版本。对我来说,问题是旧版本在从纵向模式切换到横向模式时,角半径拉伸得有点脏。所以我让这个版本使用可拉伸的ImageWithLeftCapWidth: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
  •   Bob Snider Bob Snider    17 年前

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

        10
  •  1
  •   iTinck    16 年前

    Tim James的解决方案(单段分段控件)对我很有效,当时我想要一个简单的“保存”按钮,背景是一个不错的蓝色渐变。我只是在笔尖中创建了一个2段控件,按照我的要求设置第一段,然后使用[myDSegmentedControl removeSegmentAtIndex:1动画:否]在viewWillAppear下以编程方式删除第二段。 出于我的目的,对于笔尖中的分段控制的第一个分段,“Momentary”需要处于活动状态(勾选),而“Selected”对任何一个分段都不处于活动状态。“值已更改”是分段控件连接的操作。

        11
  •  1
  •   Bryan    15 年前

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

        12
  •  1
  •   saurabh    15 年前

    我按照以下步骤创建了类似按钮的系统删除按钮,如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
  •   Patch    14 年前

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

    UI按钮+彩色背景。英语字母表的第8个字母

    //  UIButton+ColoredBackground.h
    
    #import <UIKit/UIKit.h>
    
    @interface UIButton (ColoredBackground)
    
    - (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;
    + (UIColor *) silverColor;
    
    @end
    

    UI按钮+彩色背景。男性

    //  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
  •   Domness    17 年前

    keremk说得对,当你点击按钮并进入检查器时,改变“视图”背景颜色。这会将小角落变成你选择的任何颜色。

        15
  •  0
  •   Jacob Jennings    14 年前

    colored UIButton

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

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

    #import <QuartzCore/QuartzCore.h>
    
    colorizeOverlayView.layer.cornerRadius = 10.0f;
    colorizeOverlayView.layer.masksToBounds = YES;
    
        16
  •  0
  •   T.J.    13 年前

    在@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]];
    }
    

    请确保按钮类型为自定义,否则可能无法调用drawRect。

        17
  •  0
  •   user3743847    11 年前

    所以,我找到了一个使用类别的非常简单的解决方案。 (太简单了,我想我一定是在做一些古怪的事情,但我没有看到!)

    为UIButton定义一个类别(如果你不知道那是什么,总之:这是一种最小化“扩展”类的方法;也就是说,向类中添加方法,但不添加属性),并创建一个方法“setBackgroundColor”来调用UIButton的超类(UIControl)的setBackgroundColor方法。

    @implementation UIButton (coloredBackgroundButton)
    
    -(void)setBackgroundColor:(UIColor *)backgroundColor {
        [super setBackgroundColor:backgroundColor];
    }
    

    无论在何处使用UIButtons,只要导入声明此类别的头文件,在这种情况下,

    #import "coloredBackgroundButton.h" 
    

    您可以对它们调用setBackgroundColor。

        18
  •  -2
  •   Laurel Enrique    8 年前

    也许我误解了你的问题,但下面不适合你吗?