Можно ли изменить цвет фона UIButtons?

105

Этот меня поставил в тупик.

Можно ли вообще изменить цвет фона UIButton в Какао для iPhone. Я пробовал установить цвет фона, но он меняет только углы. setBackgroundColor:кажется, единственный доступный метод для таких вещей.

[random setBackgroundColor:[UIColor blueColor]];
[random.titleLabel setBackgroundColor:[UIColor blueColor]];
дуббит
источник
вы можете исправить изображение или удалить его? kthx;)
stigi
о-0 хмммм ....., изображение было в порядке, но теперь оно больше не отображается. Просто удалил
дуббит
Это дубликат stackoverflow.com/questions/372731/…
Брэд Ларсон
Я решаю эту проблему в моем предыдущем сообщении, пожалуйста, проверьте ссылку [Динамически изменять границу или фон UIButton] [1] [1]: stackoverflow.com/questions/9733213/…
БЕССМЕРТНО
здесь можно
Shamsudheen TK

Ответы:

160

Это можно сделать программно, сделав реплику:

loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
loginButton.backgroundColor = [UIColor whiteColor];
loginButton.layer.borderColor = [UIColor blackColor].CGColor;
loginButton.layer.borderWidth = 0.5f;
loginButton.layer.cornerRadius = 10.0f;

изменить: конечно, вам придется #import <QuartzCore/QuartzCore.h>

edit: всем новым читателям вы должны также рассмотреть несколько добавленных опций как «еще одну возможность». для вашего рассмотрения.

Поскольку это старый ответ, я настоятельно рекомендую прочитать комментарии для устранения неполадок.

Стиан Сторрвик
источник
Это то, что ищет OP.
Стивен
4
сладкий! Из всех найденных мною солнца я выбрал именно этот. В качестве пояснения: создание «реплики» означает использование Quartz для рисования скругленного прямоугольника в пользовательской кнопке, а не использование кнопки типа RoundedRect. Сначала я подумал, что это означает создание дубликата закругленного прямоугольника другого цвета, чтобы имитировать изменение цвета bg.
Давер 01
1
Работал отлично, лучший ответ на OP. Спасибо, что поделился.
Bram
@daver: Этот ответ настолько популярен, что, должно быть, заслуживает того, что мне не хватает. Как можно изменить цвет фона в зависимости от состояния? Предположительно, нужно явно менять цвет фона каждый раз при изменении состояния. Моя кнопка отключается при нажатии, пока не ответит веб-служба. Должен ли я изменить цвет выделения при нажатии и переключить таймер на отключенный цвет, ожидая ответа ws? Если я не понимаю сути, может кто-нибудь объяснить. Спасибо, Полли.
Polly
1
@Polly: Извините, не видел ваш комментарий раньше, но если вам все еще интересно, вот что я в итоге сделал: подкласс UIButton и переопределите drawRect: для рисования закругленного прямоугольника с использованием некоторых UIBezierPaths. После рисования залейте его градиентом с помощью CGGradientCreateWithColorComponents (). Одним из аргументов этой функции является 4-элементный массив чисел с плавающей запятой (соответствующий R, G, B и альфа). Я определил 2 цветовых массива, по одному для каждого состояния, и выбрал подходящий в drawRect на основе состояния кнопки.
Давер
59

У меня другой подход,

[btFind setTitle:NSLocalizedString(@"Find", @"") forState:UIControlStateNormal];    
[btFind setBackgroundImage:[CommonUIUtility imageFromColor:[UIColor cyanColor]] 
        forState:UIControlStateNormal];
btFind.layer.cornerRadius = 8.0;
btFind.layer.masksToBounds = YES;
btFind.layer.borderColor = [UIColor lightGrayColor].CGColor;
btFind.layer.borderWidth = 1;

Из CommonUIUtility,

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

Не забывай #import <QuartzCore/QuartzCore.h>

Карим
источник
2
Хороший. Я обнаружил, что должен добавитьbtFind.layer.borderWidth = 1;
DefenestrationDay
Мне нравится это решение, но на данный момент я не могу им воспользоваться. Я получаю сообщение об ошибке, потому что "CommonUIUtility" не может быть найден. Google просто дает мне материал о затмении, но я думаю, он должен быть в QuartzCore? Любые идеи?
Стефан
Нет, это определяемый пользователем класс для выполнения общих функций пользовательского интерфейса в приложении. Вы пишете метод imageFromColor в своем собственном классе.
Карим
1
Пахнет как метод категории на UIButton: setBackgroundColor:(UIColor *) forState:(UIControlState).
EthanB
3
Это так глупо, что мы на iOS 7, и это ВСЕ ЕЩЕ самый чистый способ добавить цвет фона
dmur
32

Полагаю, вы говорите о UIButton с UIButtonTypeRoundedRect? Вы не можете изменить цвет фона. Когда вы пытаетесь изменить цвет фона, вы скорее меняете цвет прямоугольника, на котором нарисована кнопка (который обычно ясен). Итак, есть два пути. Либо вы создаете подкласс UIButton и перезаписываете его -drawRect:метод, либо создаете изображения для различных состояний кнопки (что вполне нормально).

