4

今日のほとんどのアプリは、アプリのボタンの使用方法をユーザーに教えるチュートリアルを提供しています。このヘルプページは通常、小さなアルファ値(背景のみが半表示)の黒色で、コントロールを定義するテキストと対応するコンポーネントを指す矢印を含むバブルボックスがあります。

これがサンプル画像です。(アプリMyThingsから)

これは通常のページです

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

下から上にスワイプすると、ヘルプビューは次のように表示されます。

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

ここに私の疑問があります:

  • このヘルプビューで画像とテキストを作成するのに最適なのはどれですか?Core Graphicsを使用して、またはpng画像を含むUIImageViewを配置するだけで、画像とテキストを描画しますか?どちらが効率的ですか?

  • 既製のpng画像を使用してUIImageViewを実装しても問題はありません。私の知る限り、ここでの問題は画像ファイルのサイズと読み込み時間です。描画方法を考えると、以下の問題が気になります。

  • 長方形を描くのはとても簡単です。(ここを参照してください)。しかし、角が湾曲した長方形を描くのはどうですか?このケースを処理するために利用できる関数はありますか?

  • 次に、対応するコンポーネントを指す矢印..ポイントする必要がある正確なポイントをどのように見つけることができますか?(iPhone 4Sまでは、問題ありません。iPhone5の高さは異なります)

  • 長方形の特定の位置からこのポインタを描画するにはどうすればよいですか?

何か案は?

混乱しました!!

4

3 に答える 3

2

あなたの場合、私はサイズ変更可能で再利用可能な画像を参照します。アプリには多くのオーバーレイ画面もあり、最終的に5 6の一般的なアイテムの矢印、ラベルの背景、およびuilabelの長方形の背景画像を生成しました。

長方形を描くのは簡単ですが、時々過負荷になるかもしれません。

これらの矢印の方向を変更する場合は、次のようにUIImageviewにレイヤー変換を適用できます。

        arrowIamgeView.transform = CGAffineTransformMakeRotation(-M_PI / 20);

長方形の角が丸い場合は、特定の背景色のテキストフィールドを使用して、レイヤーのcornerradiusプロパティを設定できると思います。

于 2012-09-24T13:09:30.480 に答える
2
  • CGで泡と矢印を描く方がいいです、私見。アプリを完全に変更した場合でも機能します(たとえば、ボタンの中央を指すように正しく描画した場合)。画像の場合、ディスプレイの解像度とスケールを変えるために、いくつかのコピーが必要になります。また、何かを変更した場合は、矢印を更新する必要があります。

  • パフォーマンスの低下は見られません。どちらの方法でも、泡は非常に速く描画されます。また、CGで生成された画像を将来の使用のためにキャッシュできると考えてください。

  • 泡を描く方法を知るには、次の質問を参照してください。

  • 各バブルが指すボタンの中心を使用するのは理にかなっているようです。描画方法では、矢印を向ける場所と現在の方向(アプリが回転する場合)を知る必要があります。オーバーラップを避けるために、他のバブルを考慮に入れる必要があります。スペースを行と列に分割し、各バブルに空きスペースを割り当てることができます。

  • ユーザーエクスペリエンスを向上させるために、これらのバブルはタップを消費しないようにする必要があります。泡が表示されているときにボタンをタップすると、意図したアクションが実行されます(泡を非表示にして2回目のタップが必要になるのではありません)。

于 2012-09-24T13:22:25.670 に答える
1

やっとやった!!

私の一日の経験から、この状況に対処する方法は3つあることがわかりました。

  • 必要な画像をpngファイルとして作成し、UIImageViewを使用して表示するだけです。(ただし、解像度が異なる同じ画像を使用する必要があることを忘れないでください。これにより、アプリのサイズが大きくなります)。

  • 2番目の方法は、矢印画像を使用してラベルやテキストフィールドなどを作成し、バブル(または長方形)を表示することです。画像を変換するだけで、矢印のポインティング位置を変更できます。(Ilker Baltaciが前の回答で言ったように)。

  • 3番目の方法は、CoreGraphicsによるものです。ここで好きなものを描くことができます。私の知る限り、ラベルとテキストフィールドを初期化/割り当て/保持することでアプリのサイズを増やしたり、メモリ消費量を増やしたりすると、CoreGraphicsでこれを試すことができます。

このヘルプ画面機能を実装したい3つのビューがあります。たった3つの画面で、3つの方法のいずれかを使用できます。これは、ほとんど必要のない状況で使用しても、パフォーマンスに大きな違いがないためです。しかし、私は3番目の方法で試しました。なぜなら、私はCoreGraphicsについて何も知らなかったからです。だから、それは学習のためだけです。

