如何在 iPhone 中为照片创建灵活的框架?
Posted
技术标签:
【中文标题】如何在 iPhone 中为照片创建灵活的框架?【英文标题】:How to create a flexible frame for photo in iPhone? 【发布时间】:2011-10-26 05:26:09 【问题描述】:我尝试在我的 iPhone 应用程序中创建一个带有一些小图片的灵活框架。 CustomView 继承 UIView 并覆盖它的setFrame:
方法。在 setFrame: 中,我尝试调用 [self setNeedsDisplay];
每次缩放照片时,此框架确实显示和更改,但有些东西效果不佳。代码及效果如下:
//rotate得到originImage的镜像,isHorization表示旋转方向 - (UIImage*)fetchMirrorImage:(UIImage*)originImage 方向:(BOOL)isHorization CGSize imageSize = originImage.size; UIGraphicsBeginImageContext(imageSize); CGContextRef 上下文 = UIGraphicsGetCurrentContext(); CGAffineTransform 变换 = CGAffineTransformIdentity;
if (isHorization)
transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
transform = CGAffineTransformScale(transform, -1.0, 1.0);
else
transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextScaleCTM(context, 1, -1);
CGContextTranslateCTM(context, 0, -imageSize.height);
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, CGRectMake(0, 0, imageSize.width, imageSize.height), originImage.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
- (UIImage*)fetchPattern:(PatternType)pattern
if (!self.patternImage)
return nil;
UIImage *tmpPattern = nil;
CGRect fetchRect = CGRectZero;
CGSize imageSize = self.patternImage.size;
switch (pattern)
case kTopPattern:
fetchRect = CGRectMake(self.insetSize.width, 0, imageSize.width-self.insetSize.width, self.insetSize.height);
tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
break;
case kTopRightPattern:
fetchRect = CGRectMake(0, 0, self.insetSize.width, self.insetSize.height);
tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
break;
case kRightPattern:
break;
case kRightBottomPattern:
break;
case kBottomPattern:
break;
case kLeftBottomPattern:
break;
case kLeftPattern:
fetchRect = CGRectMake(0, self.insetSize.height, self.insetSize.width, imageSize.height-self.insetSize.height);
tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
break;
case kLeftTopPattern:
fetchRect = CGRectMake(0, 0, self.insetSize.width, self.insetSize.height);
tmpPattern = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(self.patternImage.CGImage, fetchRect)];
break;
default:
break;
return tmpPattern;
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
if (self.patternImage == nil)
return;
// Drawing code.
UIImage *conLeftImage = [self fetchPattern:kLeftTopPattern];
[conLeftImage drawAtPoint:CGPointMake(0, 0)];
UIImage *topImage = [self fetchPattern:kTopPattern];
[topImage drawAsPatternInRect:CGRectMake(self.insetSize.width, 0, self.frame.size.width-self.insetSize.width*2, self.insetSize.height)];
UIImage *leftImage = [self fetchPattern:kLeftPattern];
[leftImage drawAsPatternInRect:CGRectMake(0, self.insetSize.height, self.insetSize.width, self.frame.size.height-self.insetSize.height*2)];
UIImage *conRightImage = [self fetchMirrorImage:conLeftImage direction:YES];
[conRightImage drawAtPoint:CGPointMake(self.frame.size.width-self.insetSize.width, 0)];
UIImage *rightImage = [self fetchMirrorImage:leftImage direction:YES];
CGRect rectRight = CGRectMake(self.frame.size.width-self.insetSize.width, self.insetSize.height, self.insetSize.width, self.frame.size.height-self.insetSize.height*2);
[rightImage drawAsPatternInRect:rectRight];
UIImage *botRightImage = [self fetchMirrorImage:conRightImage direction:NO];
[botRightImage drawAtPoint:CGPointMake(self.frame.size.width-self.insetSize.width, self.frame.size.height-self.insetSize.height)];
UIImage *bottomImage = [self fetchMirrorImage:topImage direction:NO];
CGRect bottomRect = CGRectMake(self.insetSize.width, self.frame.size.height-self.insetSize.height, self.frame.size.width-self.insetSize.width*2, self.insetSize.height);
[bottomImage drawAsPatternInRect:bottomRect];
UIImage *botLeftImage = [self fetchMirrorImage:conLeftImage direction:NO];
[botLeftImage drawAtPoint:CGPointMake(0, self.frame.size.height-self.insetSize.height)];
[super drawRect:rect];
- (void)setFrame:(CGRect)frame
[super setFrame:frame];
[self setNeedsDisplay];
【问题讨论】:
【参考方案1】:是的,我成功了!!! 我唯一需要做的就是设置当前上下文的阶段。
CGContextSetPatternPhase(context, CGSizeMake(x, y));
x, y 是我想要绘制图案的起点。
我只是在使用模式时犯了一个错误。如果我不设置当前上下文的相位,它每次都从上下文(0,0)的左上角开始填充模式。
CGColorRef color = NULL;
UIImage *leftImage = [UIImage imageNamed:@"like_left.png"];
color = [UIColor colorWithPatternImage:leftImage].CGColor;
CGContextSetFillColorWithColor(context, color);
CGContextFillRect(context, CGRectMake(0, 0, FRAME_WIDTH, rect.size.height));
UIImage *topImage = [UIImage imageNamed:@"like_top.png"];
color = [UIColor colorWithPatternImage:topImage].CGColor;
CGContextSetFillColorWithColor(context, color);
CGContextFillRect(context, CGRectMake(0, 0, rect.size.width,FRAME_WIDTH));
UIImage *bottomImage = [UIImage imageNamed:@"like_bom.png"];
CGContextSetPatternPhase(context, CGSizeMake(0, rect.size.height - FRAME_WIDTH));
color = [UIColor colorWithPatternImage:bottomImage].CGColor;
CGContextSetFillColorWithColor(context, color);
CGContextFillRect(context, CGRectMake(0, rect.size.height - FRAME_WIDTH, rect.size.width, FRAME_WIDTH));
UIImage *rightImage = [UIImage imageNamed:@"like_right.png"];
CGContextSetPatternPhase(context, CGSizeMake(rect.size.width - FRAME_WIDTH, 0));
color = [UIColor colorWithPatternImage:rightImage].CGColor;
CGContextSetFillColorWithColor(context, color);
CGContextFillRect(context, CGRectMake(rect.size.width - FRAME_WIDTH, 0, FRAME_WIDTH, rect.size.height));
【讨论】:
【参考方案2】:首先,我会这样说: 我现在没有真正的答案。但是,我有一个提示..我认为它会很有用。
根据tutorial posted by Larmarche,您可以通过覆盖drawRect:
轻松自定义UIView 的边框。而且,如果您向下滚动到下面的 cmets(在教程网站中),您可以看到以下评论:
我发现了另一个故障。当您更改 RoundRect 的边界时, 它不会被更新——所以corners有时会变得很screwy (因为它们是自动缩放的)。
快速解决方法是将以下内容添加到两个 init 方法中:
self.contentMode = UIViewContentModeRedraw;
将 contentMode 设置为 Redraw 可以省去调用setNeedsDisplay
的麻烦。您可以轻松更改 UIView 的框架,立即或对其进行动画处理,并且 UIView 将自动重绘..
稍后我会尝试更好地查看您的问题.. 我会尝试实际实现它。
【讨论】:
感谢您的回答。刚才试了contentMode,还是不行。 是的,我已经把代码放在上面了。我只是覆盖drawRect,图像就是我得到的结果。以上是关于如何在 iPhone 中为照片创建灵活的框架?的主要内容,如果未能解决你的问题,请参考以下文章
如何在目标c中为iPhone UIWebView创建兼容的URL页面