4

どうしても必要な場合を除いて、車輪の再発明をしたくないので、CoreGraphicsを使用してこのような矢印を描画する方法を確認したいと思いました。

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

誰かが私がこれを始める方法を知っていますか?これは私がこれまでに持っているものですが、ブラケットの形ではなく正三角形を描画します。

    CGPoint origin = CGPointMake(100, 20);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:origin];
    [path addLineToPoint:CGPointMake(origin.x-10, origin.y-20)];
    [path addLineToPoint:CGPointMake(origin.x-10, origin.y+20)];
    [[UIColor redColor] set];
    [path fill];
4

4 に答える 4

9

@NSGodで提案されているようにストロークで描画する場合は、上部または下部の先端に移動してから、矢印の頭に線を引き、次に下部または上部の先端に線を引く必要があります。描いたような45度の角度が必要な場合は、座標に加算または座標から減算する量を等しくする必要があります。

パスの線幅も設定する必要があります。これはサイズに比例する必要があります。

CGPoint origin = CGPointMake(100, 20);

UIBezierPath *path = [UIBezierPath bezierPath];
// Upper tip
[path moveToPoint:CGPointMake(origin.x+20, origin.y-20)];
// Arrow head
[path addLineToPoint:CGPointMake(origin.x, origin.y)];
// Lower tip
[path addLineToPoint:CGPointMake(origin.x+20, origin.y+20)];

[[UIColor redColor] set];
// The line thickness needs to be proportional to the distance from the arrow head to the tips.  Making it half seems about right.
[path setLineWidth:10];
[path stroke];

結果はこのような形になります。

上記のコードで描かれた矢印

ストロークではなく塗りつぶしたい場合(矢印の輪郭を描きたい場合に必要になる場合があります)、6つのポイントをプロットしてから、パスを閉じる必要があります。

于 2012-04-26T02:30:34.460 に答える
3

問題の潜在的な部分の1つは、のfill代わりにを使用していたことですstroke

に変更[path fill]すると[path stroke]、次のようになります。

CGPoint origin = CGPointMake(100, 20);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:origin];
[path addLineToPoint:CGPointMake(origin.x - 10, origin.y - 20)];
[path addLineToPoint:CGPointMake(origin.x - 10, origin.y + 20)];
[[UIColor redColor] set];
// [path fill];
[path stroke];

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

これは、あなたがその点で何を意図していたのかという疑問を提起しますorigin。これは、原点がどのように使用されるかという従来の感覚ではなく、実際には矢印のポイントに変換されます(描画されるオブジェクトの左上隅を意味します)。

の意味を維持したい場合originは、コードを次のように変更する必要があります。

CGPoint origin = CGPointMake(100, 20);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(origin.x - 20, origin.y - 20)];
[path addLineToPoint:origin];
[path addLineToPoint:CGPointMake(origin.x - 20, origin.y + 20)];
path.lineWidth = 4.0;
[[UIColor redColor] set];
[path stroke];

または、の従来の意味を使用する場合はorigin、次を使用できます。

CGPoint origin = CGPointMake(100, 20);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:origin];
[path addLineToPoint:CGPointMake(origin.x + 20, origin.y + 20)];
[path addLineToPoint:CGPointMake(origin.x, origin.y + 20 * 2)];
path.lineWidth = 4.0;
[[UIColor redColor] set];
[path stroke];

これにより、次のようになります。

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

于 2012-04-26T02:13:02.570 に答える
1

これは、上記の@Dondragmerの回答から取得したオリジンコードへのクレジットを持つSwift3.0互換クラスです

あなたは変更することができます:

  • lineHeight:CGFloat
  • lineColor:UIColor
  • 方向:Arrow.Direction(.up、.down、.left、.rightの列挙型)
クラス矢印:UIView {

    列挙型方向{
        ケースアップ、ダウン、左、右
    }

    var direction:Direction = Direction.right {
        didSet {
            レビュー()
        }
    }

    var lineColor = UIColor.red {
        didSet {
            レビュー()
        }
    }

    var lineWidth:CGFloat = 20 {
        didSet {
            レビュー()
        }
    }

    func review(){
        setNeedsDisplay()
    }


    static func directionToRadians(_ direction:Arrow.Direction)-> CGFloat {
        方向を切り替える{
        ケース.up:
            Arrow.degreesToRadians(90)を返す
        ケース.down:
            Arrow.degreesToRadians(-90)を返す
        ケース.left:
            Arrow.degreesToRadians(0)を返します
        ケース.right:
            Arrow.degreesToRadians(180)を返す
        }
    }

    static funcdegreesToRadians(_度:CGFloat)-> CGFloat {
        戻り度*CGFloat(M_PI)/ 180
    }

    func draw(_ rect:CGRect){をオーバーライドします
        origin = CGPoint(x:12、y:self.frame.height / 2)
        パス=UIBezierPath()
        path.lineJoinStyle = CGLineJoin.round
        path.move(to:CGPoint(x:origin.x + self.frame.width *(1/2)、y:frame.height-10))
        path.addLine(to:CGPoint(x:origin.x、y:origin.y))
        path.addLine(to:CGPoint(x:origin.x + self.frame.width *(1/2)、y:10))
        lineColor.set()
        path.lineWidth = lineWidth
        path.stroke()
        self.backgroundColor = UIColor.clear
        self.transform = CGAffineTransform(rotationAngle:Arrow.directionToRadians(self.direction))
    }
}

そして今、あなたは使用することができます

これも自動レイアウトと互換性があります。

let arrow = Arrow(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
arrow.lineWidth = 20
arrow.lineColor = UIColor.blue
arrow.direction = .up
于 2016-11-02T10:17:25.420 に答える
0

私はコードを書くためにコンピューターの前にいませんが、基本的にはCGMutablePathを作成し、追加してから実行します

CGContextStrokePath(context);

ストローク幅とラインキャップを設定して、希望の効果を得ることができます

于 2012-04-26T01:46:47.613 に答える