Зображення кольорового відтінку UIButton


294

Я помітив, що коли я поміщаю білий або чорний колір UIImageв нього, UISegmentedControlвін автоматично маскує його, щоб він відповідав відтінку сегментованого елемента управління. Я подумав, що це дійсно круто, і мені було цікаво, чи можу я це зробити і в інших місцях. Наприклад, у мене є купа ґудзиків, які мають однакову форму, але різноманітні кольори. Замість того, щоб створити PNG для кожної кнопки, чи можу я якось за допомогою цього кольорового маскування використовувати однакове зображення для всіх, але потім встановити колір відтінку чи щось, щоб змінити їх власний колір?


Чи можете ви розмістити зображення, яке ви хочете використовувати, а також зображення для бажаного результату?
Пратюша Терлі

це робити те ж саме з інтерфейсом будівельник stackoverflow.com/a/25179217/2051381
Chuy47

Відповіді:


619

Як і в iOS 7, існує новий метод UIImageвказувати режим візуалізації. Використання режиму візуалізації UIImageRenderingModeAlwaysTemplateдозволить керувати кольором зображення кольором відтінку кнопки.

Ціль-С

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [[UIImage imageNamed:@"image_name"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[button setImage:image forState:UIControlStateNormal]; 
button.tintColor = [UIColor redColor];

Швидкий

let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red

14
Я думаю, що краще використовувати button.imageView.tintColor
М.Отман

3
@ M.Othman працює для мене лише тоді, коли я використовую button.tintColor, а не button.imageview.tintColor
pnizzle

32
Просто пам’ятайте, щоб встановити режим візуалізації зображення на зображенні у xcassets per @hashier
Dean

23
Створення UIButton типу UIButtonTypeSystem автоматично вшановує встановлений вами tintColor.
carloshwa

4
Якщо у вас tintColorзанадто темно, переконайтесь, що adjustsImageWhenHighlightedНІ. (Або в IB: "Виділене коригування зображення" не знімається.)
Джейсон Мур

225

Як Рік вже згадував у своєму дописі, ви можете встановити режим візуалізації в коді, ви також можете це зробити безпосередньо в каталозі зображень, див. Додане зображення нижче. Просто встановіть Render AsнаTemplate Image

введіть тут опис зображення

Caveat У мене були проблеми з iOS 7 та таким підходом. Тож якщо ви також використовуєте iOS 7, можливо, ви хочете це зробити і в коді, щоб бути впевненим, як описано тут .


1
Як бічна примітка, файл зображення має бути чорним і прозорим (не чорно-білим)
Axel Guilmin

6
@AxelGuilmin не дуже. Ваше зображення може бути будь-якого забарвленого кольору та прозорого. Будь-який колір, відмінний від прозорого, буде перетворений на загальний, і тоді він буде зафарбований чорним кольором за замовчуванням.
Алехандро Іван

90

Спеціальні кнопки відображаються у відповідних кольорах зображення. Якщо встановити тип кнопки на "Система" на аркуші розкадрування (або UIButtonTypeSystemв коді), виведе зображення кнопки з кольором відтінку за замовчуванням.

Тип кнопки Система надає піктограми тонованими

(перевірено на iOS9, Xcode 7.3)


2
Цього можна уникнути, запропонованими тут завжди методами шаблону та tintColor. З перевагою кнопки .system ви отримуєте зміну кольору з натисканням на кран.
Кріс Принс

44

Ви повинні встановити режим візуалізації зображення UIImageRenderingModeAlwaysTemplate, щоб tintColorвплинути на UIImage. Ось рішення у Swift:

let image = UIImage(named: "image-name")
let button = UIButton()
button.setImage(image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), forState: .Normal)
button.tintColor = UIColor.whiteColor()

SWIFT 4x

button.setImage(image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate), for: .normal)
button.tintColor = UIColor.blue

28

Якщо у вас є спеціальна кнопка з фоновим зображенням. Ви можете встановити колір відтінку вашої кнопки та змінити зображення на наступне.

В активах виберіть фон кнопки, для якої потрібно встановити колір відтінку.

В інспекторі атрибутів зображення встановіть значення візуалізації як "Зображення шаблону"

введіть тут опис зображення

Тепер, коли ви встановите button.tintColor = UIColor.red, кнопка відображатиметься червоним кольором.


якщо ви тут, перейдіть за цим посиланням: useyourloaf.com/blog/styling-buttons-using-the-asset-catalog та перейдіть до зображень шаблону (щоб послужити поясненням)
cspam

Це краще рішення, оскільки воно зменшує код і майже робить те саме, що і прийнята відповідь.
ДС.

Я думаю, це має бути правильним. менший код і простий в обробці.
Umair_UAS

17

У Swift це можна зробити так:

var exampleImage = UIImage(named: "ExampleImage.png")?.imageWithRenderingMode(.AlwaysTemplate)

Тоді на ваш поглядDidLoad

exampleButtonOutlet.setImage(exampleImage, forState: UIControlState.Normal)