私が直面した問題

  • 矢印はボタンの中心(またはボタンの上部)を指している必要があります。したがって、この正確な場所を見つけるのは複雑です。この機能は、アプリの3ページでのみ使用しています。各ページには、説明する最大4つのアイコンが含まれています。だから私は値をハードコーディングしただけです(私のもう一つの幸運は、アプリがランドスケープモードをサポートしていないことです)。ただし、この機能を非常に多くのページで使用する場合は、いくつかの配列と、アイコンの原点、高さと幅、何とか、何とかを参照してアイコンの中心を計算することにより、アイコンの中心を見つけるメソッドを定義する必要があります。

  • もう1つの問題は、バブルがどこにも重なっていないことを確認する必要があることです。ここでも、各バブルの場所を見つけるグローバルメソッドが必要です。バブルのサイズは、バブル内に配置されるテキストサイズによって異なります。これはより複雑な問題であり、3つの画面については、何百もの計算を使用してグローバルメソッドを定義するつもりはありません。そこで、 self.viewを参照して、各バブルの原点、高さ、幅をハードコーディングしました。

  • 最後になりましたが..アロー!! 矢印の高さは、バブルの場所によって異なる場合があります。泡の幅も高さによって異なる場合があります。また、矢印がボタンに向かうバブルの側面とポイントを知っておく必要があります。すでに頭の中で泡の場所を修正している場合、これらはあなたにとってまったく問題ではありません..:P

それでは、コーディングの部分に行きましょう。

- (void) createRect:(CGRect)rect xPoint:(float)x yPoint:(float)y ofHeight:(float)height ofWidth:(float)width toPointX:(float)toX toPointY:(float)toY withString:(NSString *)helpString inDirection:(NSString *)direction
{
    float distance = 5.0;
    float widthOfLine = 5.0;
    float arrowLength = 15.0;

    //Get current context

    CGContextRef context = UIGraphicsGetCurrentContext();

    //Set width of border & colors of bubble

    CGContextSetLineWidth(context, widthOfLine);
    CGContextSetStrokeColorWithColor(context, [[UIColor darkGrayColor] CGColor]);
    CGContextSetFillColorWithColor(context, [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.9] CGColor]);

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, x, y);

    CGContextAddLineToPoint(context, x+width, y);
    CGContextAddQuadCurveToPoint(context, x+width, y, x+width+distance, y+distance);

    CGContextAddLineToPoint(context, x+width+distance, y+distance+height);
    CGContextAddQuadCurveToPoint(context, x+width+distance, y+distance+height, x+width, y+distance+height+distance);

    CGContextAddLineToPoint(context, x, y+distance+height+distance);    
    CGContextAddQuadCurveToPoint(context, x, y+distance+height+distance, x-distance, y+distance+height);

    CGContextAddLineToPoint(context, x-distance, y+distance);
    CGContextAddQuadCurveToPoint(context, x-distance, y+distance, x, y);

    CGContextDrawPath(context, kCGPathFillStroke);

    //Draw curvely arrow from bubble to button (but without arrow mark)

    CGContextBeginPath(context);
    CGContextSetLineWidth(context, 5.0);
    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);

    CGPoint startPoint = CGPointMake(x+(width/2.0), y+distance+distance+height);

    CGPoint endPoint = CGPointMake(toX, toY);

    CGContextMoveToPoint(context, startPoint.x, startPoint.y+5.0);

    if ([direction isEqualToString:@"left"])
    {
        CGContextAddCurveToPoint(context, startPoint.x, startPoint.y+5.0, endPoint.x, endPoint.y, toX-10, toY);
    }

    else
    {
        CGContextAddCurveToPoint(context, startPoint.x, startPoint.y+5.0, endPoint.x, endPoint.y, toX+10, toY);
    }

    CGContextStrokePath(context);

    //Draw the arrow mark

    CGContextBeginPath(context);
    CGContextSetLineWidth(context, 5.0);
    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);

    if ([direction isEqualToString:@"left"])
    {
        CGContextMoveToPoint(context, toX-10.0, toY-arrowLength);

        CGContextAddLineToPoint(context, toX-10.0, toY);
        CGContextAddLineToPoint(context, toX-10.0+arrowLength, toY);
    }

    else
    {
        CGContextMoveToPoint(context, toX+10.0, toY-arrowLength);

        CGContextAddLineToPoint(context, toX+10.0, toY);
        CGContextAddLineToPoint(context, toX+10.0-arrowLength, toY);
    }

    CGContextStrokePath(context);

    .......
    .......
}

drawRect:このメソッドは、次のようなメソッドから呼び出すことができます。

[self createRect:rect xPoint:30.0 yPoint:250.0 ofHeight:100.0 ofWidth:100.0 toPointX:48.0 toPointY:430.0 withString:@"xxxxxxx" inDirection:@"left"];

[self createRect:rect xPoint:160.0 yPoint:100.0 ofHeight:100.0 ofWidth:100.0 toPointX:260.0 toPointY:420.0 withString:@"yyyyyyy" inDirection:@"right"];

そして、最終的な画像は次のようになります。

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

この矢印タイプは手書き効果があるため、三角形の矢印はスキップしました。

貴重な回答を寄せてくれた@djromeroとIlkerBaltaciに感謝します。

私の次の混乱はテキストの描画についてです!!!!! :P

于 2012-09-25T13:19:50.547 に答える