Cocoa touch Cocoa Touch-使用叠加视图添加纹理

Cocoa touch Cocoa Touch-使用叠加视图添加纹理,cocoa-touch,core-graphics,quartz-graphics,Cocoa Touch,Core Graphics,Quartz Graphics,我有一组具有可编程背景色的UI视图,每一个都有一个 可以是不同的颜色。我想添加纹理,像一个侧面照亮斜面,每一个。这可以通过覆盖视图或其他方法完成吗 我正在寻找的建议,不需要为每个案件自定义图像文件 这可能会对某人有所帮助,尽管这是从其他主题拼凑而成的。 为了创建一个具有任意颜色的斜切平铺图像用于正常和视网膜显示,我在photoshop中制作了一个斜切图像,并将饱和度设置为零,制作了一个名为tileBevel.png 我还为视网膜显示器创建了一个(tileBevel@2x.png) 代码如下:

我有一组具有可编程背景色的UI视图,每一个都有一个 可以是不同的颜色。我想添加纹理,像一个侧面照亮斜面,每一个。这可以通过覆盖视图或其他方法完成吗


我正在寻找的建议,不需要为每个案件自定义图像文件

这可能会对某人有所帮助,尽管这是从其他主题拼凑而成的。 为了创建一个具有任意颜色的斜切平铺图像用于正常和视网膜显示,我在photoshop中制作了一个斜切图像,并将饱和度设置为零,制作了一个名为
tileBevel.png

我还为视网膜显示器创建了一个(
tileBevel@2x.png

代码如下:

+ (UIImage*) createTileWithColor:(UIColor*)tileColor {

    int pixelsHigh = 44;
    int pixelsWide = 46;
    UIImage *bottomImage;

    if([UIScreen respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2.0) {
        pixelsHigh *= 2;
        pixelsWide *= 2;
        bottomImage = [UIImage imageNamed:@"tileBevel@2x.png"];        
    }
    else {
        bottomImage = [UIImage imageNamed:@"tileBevel.png"];
    }

    CGImageRef theCGImage = NULL;
    CGContextRef tileBitmapContext = NULL;

    CGRect rectangle = CGRectMake(0,0,pixelsWide,pixelsHigh);

    UIGraphicsBeginImageContext(rectangle.size);

    [bottomImage drawInRect:rectangle];

    tileBitmapContext = UIGraphicsGetCurrentContext();

    CGContextSetBlendMode(tileBitmapContext, kCGBlendModeOverlay);

    CGContextSetFillColorWithColor(tileBitmapContext, tileColor.CGColor);        
    CGContextFillRect(tileBitmapContext, rectangle);

    theCGImage=CGBitmapContextCreateImage(tileBitmapContext);

    UIGraphicsEndImageContext();

    return [UIImage imageWithCGImage:theCGImage];

}
这将检查是否使用视网膜显示,调整要绘制的矩形的大小,选择适当的灰度基础图像,将混合模式设置为叠加,然后在底部图像的顶部绘制矩形。所有这些都是在由BeginImageContext和EndImageContext调用括起来的图形上下文中完成的。这些设置UIImage drawRect:方法所需的当前上下文。核心图形函数需要上下文作为参数,通过调用获取当前上下文即可获得该参数

结果如下所示:


如果您想保留源图像的alpha通道,只需在fill rect之前将其添加到jim的代码中:

// Apply mask
CGContextTranslateCTM(tileBitmapContext, 0, rectangle.size.height);
CGContextScaleCTM(tileBitmapContext, 1.0f, -1.0f);

CGContextClipToMask(tileBitmapContext, rectangle, bottomImage.CGImage);

Swift 3解决方案,基本上基于Jim的答案和Scriptease的补充,以及一些小改动:

class func image(bottomImage: UIImage, topImage: UIImage, tileColor: UIColor) -> UIImage? {
    let pixelsHigh: CGFloat = bottomImage.size.height
    let pixelsWide: CGFloat = bottomImage.size.width

    let rectangle = CGRect.init(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
    UIGraphicsBeginImageContext(rectangle.size);

    bottomImage.draw(in: rectangle)

    if let tileBitmapContext = UIGraphicsGetCurrentContext() {
        tileBitmapContext.setBlendMode(.overlay)
        tileBitmapContext.setFillColor(tileColor.cgColor)
        tileBitmapContext.scaleBy(x: 1.0, y: -1.0)
        tileBitmapContext.clip(to: rectangle, mask: bottomImage.cgImage!)
        tileBitmapContext.fill(rectangle)
        let theCGImage = tileBitmapContext.makeImage()
        UIGraphicsEndImageContext();

        if let theImage = theCGImage {
            return UIImage.init(cgImage: theImage)
        }
    }

    return nil
}