스토리 보드 / xib 파일에서 UIImage renderingMode 수정


답변:


101

.xib 또는 스토리 보드 파일에서 수행하는 방법은 다음과 같습니다.

(Obj-C) 카테고리 만들기 UIImageView:

@interface UIImageView (Utils)

- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode;

@end

@implementation UIImageView (Utils)

- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode
{
    NSAssert(self.image, @"Image must be set before setting rendering mode");
    self.image = [self.image imageWithRenderingMode:renderMode];
}

@end

(Swift 4) 다음에 대한 확장 만들기 UIImageView:

extension UIImageView {
    func setImageRenderingMode(_ renderMode: UIImage.RenderingMode) {
        assert(image != nil, "Image must be set before setting rendering mode")
        // AlwaysOriginal as an example
        image = image?.withRenderingMode(.alwaysOriginal)
    }
}

그런 다음 xib 파일의 Identity Inspector에서 런타임 속성을 추가합니다.

여기에 이미지 설명 입력


44
이 답변에 대해 제가 좋아하는 것은 질문에 대한 답변이라는 것입니다.
— algal 2014 년

1
키 값 설정을 수행하는 대신 UIImageView 하위 클래스를 만드는 것을 선호합니다. 왜냐하면 설정하기가 더 쉽고 열거 값에 대한 숫자 설정을 피할 수 있기 때문입니다. 예 :`@implementation TemplateRenderingImageView-(id) initWithCoder : (NSCoder *) aDecoder {self = [super initWithCoder : aDecoder]; if (self) {self.image = [self.image imageWithRenderingMode : UIImageRenderingModeAlwaysTemplate]; } return self; } @ end`
— 존 환상

1
좋은 대답입니다! 스크린 샷이 도움이되었습니다.
— BigSauce

1
물론 Launch Screen.xib에서는 작동하지 않습니다. 사용자 정의 런타임 속성을 사용할 수 없기 때문입니다.
— Steve Moser 2015 년

3
값으로 2를 하드 코딩하는 것은 나쁘다 나쁘다 나쁘다 .. xcassets 카탈로그를 사용하는 것이 정답입니다.
— tGilani

198

.xib파일이 아니라 .xcassets라이브러리 에서 이미지 렌더링 모드를 설정할 수 있습니다 .

자산 라이브러리에 이미지를 추가 한 후 이미지를 선택하고 Xcode의 오른쪽에서 속성 관리자를 엽니 다. 'Render As'속성을 찾아 'template'으로 설정합니다.

이미지의 렌더링 모드를 설정 한 후 틴트 색상을 UIImageView.xib 또는 에.storyboard 파일 하여 이미지 색상을 조정할 수 있습니다.

이것은 하나의 인터페이스 작성기 파일이 아닌 사용되는 위치에 관계없이 이미지의 속성을 설정하지만 거의 모든 경우 (내가 본 적이있는) 이것이 원하는 동작입니다.

이미지 속성 검사기를 보여주는 Xcode의 스크린 샷

참고할 몇 가지 사항 :

  • 이미지 색상은 인터페이스 빌더 (Xcode 6.1.1 기준)에서 변경된 것처럼 보이지 않지만 애플리케이션이 실행될 때 작동합니다.
  • 나는이 기능에 약간의 버그를 경험했고 어떤 상황에서 나는 제거하고 다시 추가해야했다 UIImageView . 나는 그것을 깊이 조사하지 않았습니다.
  • 이것은 또한 의 및 의 UIKitComponents이미지와 같은 다른 것에서도 잘 작동합니다 .UIButtonUIBarButtonItem
  • 자산 라이브러리에서 보이지 않는 흰색 이미지가 많이있는 경우 검은 색 / 투명한 이미지로 만들고 렌더링 모드를 변경하면 삶이 최대 10 배 향상됩니다.

15
색조 색상이 켜져있는 버그가있는 것 같습니다 UIImageView. 따라서 앱을 실행할 때 색조 색상이 항상 표시되지는 않습니다.
— Fogh

@Fogh 나도 그런 일관되지 않은 버그가 있습니다. 색조 색상을 프로그래밍 방식으로 설정하면 문제가 해결됩니까?
— Anthony Mattox

