7

私は子供向けの本のアプリに取り組んでおり、添付のスクリーンショットに示すように、キャラクターの会話用の吹き出しを動的に入力したいと考えています。スクリーンショットは、Cocos2D(または3D)を使用して開発されたCinderellaアプリからのものだと思います。ただし、objective-cとiOSSDKを使用してこの機能を実現したいと思います。

1つのアプローチは次のとおりです。

フォントとサイズを指定してテキストのサイズを計算し(NSStringメソッドsizeWithFont:constrainedToSize :を使用)、次に丸みを帯びた長方形を描画して(CALayerを使用)そのサイズを囲みます。

角丸長方形を描画するには、背景色、境界線の幅、境界線の色、および色の半径を使用してCALayerを設定し、それをUIViewオブジェクトに追加します。それは非常に簡単に吹き出し効果を与えるでしょう。

さて、キャラクターの口を指すコーナーをどのように取得しますか?キャラクターの口からCALayerをポップアウトおよびポップインするにはどうすればよいですか?このアニメーションをどのように実装しますか?私のメインシーン(イラスト)はUIImageviewで、このダイアログポップポップはキャラクターの口からアニメーションで表示され、数秒後にはキャラクターの口に戻るように消えます。あなたの提案をいただければ幸いです。

どこかのサンプルコード/記事を知っている場合は、それに応じて私をルーティングしてください。

キャラクターのダイアログが吹き出しとしてポップインおよびポップアウトする方法を示すアプリのビデオリンクは次のとおりです。http ://www.youtube.com/watch?v = umfNJLyrrNg

ここに画像の説明を入力してください

4

3 に答える 3

15

これが、このアップルチュートリアルを変更した私の実装です。

https://developer.apple.com/library/ios/samplecode/quartzdemo/Listings/QuartzDemo_QuartzCurves_m.html

- (void)drawRect:(CGRect)rect
{
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, .5f);
    CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
    CGContextSetRGBFillColor(context, 1, 1, 1, 1);

    rect.origin.y++;
    CGFloat radius = cornerRadius;

    CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect);
    CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect);

    CGMutablePathRef outlinePath = CGPathCreateMutable();

    if (![User isCurrentUser:message.user])
    {
        minx += 5;
    
        CGPathMoveToPoint(outlinePath, nil, midx, miny);
        CGPathAddArcToPoint(outlinePath, nil, maxx, miny, maxx, midy, radius);
        CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, midx, maxy, radius);
        CGPathAddArcToPoint(outlinePath, nil, minx, maxy, minx, midy, radius);
        CGPathAddLineToPoint(outlinePath, nil, minx, miny + 20);
        CGPathAddLineToPoint(outlinePath, nil, minx - 5, miny + 15);
        CGPathAddLineToPoint(outlinePath, nil, minx, miny + 10);
        CGPathAddArcToPoint(outlinePath, nil, minx, miny, midx, miny, radius);
        CGPathCloseSubpath(outlinePath);
    
        CGContextSetShadowWithColor(context, CGSizeMake(0,1), 1, [UIColor lightGrayColor].CGColor);
        CGContextAddPath(context, outlinePath);
        CGContextFillPath(context);
    
        CGContextAddPath(context, outlinePath);
        CGContextClip(context);
        CGPoint start = CGPointMake(rect.origin.x, rect.origin.y);
        CGPoint end = CGPointMake(rect.origin.x, rect.size.height);
        CGContextDrawLinearGradient(context, [self normalGradient], start, end, 0);
    }
    else
    {
        maxx-=5;
        CGPathMoveToPoint(outlinePath, nil, midx, miny);
        CGPathAddArcToPoint(outlinePath, nil, minx, miny, minx, midy, radius);
        CGPathAddArcToPoint(outlinePath, nil, minx, maxy, midx, maxy, radius);
        CGPathAddArcToPoint(outlinePath, nil, maxx, maxy, maxx, midy, radius);
        CGPathAddLineToPoint(outlinePath, nil, maxx, miny + 20);
        CGPathAddLineToPoint(outlinePath, nil, maxx + 5, miny + 15);
        CGPathAddLineToPoint(outlinePath, nil, maxx, miny + 10);
        CGPathAddArcToPoint(outlinePath, nil, maxx, miny, midx, miny, radius);
        CGPathCloseSubpath(outlinePath);
    
        CGContextSetShadowWithColor(context, CGSizeMake(0,1), 1, [UIColor lightGrayColor].CGColor);
        CGContextAddPath(context, outlinePath);
        CGContextFillPath(context);
    
        CGContextAddPath(context, outlinePath);
        CGContextClip(context);
        CGPoint start = CGPointMake(rect.origin.x, rect.origin.y);
        CGPoint end = CGPointMake(rect.origin.x, rect.size.height);
        CGContextDrawLinearGradient(context, [self greenGradient], start, end, 0);
    }


    CGContextDrawPath(context, kCGPathFillStroke);

}

- (CGGradientRef)normalGradient
{

    NSMutableArray *normalGradientLocations = [NSMutableArray arrayWithObjects:
                                               [NSNumber numberWithFloat:0.0f],
                                               [NSNumber numberWithFloat:1.0f],
                                               nil];


    NSMutableArray *colors = [NSMutableArray arrayWithCapacity:2];

    UIColor *color = [UIColor whiteColor];
    [colors addObject:(id)[color CGColor]];
    color = [StyleView lightColorFromColor:[UIColor cloudsColor]];
    [colors addObject:(id)[color CGColor]];
    NSMutableArray  *normalGradientColors = colors;

    int locCount = [normalGradientLocations count];
    CGFloat locations[locCount];
    for (int i = 0; i < [normalGradientLocations count]; i++)
    {
        NSNumber *location = [normalGradientLocations objectAtIndex:i];
        locations[i] = [location floatValue];
    }
    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();

    CGGradientRef normalGradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)normalGradientColors, locations);
    CGColorSpaceRelease(space);

    return normalGradient;
}

これは結果として... ここに画像の説明を入力してください

于 2013-06-12T01:50:57.543 に答える
7

これを行う別の方法は、キャップインセット付きの画像を使用することです。UIImageメソッドを見てください。

resizableImageWithCapInsets:

基本的に、最小サイズのバブルの画像を作成し、「バブル」の境界線の外観を維持しながら、それを無期限に伸ばすことができます。

以下のコードは、画像を拡大/サイズ変更するときに、上下左右の12ピクセルが保持される画像を指定します。

UIImage *bubble = [[UIImage imageNamed:@"bubble.png"] 
                            resizableImageWithCapInsets:UIEdgeInsetsMake(12, 12, 12, 12)];
UIImageView *imgView = [[[UIImageView alloc] initWithImage:bubble] autorelease];
imgView.frame = CGRectZero;

UIImageViewのサイズ変更のアニメーションは無料で提供されます。

[UIView animateWithDuration:0.3
                 animations:^(void) {
                     imgView.frame = CGRectMake(50, 50, 200, 100);
                 } completion:^(BOOL finished) {

                 }];
于 2012-06-25T19:43:25.580 に答える
3

three20フレームワーク(実際にはThree20Style)には、TTSpeechBubbleShapeと呼ばれる整形されたウィンドウクラスがあります。これは基本的にあなたが探しているものです。

今、私が見ているように、2つのオプションがあります。

  1. Three20を使用します。また

  2. TTSpeechBubbleShapeクラスを分析して、これがどのように実装されているかを確認し、アプリで同じことを行います。

于 2012-06-25T19:38:24.337 に答える