Màu sắc hình ảnh UIButton


294

Tôi nhận thấy rằng khi tôi đặt một màu trắng hoặc đen UIImagevào UISegmentedControlnó, nó sẽ tự động tô màu nó để phù hợp với tông màu của điều khiển được phân đoạn. Tôi nghĩ rằng điều này thực sự tuyệt vời, và tự hỏi liệu tôi có thể làm điều này ở nơi khác không. Ví dụ, tôi có một loạt các nút có hình dạng đồng nhất nhưng màu sắc đa dạng. Thay vì tạo một PNG cho mỗi nút, bằng cách nào đó tôi có thể sử dụng mặt nạ màu này để sử dụng cùng một hình ảnh cho tất cả chúng nhưng sau đó đặt màu sắc hoặc một cái gì đó để thay đổi màu thực tế của chúng?


Bạn có thể đăng hình ảnh mà bạn muốn sử dụng và hình ảnh cho kết quả mong muốn?
Pratyusha Terli

điều này làm tương tự từ trình xây dựng giao diện stackoverflow.com/a/25179217/2051381
Chuy47

Câu trả lời:


619

Kể từ iOS 7, có một phương pháp mới UIImageđể chỉ định chế độ kết xuất. Sử dụng chế độ kết xuất UIImageRenderingModeAlwaysTemplatesẽ cho phép màu sắc hình ảnh được kiểm soát bởi màu sắc của nút.

Mục tiêu-C

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

Nhanh

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

14
Tôi nghĩ sẽ tốt hơn khi sử dụng button.imageView.tintColor
M.Othman 11/03/2015

3
@ M.Othman chỉ hoạt động với tôi khi tôi sử dụng button.tintColor chứ không phải button.imageview.tintColor
pnizzle

32
Chỉ cần nhớ đặt chế độ kết xuất hình ảnh trên hình ảnh trong xcassets mỗi @hashier
Dean

23
Tạo một UIButton loại UIButtonTypeSystem sẽ tự động tôn vinh tintColor bạn đặt.
carloshwa

4
Nếu bạn tintColorquá tối, hãy chắc chắn adjustsImageWhenHighlightedlà KHÔNG. (Hoặc trong IB: "Hình ảnh điều chỉnh nổi bật" không được chọn.)
Jason Moore

225

Như Ric đã đề cập trong bài đăng của mình, bạn có thể đặt chế độ kết xuất trong mã, bạn cũng có thể thực hiện việc này trực tiếp trong danh mục hình ảnh, xem hình ảnh đính kèm bên dưới. Chỉ cần đặt Render AsđểTemplate Image

nhập mô tả hình ảnh ở đây

Hãy cẩn thận Tôi đã có vấn đề với iOS 7 và cách tiếp cận này. Vì vậy, nếu bạn sử dụng iOS 7, bạn cũng có thể muốn làm điều đó bằng mã để đảm bảo, như được mô tả ở đây .


1
Lưu ý phụ, tệp hình ảnh phải có màu đen và trong suốt (không phải b & w)
Axel Guilmin

6
@AxelGuilmin không thực sự. Hình ảnh của bạn có thể là bất kỳ màu nào bạn muốn và trong suốt. Bất kỳ màu nào khác với màu trong suốt sẽ được chuyển đổi thành màu chung và sau đó nó sẽ được tô màu với màu đen theo mặc định.
Alejandro Iván

90

Nút tùy chỉnh xuất hiện trong màu sắc hình ảnh tương ứng của họ. Đặt loại nút thành "Hệ thống" trong bảng phân cảnh (hoặc thành UIButtonTypeSystemmã), sẽ hiển thị hình ảnh của nút với màu sắc mặc định.

Nút Kiểu hệ thống Trình bày biểu tượng nhuốm màu

(đã thử nghiệm trên iOS9, Xcode 7.3)


2
Điều này có thể tránh được với các phương thức alwaysTemplate và tintColor được đề xuất ở đây. Với lợi thế của nút .system là bạn có thể thay đổi màu sắc bằng cách chạm xuống trên vòi.
Hoàng tử Chris

44

