如何在 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页面

如何实现 iPhone 照片编辑抽屉?

如何在 iPhone (iOS 5) 上的音乐应用程序中为 UITableViewCell 创建一个弹出窗口

如何在 xcode4 中为 iphone 分配默认横向图像

如何在opengl iphone中为纹理提供动画?

如何在 Xcode 中为 Iphone 应用程序导入字体 [重复]