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 は、パターンを描画する開始点です。

パターンの使い方を間違えただけです。現在のコンテキストのフェーズを設定しないと、毎回 context(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:。また、下のコメント (チュートリアル Web サイト内) までスクロールすると、次のコメントが表示されます。

もう一つ不具合を発見。RoundRect の境界を変更しても、更新されません。そのため、がすべておかしくなることがあり ます (自動的にスケーリングされるため)。

簡単な修正は、両方の init メソッドに次を追加することです。

self.contentMode = UIViewContentModeRedraw;

contentMode を Redraw に設定すると、 を呼び出す手間が省けますsetNeedsDisplay。UIView のフレームを簡単に変更したり、即座にアニメーション化したりできます。UIView は自動的に再描画されます。

後で問題をよく調べてみます..実際に実装してみます。

于 2011-10-31T03:22:28.513 に答える