我希望能够像UIImageView这样的UI对象并在其中平铺图像。
我已经能够使用CGContextDrawTiledImage更新主窗口中的背景,但不能更新图像视图。如果我修改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);
}
答案 0 :(得分:26)
如果您只想在视图中平铺图像,请将其更改为普通UIView并使用UIColor initWithPatternImage平铺背景:
backgroundView.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageWithContentsOfFile:[self bundlePath:@"some_tile_image.png" inDirectory:@"tiles"]]];
答案 1 :(得分:17)
假设您想要平铺的图片CGImageRef
为tileImage
,UIImageView
为imageView
。您需要做的是创建UIImage
以分配给image
的{{1}}属性。你可以这样做:
imageView
这将创建所需大小的位图图像上下文,将图像平铺到该上下文中,从上下文中获取CGSize imageViewSize = imageView.bounds.size;
UIGraphicsBeginImageContext(imageViewSize);
CGContextRef imageContext = UIGraphicsGetCurrentContext();
CGContextDrawTiledImage(imageContext, (CGRect){ CGPointZero, imageViewSize }, tileImage);
UIImage *finishedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView.image = finishedImage;
,然后将其分配给UIImage
。只要图像视图和平铺图像已加载并准备就绪,您就可以将此代码放在任何位置。
答案 2 :(得分:2)
不要试图修改UIImageView,而是考虑子类化UIView。 UIImageView专为一个非平铺图像而设计,一些内部可能会让你烦恼。它并不打算以你描述的方式进行修改。
在UIView(UITiledImageView?)的子类中,您可以使用drawRect:方法来执行您想要的操作。您甚至可以为图像,大小和平铺属性创建ivars,以获得更大的灵活性和可扩展性。
更新了示例项目:http://github.com/kailoa/6tringle-tiledimageview/tree/master
相关图纸代码:
- (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);
}
}
答案 3 :(得分:1)
很抱歉不知道如何在其他人的答案中添加评论,所以我在这里创建了一个新答案:
我只想指出Kailoa Kadano提供的答案有错误,image_rect.origin没有正确初始化。
大约3个星期前,我在我的项目中复制了他的代码,看起来很有效。但是,昨天,我试图在ios模拟器(iphone 4.3)中运行代码,它只是挂在CGContextDrawTiledImage中。 添加以下行后,如keremk的回答所示:
image_rect.origin = CGPointMake(0.0, 0.0);
再次有效!
这是相当棘手的,实际上起初我在iphone 4.3模拟器下测试过,最近我在iphone 4.0模拟器下测试过,然后昨天当我切换回4.3模拟器或4.2模拟器时,问题就出现了。那就是image_rect.origin是未定义的,有时它是零数据,有时它可能有一些随机数据。
答案 4 :(得分:0)
我最近通过创建自定义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