Как установить пользовательский цвет фона кнопки?
Интерфейс Builder, похоже, не имеет интерфейса для этого.
Доступно ли это только программно? Если да, можете ли вы привести пример, пожалуйста?
Как установить пользовательский цвет фона кнопки?
Интерфейс Builder, похоже, не имеет интерфейса для этого.
Доступно ли это только программно? Если да, можете ли вы привести пример, пожалуйста?
Я прочитал ваш вопрос, чтобы потребовать (как и я) программный способ установить цвет кнопки. Это явное упущение из 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];
Обратите внимание, что свойства momentary
и segmentedControlStyle
имеют значение, а изображение можно использовать вместо имени NSString *
.
Растяжимое изображение с торцевыми крышками прекрасно работает, если вы можете использовать конечный набор консервированных изображений, но это не соответствует требованиям! Например.
buttonImage = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:26 topCapHeight: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];
Установка цвета фона для кнопки с закругленными углами не изменяет цвет фона кнопки. Попробуйте сделать кнопку пользовательской кнопкой (первый раскрывающийся список в инспекторе), а затем установите цвет фона. Вы получите желаемый эффект:)
Кажется, что цвет кнопки по-прежнему является проблемой. Следующая категория полностью устанавливает программный код кнопки через метод экземпляра, который принимает параметр UIColor. Нет необходимости создавать файлы 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 size
CGSize gcSize = tcv.frame.size;
UIGraphicsBeginImageContext(gcSize);
// add tcv layer to context
[tcv.layer renderInContext:UIGraphicsGetCurrentContext()];
// create background image now
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// set image as button 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];
http://github.com/dermdaly/ButtonMaker
Вы можете создать изображение UIbutton с помощью этого приложения... и можете установить его как фоновое изображение вашей кнопки
Задайте тип кнопки "custom" в палитре атрибутов кнопок. Это даст вам квадратную кнопку с любым цветом, который вы выбрали для фона.
Если вам нужна кнопка, которая больше похожа на традиционную кнопку, но имеет другой цвет, вам понадобится перейти в какое-то программное обеспечение для редактирования изображений и создать его (я использую Photoshop для пользовательских кнопок).
Эта ссылка обеспечивает элегантное решение вашей проблемы... http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/
Чтобы закруглить кнопку, как насчет использования
view.layer.cornerRadius = 8;
описанный здесь
Я немного изменил версию кода @Patch. Проблема для меня заключалась в том, что старая версия растягивала угловой радиус грязного при переключении с портретного на альбомный. Таким образом, я сделал эту версию use 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 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
Использование не изменилось. Теперь он выглядит яснее по краям, и я также использовал градиент, чтобы сделать больше пластика. но вы также можете удалить это.
Я решил эту проблему, создав собственную кнопку в Fireworks. Я нарисовал округленный прямоугольник размером с размер, который я хотел, с цветом заливки и цветом границы, который я хотел. Обрежьте холст и сохраните его как PNG. В XCode добавьте файл в папку "Ресурсы". Вы можете использовать пользовательскую кнопку в Interface Builder и указать изображение как PNG. Он изменит размер по мере необходимости, поместит текст сверху и т.д. Кривая углов может исказиться, если вам придется значительно изменить размер оригинала.
Решение Тима Джеймса (односегментный сегментированный контроль) работало для меня, когда мне нужна простая кнопка "Сохранить" с приличным фоном синего градиента. Я просто создал 2-сегментный элемент управления в nib, настроил первый сегмент, как я этого хотел, а затем программно удалил второй сегмент под -viewWillAppear, используя [mySegmentedControl removeSegmentAtIndex: 1 анимированный: НЕТ]. Для моих целей "Momentary" должен был быть активным (отмечен) для сегмента Segmented Control первого сегмента в циферблате, а "Selected" неактивен для любого сегмента. "Value Changed" - это действие Сегментированное управление для подключения.
Вот бесплатное приложение, которое я создал, которое создает изображения UIGlassButton. Установите тип кнопки в обычном режиме. http://itunes.apple.com/us/app/uibutton-builder/id408204223?mt=8
Я сделал это следующим образом, чтобы создать кнопку, например, кнопку удаления системы, как в 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 и добавьте эту структуру в свой проект.
Здесь вариант для решения @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 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];
keremk был прав, когда он сказал, чтобы изменить цвет фона "вид", когда вы нажали на кнопку и вошли в инспектор. Это изменяет маленькие углы в любой цвет, который вы выбрали.
Если вы не хотите использовать изображения и хотите, чтобы он выглядел точно так же, как стиль Rounded Rect, попробуйте это. Просто поместите UIView над UIButton, с идентичной рамкой и маской автоматического изменения размера, установите альфа-значение в 0.3 и установите фон в цвет. Затем снимите снимок ниже, чтобы скопировать закругленные края с цветного наложения. Кроме того, снимите флажок "Взаимодействие с пользователем" в IB на UIView, чтобы позволить событиям касания каскадом вниз к UIButton под ним.
Один побочный эффект заключается в том, что ваш текст также будет раскрашен.
#import <QuartzCore/QuartzCore.h>
colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;
Продолжая работу над @Denny1989 Я решил проблему получения ошибок (недопустимый контекст 0x0) при настройке кнопки в viewDidLoad. Кнопка должна быть выложена до того, как она будет иметь размер и, следовательно, не может зависеть, пока не появится представление. Эта категория добавляет цвет для 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 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, который нельзя вызвать.
Итак, я нашел невероятно простое решение с использованием категорий. (Так просто, что я думаю, что я должен делать что-то взломанное, но я этого не вижу!)
Определите категорию (если вы не знаете, что это такое, в итоге: это способ "расширить" класс минимально, то есть добавлять методы к классу, но без свойств) для UIButton, и создать метод "setBackgroundColor", который вызывает метод UIButton super class (UIControl) setBackgroundColor.
@implementation UIButton (coloredBackgroundButton)
-(void)setBackgroundColor:(UIColor *)backgroundColor {
[super setBackgroundColor:backgroundColor];
}
Если вы используете UIButtons, пока вы импортируете заголовочный файл, в котором объявлена эта категория, в этом случае
#import "coloredBackgroundButton.h"
вы можете вызвать setBackgroundColor на них.
Возможно, я неправильно понял ваш вопрос, но не работает ли ниже для вас?
alt text http://img.skitch.com/20081216-fgi9eew577fncx2k3bbw3yc28d.png