2011-06-27 7 views
129

Tworzę kolorowy obraz tak:Tworzenie UIImage z UIColor użyć jako tła dla UIButton

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

a następnie użyć go jako obrazu tła guzika:

[resultButton setBackgroundImage:img forState:UIControlStateNormal]; 

Działa to świetnie przy użyciu czerwonego koloru, jednak chcę użyć koloru RGB (jak pokazano w linii komentarza). Kiedy używam koloru RGB, tło przycisków nie ulega zmianie.

Czego mi brakuje?

+0

Jeśli po prostu ustawiasz kolor tła przycisku, dlaczego nie miałbyś po prostu użyć metody setBackgroundColor:? –

+0

Ustawienie tła Kolor zmienia tylko zewnętrzną część zaokrąglonych rogów, ale nie faktyczny obszar samego przycisku. – Thorsten

+0

Twój kod działa poprawnie na moim ENV, xcode501, iPhoneSimulator703, spójrz uważnie, przycisk jest najprawdopodobniej przyciskiem z jasnym białym obrazem. – oxromantic

Odpowiedz

3

Przypuszczam, że 255 w 227./255 postrzegana jest jako liczba całkowita i podział jest zawsze zwraca 0

+0

Dzięki za pomysł (również sugerowany przez kogoś, kto skasował jego odpowiedź). Podział działa dobrze, jak jest, nawet przy budowaniu koloru z poprawnie ustawionych spławików (deklarowane vary-dumy i ich wartość sprawdzana w debugerze), ustawienie obrazu tła nic nie robi. – Thorsten

3
CGContextSetFillColorWithColor(context,[[UIColor colorWithRed:(255/255.f) green:(0/255.f) blue: (0/255.f) alpha:1] CGColor]); 
+0

Nie jestem pewien, co masz na myśli, odpowiadając na odpowiedź .. Nie próbowałem zastąpić colorRed wartościami RGB, ale zamiast tego używaj moich własnych wartości - co nie działa. – Thorsten

5

Czy używasz ARC? Problem polega na tym, że nie masz odniesienia do obiektu UIColor, który próbujesz zastosować; CGColor jest wspierany przez tę UIColor, ale ARC zwolni subskrypcję UIColor, zanim będziesz mógł skorzystać z CGColor.

Najbardziej oczywistym rozwiązaniem jest ustawienie zmiennej lokalnej na wartość UIColor za pomocą atrybutu objc_precise_lifetime.

Więcej informacji na ten temat można znaleźć pod adresem this article about UIColor and short ARC lifetimes lub uzyskać więcej informacji na temat the objc_precise_lifetime attribute.

+0

Ważna obserwacja, ale to spowodowałoby awarię, która brzmi tak, jak PO nie zaobserwował. –

+0

Niekoniecznie; zależy to od szczegółów interakcji CGColor i CGContextFillRect, nie wspominając o innych szczegółach, które mogą ulec zmianie z wersji OS na OS. Z pewnością może to być coś innego, ale ponieważ kod jest zepsuty jak zapisano (jeśli używany jest ARC), jest to przynajmniej pierwszy krok. –

+0

Mój kod pochodził z dni poprzedzających ARC. – Thorsten

4

Dodaj kropki do wszystkich wartości:

[[UIColor colorWithRed:222./255. green:227./255. blue: 229./255. alpha:1] CGColor]) ; 

przeciwnym razie są podzielenie pływaka przez int.

+5

Not true - argument liczby całkowitej jest automatycznie promowany do wartości zmiennoprzecinkowej (w tym przypadku podwójnej), zanim wyrażenie zostanie ocenione, ponieważ operand po lewej stronie jest typu double. [Zobacz tę odpowiedź, aby uzyskać szczegółowe wyjaśnienie] (http://stackoverflow.com/questions/5563000/implicit-type-conversion-rules-in-c-operators) –

104

Utworzono kategorię wokół UIButton, aby ustawić kolor tła przycisku i ustawić stan. Może się to okazać przydatne.

@implementation UIButton (ButtonMagic) 

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state { 
    [self setBackgroundImage:[UIButton imageFromColor:backgroundColor] forState:state]; 
} 

+ (UIImage *)imageFromColor:(UIColor *)color { 
    CGRect rect = CGRectMake(0, 0, 1, 1); 
    UIGraphicsBeginImageContext(rect.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetFillColorWithColor(context, [color CGColor]); 
    CGContextFillRect(context, rect); 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return image; 
} 

To będzie część zestawu kategorii pomocników, które mam otwarte w tym miesiącu.

Swift 2,2

extension UIImage { 
static func fromColor(color: UIColor) -> UIImage { 
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1) 
    UIGraphicsBeginImageContext(rect.size) 
    let context = UIGraphicsGetCurrentContext() 
    CGContextSetFillColorWithColor(context, color.CGColor) 
    CGContextFillRect(context, rect) 
    let img = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return img 
    } 
} 

Swift 3,0

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

Zastosowanie jako roztwór

let img = UIImage.from(color: .black) 
+0

wielkie dzięki, kolego. – Felipe

+0

Zamiast być w kategorii na UIButton, chociaż teraz w Swift jesteśmy raczej na rozszerzeniach, a nie na kategoriach, czy nie uważasz, że byłoby lepiej mieć rozszerzenie na UIImage dla inicjalizatora niż UIButton? – SwiftMatt

+0

Czy mogę użyć tego do stworzenia obraz niektórych wymiarów? Jak mam to zrobić? Przepraszam, jeśli moje pytanie wydaje się bardzo naiwne ..: -/ – Shyam

7

Xamarin.iOS

public UIImage CreateImageFromColor() 
{ 
    var imageSize = new CGSize(30, 30); 
    var imageSizeRectF = new CGRect(0, 0, 30, 30); 
    UIGraphics.BeginImageContextWithOptions(imageSize, false, 0); 
    var context = UIGraphics.GetCurrentContext(); 
    var red = new CGColor(255, 0, 0); 
    context.SetFillColor(red); 
    context.FillRect(imageSizeRectF); 
    var image = UIGraphics.GetImageFromCurrentImageContext(); 
    UIGraphics.EndImageContext(); 
    return image; 
}