Если вы установите фоновые изображения в Interface Builder, вы должны заметить, что IB не поддерживает установку изображений для всех состояний, которые может иметь кнопка, поэтому я рекомендую установить изображения в коде следующим образом:

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setBackgroundImage:[UIImage imageNamed:@"normal.png"] forState:UIControlStateNormal];
[myButton setBackgroundImage:[UIImage imageNamed:@"disabled.png"] forState:UIControlStateDisabled];
[myButton setBackgroundImage:[UIImage imageNamed:@"selected.png"] forState:UIControlStateSelected];
[myButton setBackgroundImage:[UIImage imageNamed:@"higligted.png"] forState:UIControlStateHighlighted];
[myButton setBackgroundImage:[UIImage imageNamed:@"highlighted+selected.png"] forState:(UIControlStateHighlighted | UIControlStateSelected)];

В последней строке показано, как установить изображение для выбранного и выделенного состояния (это то, что IB не может установить). Вам не нужны выбранные изображения (строки 4 и 6), если вашей кнопке не нужно выбранное состояние.

Стиги
источник
Спасибо за объяснение. Просто быстрый вопрос. Если я переписываю метод drawrect, я думаю, это потребует от меня использования библиотеки рисования? Что-то одно - линии программного рисования прямоугольника с закругленными углами и заливки его цветом?
даббит
2
Я только что сделал короткий запрос в Google по запросу «iphone drawrect round corner» и нашел это: iphonedevelopment.blogspot.com/2008/11/… Проверьте метод drawrect, чтобы увидеть, как нарисовать круглый прямоугольник. Вы можете использовать CGContextSetFillColorWithColorи CGContextFillPathдля заполнения нарисованного пути CGContextAddArcToPoint.
stigi
2
+50 за указание на потенциал битовой маски для состояний управления, например: forState:(UIControlStateHighlighted | UIControlStateSelected)Ура.
NSTJ
28

Другая возможность:

  1. Создайте UIButton в построителе интерфейсов.
  2. Присвойте ему тип Custom
  3. Теперь в IB можно изменить цвет фона

Однако кнопка квадратная, а это не то, что нам нужно. Создайте IBOutlet со ссылкой на эту кнопку и добавьте следующее в метод viewDidLoad:

[buttonOutlet.layer setCornerRadius:7.0f];
[buttonOutlet.layer setClipToBounds:YES];

Не забудьте импортировать QuartzCore.h

Wubbe
источник
7
Отлично спасибо! Я не уверен, что это из-за версии iOS, которую я использую (5.1), но setClipToBounds был недоступен. Вместо этого я использовал buttonOutlet.layer.masksToBounds = TRUE;
iforce2d
Когда я добавляю этот код, он показывает прямоугольник с закругленными углами, но когда я нажимаю на него, кнопка не меняет выделение. Что происходит?
Will
Проблема с этим подходом заключается в том, что вы не можете установить цвет фона для выделенного состояния кнопки.
ch3rryc0ke
17

Подкласс UIButton и переопределите методы setHighlighted и setSelected

-(void) setHighlighted:(BOOL)highlighted {

  if(highlighted) {
    self.backgroundColor = [self.mainColor darkerShade];
  } else {
    self.backgroundColor = self.mainColor;
  }
  [super setHighlighted:highlighted];
}

-(void) setSelected:(BOOL)selected {

  if(selected) {
    self.backgroundColor = [self.mainColor darkerShade];
  } else {
    self.backgroundColor = self.mainColor;
  }
  [super setSelected:selected];
}

Мой метод darkerShade находится в такой категории UIColor

-(UIColor*) darkerShade {

  float red, green, blue, alpha;
  [self getRed:&red green:&green blue:&blue alpha:&alpha];

  double multiplier = 0.8f;
  return [UIColor colorWithRed:red * multiplier green:green * multiplier blue:blue*multiplier alpha:alpha];
}
Mugunth
источник
7

цветной UIButton

Если вы не хотите использовать изображения и хотите, чтобы они выглядели точно так же, как стиль Rounded Rect, попробуйте это. Просто поместите UIView поверх UIButton с идентичной рамкой и маской автоматического изменения размера, установите альфа-канал на 0,3 и установите цвет фона. Затем используйте приведенный ниже фрагмент, чтобы вырезать закругленные края цветного наложения. Кроме того, снимите флажок «Взаимодействие с пользователем включено» в IB в UIView, чтобы разрешить событиям касания каскадно переходить в UIButton внизу.

Одним из побочных эффектов является то, что ваш текст также будет раскрашен.

#import <QuartzCore/QuartzCore.h>

colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;
Джейкоб Дженнингс
источник
7

Другой вариант (лучший и самый красивый imho):

Создайте UISegmentedControl с 2 сегментами требуемого цвета фона в Интерфейсном Разработчике. Установите тип "бар". Затем измените его на один сегмент. Конструктор интерфейсов не принимает один сегмент, поэтому вам придется делать это программно.

