ios - Цветовой оттенок UIButton Image




iphone ios7 (10)

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


Swift 4 с customType:

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

В 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 для Template Image, а затем вам не нужно специально объявлять его в var exampleImage больше


Для 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);

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

- (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;
}

Изменить изображение кнопки или цвет оттенка изображения Swift:

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

btn.imageView? .tintColor = #colorLiteral (красный: 0, зеленый: 0, синий: 0, альфа: 1)


Как уже упоминал Ric в своем post вы можете установить режим рендеринга в коде, вы также можете сделать это прямо в каталоге изображений, см. Прикрепленное изображение ниже. Просто установите Render As to Template Image

Предостережение У меня были проблемы с iOS 7 и этим подходом. Поэтому, если вы используете iOS 7, вы также можете сделать это в коде, чтобы быть уверенным, как описано post .


Не уверен, что именно вы хотите, но метод этой категории замаскирует 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];

Ни один из вышеперечисленных не работал для меня, потому что оттенок был очищен после клика. Мне пришлось использовать

button.setImageTintColor(Palette.darkGray(), for: UIControlState())

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)

Swift 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 .







uisegmentedcontrol