Bạn phải đặt chế độ hiển thị hình ảnh thành UIImageRenderingModeAlwaysTemplateđể có tintColorảnh hưởng đến UIImage. Đây là giải pháp trong Swift:

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

Chuyển đổi gấp 4 lần

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

28

Nếu bạn có một nút tùy chỉnh với hình nền. Bạn có thể đặt màu sắc của nút và ghi đè hình ảnh bằng cách sau.

Trong tài sản, chọn nền nút bạn muốn đặt màu.

Trong trình kiểm tra thuộc tính của hình ảnh, đặt giá trị hiển thị thành "Hình ảnh mẫu"

nhập mô tả hình ảnh ở đây

Bây giờ bất cứ khi nào bạn đặt button.tintColor = UIColor.rednút của bạn sẽ được hiển thị màu đỏ.


nếu bạn ở đây, bạn có thể truy cập liên kết này: useyourloaf.com/blog/stomme-buttons-USE-the-asset-catalog và đi xuống hình ảnh mẫu (để phục vụ như một lời giải thích)
cspam

Đây là một giải pháp tốt hơn vì nó làm giảm mã và khá nhiều điều tương tự như câu trả lời được chấp nhận.
DS.

Tôi nghĩ rằng đây là một trong những chính xác. ít mã và dễ xử lý.
Umair_UAS

17

Trong Swift bạn có thể làm như vậy:

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

Sau đó, trong viewDidLoad của bạn

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

Và để sửa đổi màu sắc

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

EDIT Xcode 8 Bây giờ bạn cũng có thể chỉ cần chế độ kết xuất của hình ảnh trong .xcassets của bạn thành Mẫu hình ảnh và sau đó bạn không cần phải khai báo cụ thể trong hình var exampleImagenữa


14

Không chắc chắn chính xác những gì bạn muốn nhưng phương pháp thể loại này sẽ che dấu một UIImage với một màu được chỉ định để bạn có thể có một hình ảnh duy nhất và thay đổi màu sắc của nó thành bất cứ điều gì bạn muốn.

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

Nhập danh mục ImageUtils và làm một cái gì đó như thế này ...

#import "ImageUtils.h"

...

UIImage *icon = [UIImage imageNamed:ICON_IMAGE];

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

3
Sử dụng kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLastvàoCGBitmapContextCreate
Luis Ascorbe

4
Đẹp, nhưng cần phải được điều chỉnh cho đồ họa Retina ... Khi tôi chạy nó trên hình ảnh Retina, nó sẽ trả về cho tôi một hình ảnh không phải võng mạc.
jowie

Để hỗ trợ các thiết bị Retina bạn có thể sử dụng tài sản của quy mô UIDevicelớp: CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale;Các scaletài sản tồn tại như của iOS 4.0.
Philipp Frischmuth

Bạn cũng cần sử dụng scalegiá trị khi UIImageđược tạo:UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
Philipp Frischmuth

8

Swift 4 với customType:

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

5

Đối với 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

Swift 3 :

Giải pháp này có thể thoải mái nếu bạn đã giải quyết hình ảnh của mình thông qua trình tạo giao diện xCode. Về cơ bản, bạn có một tiện ích mở rộng để tô màu cho hình ảnh:

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

Sau đó, bạn có thể chuẩn bị tiện ích mở rộng UIButton này để tô màu hình ảnh cho một trạng thái cụ thể:

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)
        }
    }
}

Sử dụng:

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

PS (hoạt động tốt trong các ô của bảng, bạn không cần gọi setNeedDisplay()phương thức, việc thay đổi màu ngay lập tức là do phần mở rộng UIImage ..


3

Nếu bạn muốn che dấu thủ công hình ảnh của mình, đây là mã được cập nhật hoạt động với màn hình võng mạc

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

Bạn nên thử

Sau khi thiết lập khung

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

Thay đổi hình ảnh nút hoặc chế độ xem hình ảnh màu sắc Swift:

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

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

-1

Không có cái nào ở trên làm việc cho tôi, vì màu đã bị xóa sau khi nhấp. Tôi đã phải sử dụng

button.setImageTintColor(Palette.darkGray(), for: UIControlState())
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.