4

我尝试用一​​些小图片在我的 iPhone 应用程序中创建一个灵活的框架。CustomView 继承 UIView 并覆盖它的setFrame:方法。在 setFrame: 中,我尝试调用[self setNeedsDisplay];每次缩放照片时,此框架确实显示和更改,但有些东西效果不佳。代码及效果如下:

这是我用来绘制框架的图像,在 self.patternImage 的代码中


我的代码的效果


我的代码的效果


//旋转得到originImage的镜像,isHorization表示旋转方向 - (UIImage*)fetchMirrorImage:(UIImage*)originImage direction:(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];
}
4

2 回答 2

4

是的,我成功了!!!最终效果 我唯一需要做的就是设置当前上下文的阶段。

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));
于 2011-11-01T04:02:53.823 回答
0

首先,我要说的是:
我现在没有真正的答案。但是,我有一个提示.. 我认为它会很有用。

根据Larmarche 发布的教程,您可以通过重写轻松自定义 UIView 的边框drawRect:。而且,如果您向下滚动到下面的评论(在教程网站中),您可以看到以下评论:

我发现了另一个故障。当你改变 RoundRect 的边界时,它不会被更新——所以角落有时会变得很乱 (因为它们是自动缩放的)。

快速修复是将以下内容添加到两个 init 方法中:

self.contentMode = UIViewContentModeRedraw;

将 contentMode 设置为 Redraw 可以省去调用的麻烦setNeedsDisplay。您可以轻松更改 UIView 的框架,立即或为其设置动画,并且 UIView 将自动重绘..

稍后我将尝试更好地查看您的问题.. 我将尝试实际实施它。

于 2011-10-31T03:22:28.513 回答