Iphone 如何使用CGContextDrawTileImage平铺图像?

Iphone 如何使用CGContextDrawTileImage平铺图像?,iphone,cocoa-touch,Iphone,Cocoa Touch,我希望能够创建像UIImageView这样的UI对象,并在其中平铺图像 我已经能够使用cgContextDrawTileImage来更新主窗口中的背景,但不是图像视图。如果我在MainView类中修改drawRect函数,就可以做到这一点 我觉得我很接近,但仍然错过了一些东西。有人能给我指出正确的方向吗 - (void)drawRect:(CGRect)rect { CGImageRef image = CGImageRetain(currentImage.CGImage); CGRect

我希望能够创建像UIImageView这样的UI对象,并在其中平铺图像

我已经能够使用cgContextDrawTileImage来更新主窗口中的背景,但不是图像视图。如果我在MainView类中修改drawRect函数,就可以做到这一点

我觉得我很接近,但仍然错过了一些东西。有人能给我指出正确的方向吗

- (void)drawRect:(CGRect)rect {

CGImageRef image = CGImageRetain(currentImage.CGImage);

CGRect imageRect;
imageRect.origin = CGPointMake(160, 240);
imageRect.size = CGSizeMake(320.0, 480.0);

CGContextRef uiContext = UIGraphicsGetCurrentContext();

CGContextClipToRect(uiContext, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height));

CGContextDrawTiledImage(uiContext, imageRect, image);

}/P>< P>而不是试图修改UIVIEVIEW,而是考虑子类UIVIEW。UIImageView是专门为一个非平铺图像而设计的,一些内部组件可能会把您搞砸。它并不是真的打算按照你描述的方式进行修改

在UIView(UITiledImageView?)的子类中,可以使用drawRect:方法来执行所需的操作。您甚至可以为图像、图像大小和平铺属性创建IVAR,以获得更大的灵活性和扩展性

更新了示例项目:

相关图纸代码:

- (void)drawRect:(CGRect)rect 
{
    if (TiledImage) {

        //Since we are retaining the image, we append with ret_ref.  this reminds us to release at a later date.
        CGImageRef image_to_tile_ret_ref = CGImageRetain(TiledImage.CGImage); 

        CGRect image_rect;
        image_rect.size = TiledImage.size;  //This sets the tile to the native size of the image.  Change this value to adjust the size of an indivitual "tile."

        CGContextRef context = UIGraphicsGetCurrentContext();

        CGContextDrawTiledImage(context, image_rect, image_to_tile_ret_ref);

        CGImageRelease(image_to_tile_ret_ref);
    }
}

我最近通过创建自定义UIView来实现这一点

@interface TiledImageView : UIView {
@private
    UIImage *image_;
}

@property (nonatomic, retain) UIImage *image;
@end
对于.m文件:

@implementation TiledImageView
@synthesize image = image_;

- (void)dealloc {
    [image_ release];
    [super dealloc];
}

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Initialization code
        self.image = [UIImage imageNamed:@"BGTile.png"];

    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGImageRef image = CGImageRetain(image_.CGImage);

    CGRect imageRect;
    imageRect.origin = CGPointMake(0.0, 0.0);
    imageRect.size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));

    CGContextRef context = UIGraphicsGetCurrentContext();   
    CGContextClipToRect(context, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height));  
    CGContextDrawTiledImage(context, imageRect, image);
    CGImageRelease(image);
}

@end

假设您有一个
cImageRef
用于要平铺的图像,名为
tileImage
,还有一个
UIImageView
名为
imageView
。您需要做的是创建一个
UIImage
以分配给
imageView
image
属性。您可以这样做:

CGSize imageViewSize = imageView.bounds.size;
UIGraphicsBeginImageContext(imageViewSize);
CGContextRef imageContext = UIGraphicsGetCurrentContext();
CGContextDrawTiledImage(imageContext, (CGRect){ CGPointZero, imageViewSize }, tileImage);
UIImage *finishedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

imageView.image = finishedImage;

这将创建所需大小的位图图像上下文,将图像平铺到该上下文中,从上下文中获取
UIImage
,然后将其分配给
UIImageView
。只要图像视图和平铺图像已加载并准备就绪,您就可以将此代码放在任何位置。

如果您只想在视图中平铺图像,请将其更改为普通UIView,并使用UIColor initWithPatternImage平铺背景:

backgroundView.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageWithContentsOfFile:[self bundlePath:@"some_tile_image.png" inDirectory:@"tiles"]]];

很抱歉,不知道如何在其他人的答案中添加注释,因此我在此处创建了一个新答案:

我只想指出Kailoa Kadano提供的答案有一个bug,image_rect.origin没有正确初始化

大约三周前,我在我的项目中复制了他的代码,它似乎起了作用。然而,昨天,我尝试在ios模拟器(iPhone4.3)中运行代码,它只是挂在CGContextDrawTileImage中。 在添加以下行后,如keremk的回答所示:

image_rect.origin = CGPointMake(0.0, 0.0);
它又起作用了


这是相当棘手的,事实上,起初我在iPhone4.3模拟器下测试,然后最近我在iPhone4.0模拟器下测试,然后昨天当我切换回4.3模拟器或4.2模拟器时,问题出现了。这就是图像。原点是未定义的,有时是零数据,有时可能有一些随机数据。

我会在这里使用-[UIImage ImageName:],但是相同的想法。我想也可以改变偏移量,但记不清了。这个很完美。iOS允许图像使用UIColor是很奇怪的,但不管怎样,这都会泄露出去。使用此
backgroundView.backgroundColor=[uicolorWithPatternImage:[UIImage imageNamed:@“some_tile_image.png”]这个答案应该比所有其他答案都高。只是说说而已。图像绘制正确,没有颠倒。然而,它似乎是从底部绘制的,因为当我调整窗口大小时,图像的底部似乎粘在底部,图像从底部滑出窗口。你知道我怎么才能得到相反的结果吗?这是一个非常古老的问题,我知道:为了防止有人在这里绊倒:你不应该覆盖UIImageView的drawRect-我认为它是UIKit中唯一一个有此限制的UIView子类。。。