І щоб змінити колір

exampleButtonOutlet.tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) //your color

EDIT Xcode 8 Тепер ви можете просто рендеринга режим зображення в ваших .xcassets для шаблону зображення і тоді вам не потрібно спеціально оголосити його в var exampleImageбільше


14

Не впевнений, що саме ви хочете, але цей метод категорії маскує UIImage вказаним кольором, щоб ви могли мати одне зображення та змінити його колір на все, що завгодно.

ImageUtils.h

- (UIImage *) maskWithColor:(UIColor *)color;

ImageUtils.m

-(UIImage *) maskWithColor:(UIColor *)color 
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width;
    CGFloat height = self.size.height;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);    
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;    
}

Імпортуйте категорію ImageUtils і зробіть щось подібне ...

#import "ImageUtils.h"

...

UIImage *icon = [UIImage imageNamed:ICON_IMAGE];

UIImage *redIcon = [icon maskWithColor:UIColor.redColor];
UIImage *blueIcon = [icon maskWithColor:UIColor.blueColor];

3
Використовуйте kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLastнаCGBitmapContextCreate
Луїс Ascorbe

4
Приємно, але його потрібно підробити для графіки Retina ... Коли я запускаю це на зображенні Retina, воно повертає мені неретина.
jowie

Для підтримки пристроїв Retina можна використовувати масштаб властивість UIDeviceкласу: властивість існує як з прошивки 4.0. CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale;scale
Філіп Фрішмут

Також потрібно використовувати scaleзначення, коли UIImageстворено:UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
Philipp Frischmuth

8

Swift 4 з користувальницьким типом:

let button = UIButton(frame: aRectHere)
    let buttonImage = UIImage(named: "imageName")
    button.setImage(buttonImage?.withRenderingMode(.alwaysTemplate), for: .normal)
    button.tintColor = .white

5

Для Xamarin.iOS (C #):

        UIButton messagesButton = new UIButton(UIButtonType.Custom);
        UIImage icon = UIImage.FromBundle("Images/icon.png");
        messagesButton.SetImage(icon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
        messagesButton.TintColor = UIColor.White;
        messagesButton.Frame = new RectangleF(0, 0, 25, 25);

5

Швидкий 3 :

Це рішення може бути зручним, якщо ви вже встановили своє зображення через програму інтерфейсів xCode. В основному у вас є одне розширення, щоб розфарбувати зображення:

extension UIImage {
    public func image(withTintColor color: UIColor) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(CGBlendMode.normal)
        let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context.clip(to: rect, mask: self.cgImage!)
        color.setFill()
        context.fill(rect)
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }
}

Потім ви можете підготувати це розширення UIButton, щоб розфарбувати зображення для певного стану:

extension UIButton {
    func imageWith(color:UIColor, for: UIControlState) {
        if let imageForState = self.image(for: state) {
            self.image(for: .normal)?.withRenderingMode(.alwaysTemplate)
            let colorizedImage = imageForState.image(withTintColor: color)
            self.setImage(colorizedImage, for: state)
        }
    }
}

Використання:

myButton.imageWith(.red, for: .normal)

PS (добре працює і в клітинках таблиці, вам не потрібно викликати setNeedDisplay()метод, зміна кольору відбувається негайно через розширення UIImage .


3

Якщо ви хочете вручну замаскувати зображення, тут оновлений код, який працює з екранами сітківки

- (UIImage *)maskWithColor:(UIColor *)color
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width * self.scale;
    CGFloat height = self.size.height * self.scale;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:self.scale orientation:self.imageOrientation];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;
}

2

Ви повинні спробувати

Після встановлення кадру

NSArray *arr10 =[NSArray arrayWithObjects:btn1,btn2,nil];
for(UIButton *btn10 in arr10)
{
CAGradientLayer *btnGradient2 = [CAGradientLayer layer];
btnGradient2.frame = btn10.bounds;

btnGradient2.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:151.0/255.0f green:206.0/255.5 blue:99.0/255.0 alpha:1] CGColor],
                       (id)[[UIColor colorWithRed:126.0/255.0f green:192.0/255.5 blue:65.0/255.0 alpha:1]CGColor],
                       nil];
[btn10.layer insertSublayer:btnGradient2 atIndex:0];

}

2

Swift 3.0

    let image = UIImage(named:"NoConnection")!

 warningButton = UIButton(type: .system)        
    warningButton.setImage(image, for: .normal)
    warningButton.tintColor = UIColor.lightText
    warningButton.frame = CGRect(origin: CGPoint(x:-100,y:0), size: CGSize(width: 59, height: 56))

    self.addSubview(warningButton)

1

Зміна зображення кнопки чи кольору зображення відтінку кольору Swift:

btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)

btn.imageView?.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)

-1

Ніщо з вищезгаданого не працювало для мене, оскільки відтінок очистився після клацання. Мені довелося користуватися

button.setImageTintColor(Palette.darkGray(), for: UIControlState())
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.