2
IB에서 틴트 색상을 설정할 때 문제가 있음을 확인할 수 있습니다. 프로그래밍 방식으로 설정하면 작동합니다. 버그 # 20305518을 제출했습니다.
— 니콜라이 Derkach

1
@AxelGuilmin 응. 실제로 알파 채널 만 사용되므로 투명도가 원하는 색상이면 모든 색상이 될 수 있습니다.
— Anthony Mattox

1
이제 Xcode 7.3 (7D175)에서 작동합니다! 허용되는 답변은 매우 직관적 인 해결 방법이지만 대신이 답변을 선호합니다.
— nstein

43

스토리 보드 또는 xib에서 UIImageView와 함께 템플릿 렌더링 모드를 사용하는 것은 iOS 7 및 iOS 8 모두에서 매우 버그가 많습니다.

iOS 7에서

UIImage가 스토리 보드 / xib에서 제대로 디코딩되지 않았습니다. 메서드 에서 imageView.image.renderingMode속성 을 검사하면 xcassets 파일에서 Render As Template Image 로 설정하더라도 viewDidLoad항상임을 알 수 있습니다.UIImageRenderingModeAutomatic

이 문제를 해결하려면 렌더링 모드를 수동으로 설정해야합니다.

self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

iOS 8에서

UIImage가 올바르게 디코딩되고 해당 renderingMode속성이 xcassets 파일에서 선택한 항목을 반영하지만 이미지에 색조가 적용되지 않습니다.

이 문제를 해결하려면 두 가지 옵션이 있습니다.

  1. 속성 관리자 창 대신 사용자 정의 런타임 속성tintColor 에서 속성을 설정합니다 .

또는

  1. tintColor를 수동으로 재설정합니다.
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;

원하는 옵션을 선택할 수 있으며 둘 다 이미지에 적절한 색조를 적용 할 수 있습니다.

(Xcode 6.2로 컴파일하는 경우 self.imageView.tintColor = self.imageView.tintColor; 에는 충분하지만 Xcode 6.3으로 컴파일하는 경우 더 이상 작동하지 않습니다.)

결론

iOS 7과 iOS 8을 모두 지원해야하는 경우 두 가지 해결 방법이 모두 필요합니다. iOS 8 만 지원해야하는 경우 하나의 해결 방법 만 필요합니다.


2
감사. Xcode 7 및 iOS 8에서는 해결 방법 # 2 만 저에게
— 효과적입니다.

3
나는 아이폰 OS 8에 대한 해결 방법은 아이폰 OS 9을 위해 또한 valable 있는지 확인
— 마이클 Pirotte

1
Xcode 7에서도 똑같은 현상이 발생합니다. 사용자 속성 해결 방법은 괜찮 았습니다. 감사!
— Geoffrey Wiseman

awakeFromNib에서 tintColor를 수동으로 재설정했습니다! (이미지는 .xcassets 카탈로그에서도 템플릿으로 설정되었습니다. 그렇지 않으면 원본에서 템플릿 이미지를 만들어야합니다). 감사!!
— horseshoe7

15

스토리 보드에서 색조 색상을 사용하도록 imageView RenderingMode를 설정하면 한 줄로 줄일 수 있습니다.

[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];

그런 다음 스토리 보드에서 이미지와 색조 색상을 모두 설정할 수 있습니다.


13

확장자를 사용하여 .xib 문제를 해결할 수 있습니다.

import UIKit

// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.tintColorDidChange()
    }
}

출처 : https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac

놀랍게도이 버그는 4 ~ 5 년 동안 존재했습니다.


3
이것은 응답으로 선택해야합니다
— farzadshbfn

여전히 버그이며 iOS 12.0부터 여전히 수정됩니다.
— Sam Soffes 2010 년

iOS 12.1의 여전히 버그
— Cesare

언리얼 녀석들, 언리얼.
— Mat

8

또는 renderingMode에서 설정할 수 없습니다 . 프로그래밍 방식으로 액세스 할 수 있습니다.storyboardxib

전의:

UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

3
코드에 작은 오타가있는 것 같습니다. 두 번째 줄이되어야합니다UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
— Artem Stepanenko 2013 년

8

Storyboard에서 tintColor 및 Class를 설정합니다.

//
//  TintColoredImageView.swift
//  TintColoredImageView
//
//  Created by Dmitry Utmanov on 14/07/16.
//  Copyright © 2016 Dmitry Utmanov. All rights reserved.
//