Поэтому создайте IBOutlet для этой кнопки и добавьте его в viewDidLoad вашего представления:

[segmentedButton removeSegmentAtIndex:1 animated:NO];

Теперь у вас есть красивая глянцевая цветная кнопка с заданным цветом фона. Для действий используйте событие «значение изменено».

(Я нашел это на http://chris-software.com/index.php/2009/05/13/creating-a-nice-glass-buttons/ ). Спасибо, Крис!

Wubbe
источник
5

Что ж, я на 99% уверен, что вы не можете просто пойти и изменить цвет фона UIButton. Вместо этого вы должны пойти и самостоятельно изменить фоновые изображения, что, на мой взгляд, является проблемой. Я удивлен, что мне пришлось это сделать.

Если я ошибаюсь или есть лучший способ без установки фоновых изображений, дайте мне знать

[random setBackgroundImage:[UIImage imageNamed:@"toggleoff.png"] forState:UIControlStateNormal];
    [random setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];


[random setBackgroundImage:[UIImage imageNamed:@"toggleon.png"] forState:UIControlStateNormal];
    [random setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
дуббит
источник
5
Ты совершенно прав. Это боль, и на ее выполнение должно уйти несколько минут вместо хлопот по созданию изображений. К тому же, если у вас круглая пуговица, сделать это будет еще труднее ... Такая боль.
Хенли Чиу,
2

Согласно предложению @EthanB и @karim, создающему прямоугольник с обратной заливкой, я просто создал категорию для UIButton, чтобы добиться этого.

Просто введите код категории: https://github.com/zmonteca/UIButton-PLColor

Использование:

[button setBackgroundColor:uiTextColor forState:UIControlStateDisabled];

Необязательно использовать forStates:

UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected
Zmonteca
источник
2

Вы также можете добавить CALayer к кнопке - вы можете делать с ними много вещей, включая наложение цвета, в этом примере используется простой цветной слой, вы также можете легко градуировать цвет. Имейте в виду, что добавленные слои закрывают нижние слои.

+(void)makeButtonColored:(UIButton*)button color1:(UIColor*) color
{

    CALayer *layer = button.layer;
    layer.cornerRadius = 8.0f;
    layer.masksToBounds = YES;
    layer.borderWidth = 4.0f;
    layer.opacity = .3;//
    layer.borderColor = [UIColor colorWithWhite:0.4f alpha:0.2f].CGColor;

    CAGradientLayer *colorLayer = [CAGradientLayer layer];
    colorLayer.cornerRadius = 8.0f;
    colorLayer.frame = button.layer.bounds;
    //set gradient colors
    colorLayer.colors = [NSArray arrayWithObjects:
                         (id) color.CGColor,
                         (id) color.CGColor,
                         nil];

    //set gradient locations
    colorLayer.locations = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:0.0f],
                            [NSNumber numberWithFloat:1.0f],
                            nil];


    [button.layer addSublayer:colorLayer];

}
топленое масло
источник
Гениально !!!!!! Но нельзя было коллировать несколько раз против одной и той же кнопки. Мог, но новые слои добавляются снова и снова.
Валерий Ван
@StanJames: изменения в коде следует предлагать в комментарии (или, если необходимо, в вашем собственном ответе).
mafso
1

добавьте вторую цель для UIButtonfor UIControlEventTouchedи измените UIButtonцвет фона. Затем верните его в UIControlEventTouchUpInsideцель;

Шон
источник
1

Для профессиональных и красивых кнопок вы можете проверить этот компонент настраиваемой кнопки . Вы можете использовать его непосредственно в ваших представлениях и таблицах или изменить исходный код, чтобы он соответствовал вашим потребностям. Надеюсь это поможет.

Ахмет Ардал
источник
1

Это не так элегантно, как подкласс UIButton, однако если вам просто нужно что-то быстрое - я создал настраиваемую кнопку, затем изображение размером 1 на 1 пиксель с цветом, который я хотел бы, чтобы кнопка была, и установил фон кнопки к этому изображению для выделенного состояния - работает для моих нужд.

SMSidat
источник
1

Я знаю, что об этом спрашивали давно, и теперь есть новая UIButtonTypeSystem. Но новые вопросы помечаются как дубликаты этого вопроса, поэтому вот мой новый ответ в контексте системной кнопки iOS 7, используйте .tintColorсвойство.

let button = UIButton(type: .System)
button.setTitle("My Button", forState: .Normal)
button.tintColor = .redColor()
ДоннаЛея
источник
0

[myButton setBackgroundColor:[UIColor blueColor]]; [myButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

Можно изменить этот способ или перейти на раскадровку и изменить фон в параметрах справа.

Винисиус Карвалью
источник
0

Swift 3:

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

        let button = UIButton(type: .system)
        let image = imageFromColor(color: .red, width: 
        button.frame.size.width, height: button.frame.size.height)
        button.setBackgroundImage(image, for: .normal)
pawurb
источник
Это был бы гораздо более полезный ответ, если бы вы сказали, как вызывать или использовать код, который вы там разместили. Он входит в расширение UIButton?
Michael Dautermann