Jak dynamicznie utworzyć kolorowy interfejs 1x1 na iPhonie?

Chciałbym stworzyć interfejs 1x1 dynamicznie oparty na Uicolorze.

Podejrzewam, że można to szybko zrobić za pomocą Quartz2d, i przeglądam dokumentację, próbując zrozumieć podstawy. Wygląda jednak na to, że istnieje wiele potencjalnych pułapek: nie identyfikowanie liczby bitów i bajtów na rzeczy poprawnie, nie określanie właściwych FLAG, nie uwalnianie nieużywanych danych itp.

Jak można to bezpiecznie zrobić z Quartz 2d (lub innym prostszym sposób)?

Author: erickson, 2009-06-13

5 answers

Możesz użyć CGContextSetFillColorWithColor i CGContextFillRect do tego:

Swift

extension UIImage {
    class func image(with color: UIColor) -> UIImage {
        let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        CGContextSetFillColorWithColor(context, color.CGColor)
        CGContextFillRect(context, rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

Swift3

extension UIImage {
    class func image(with color: UIColor) -> UIImage {
        let rect = CGRect(origin: CGPoint(x: 0, y:0), size: CGSize(width: 1, height: 1))
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()!

        context.setFillColor(color.cgColor)
        context.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }
}

Objective-C

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
 322
Author: Matt Stevens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-27 14:09:15

Oto inna opcja oparta na kodzie Matta Stephena. Tworzy obraz jednokolorowy, który można zmienić, aby można było go ponownie użyć lub zmienić jego rozmiar (np. użyć go jako tła).

+ (UIImage *)prefix_resizeableImageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 3.0f, 3.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];

    return image;
}

Umieść go w kategorii UIImage i zmień prefiks.

 7
Author: Ben Lachman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-27 08:48:49

Wielokrotnie korzystałem z odpowiedzi Matta Stevena, więc zrobiłem dla niej kategorię:

@interface UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension;
@end

@implementation UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension {
    CGRect rect = CGRectMake(0, 0, dimension, dimension);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
@end
 6
Author: mxcl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-24 00:16:44

Dla mnie, wygoda init czuje się schludniej w Swift.

extension UIImage {

    convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {

        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContext(rect.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }

        context.setFillColor(color.cgColor)
        context.fill(rect)

        guard let image = context.makeImage() else {
            return nil
        }
        UIGraphicsEndImageContext()

        self.init(cgImage: image)
    }

}
 0
Author: Mark Bridges,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 14:18:03

Ok, to nie będzie dokładnie to, czego chcesz, ale ten kod narysuje linię. Możesz go dostosować, aby coś pokazać. Albo przynajmniej trochę informacji z niego.

Tworzenie obrazu 1x1 wydaje się trochę dziwne. Pociągnięcia poruszają się po linii, więc pociągnięcie o szerokości 1,0 przy 0,5 powinno zadziałać. Po prostu się pobaw.
- (void)drawLine{

UIGraphicsBeginImageContext(CGSizeMake(320,300));

CGContextRef ctx = UIGraphicsGetCurrentContext();

float x = 0;
float xEnd = 320;
float y = 300;

CGContextClearRect(ctx, CGRectMake(5, 45, 320, 300));

CGContextSetGrayStrokeColor(ctx, 1.0, 1.0);

CGContextSetLineWidth(ctx, 1);
CGPoint line[2] = { CGPointMake(x,y), CGPointMake(xEnd, y) };

CGContextStrokeLineSegments(ctx, line, 2);

UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}
 -6
Author: Corey Floyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-13 20:49:20