import UIKit

@IBDesignable class TintColoredImageView: UIImageView {

    override var image: UIImage? {
        didSet {
            let _tintColor = self.tintColor
            self.tintColor = nil
            self.tintColor = _tintColor
        }
    }


    override init(frame: CGRect) {
        super.init(frame: frame)
        initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initialize()
    }

    override init(image: UIImage?) {
        super.init(image: image)
        initialize()
    }

    override init(image: UIImage?, highlightedImage: UIImage?) {
        super.init(image: image, highlightedImage: highlightedImage)
        initialize()
    }

    func initialize() {
        let _tintColor = self.tintColor
        self.tintColor = nil
        self.tintColor = _tintColor
    }

}

이것은 새로운 스위프트에서 일한 유일한 답변입니다. 감사합니다.
— Simon Moshenko 2017-06-12

이상한 이유로 작동하지 않습니다 ... 스토리 보드의 색상을 업데이트해야합니까?
— Cesare

4

고치는 것은 매우 쉽습니다

UIImageViewPDF 클래스를 만들고 스토리 보드에서 사용하기 만하면됩니다.

IB_DESIGNABLE
@interface UIImageViewPDF : UIImageView

@end

@implementation UIImageViewPDF

- (void) didMoveToSuperview
{
    [super didMoveToSuperview];
    self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    id color = self.tintColor;
    self.tintColor = color;
}

@end

3

또 다른 해결책은 UIImageView하위 클래스 를 만드는 것입니다 .

final class TemplateImageView: UIImageView {
    override func awakeFromNib() {
        super.awakeFromNib()
        guard let oldImage = image else { return }
        image = nil
        image = oldImage.withRenderingMode(.alwaysTemplate)
    }
}

그런 다음 Interface Builder의 클래스를 TemplateImageView.


최고의 솔루션 !!
— Irshad Mohamed

2

Storyboard에서 설정하는 간단한 방법 :

@IBDesignable
public class CustomImageView: UIImageView {
    @IBInspectable var alwaysTemplate: Bool = false {
        didSet {
            if alwaysTemplate {
                self.image = self.image?.withRenderingMode(.alwaysTemplate)
            } else {
                self.image = self.image?.withRenderingMode(.alwaysOriginal)
            }

        }
    }
}

iOS 10 및 Swift 3에서 잘 작동합니다.


1

iOS 9 tintColor에서 Interface Builder 의 속성 설정 은 여전히 ​​버그가 있습니다.

ImageView속성을 직접 수정하는 줄을 작성하는 것 외에 작동하는 솔루션 은 자산 카탈로그에서 Render As : Template Image를 설정하고 예를 들어 다음을 호출하는 것입니다.

[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];

1

런타임 속성을 추가하여이 문제를 해결했습니다. tintColor인터페이스 빌더에 .

참고 : 이미지를 Images.xcassets 파일에서 템플릿 이미지로 렌더링하도록 설정해야합니다.

여기에 이미지 설명 입력


0

IBOutlet을 만들면 awakeFromNib 메서드에서 다음과 같이 변경할 수 있습니다.

self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

@Moby의 대답이 더 정확하지만 이것은 더 간결 할 수 있습니다.


1
문제는 코드가 아닌 스토리 보드 (또는 xib)에서이를 수행하는 방법이었습니다.
— Artem Stepanenko 2014 년

@artem-예, 죄송합니다. 귀하의 질문에 대한 답변이 있다고 추론하려는 의도가 없었습니다. IBOutlet을 통해이를 처리하는 간단한 방법을 지적하기
— 만하면됩니다

0

미친이 버그는 여전히 iOS 12.1에 있습니다! 스토리 보드 / xibs의 경우 : UIImageView에 태그를 추가하면 빠른 수정이 가능합니다.

스위프트 4.2

view.viewWithTag(1)?.tintColorDidChange()

0
extension UIImageView {

   @IBInspectable var renderModeTemplate : Bool {
       get{
           return image?.renderingMode == .alwaysTemplate
       }

       set{
          image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
       }
   }
}

스토리 보드에있는 UIImageView 선택 관리자, 설정 특성 선택 renderModeTemplate= On 에서 스토리 보드를

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.