Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Нарисовать стрелку-пулю в Core Graphics

Автор вопроса: SnowmanОтветов: 4

Я не хочу изобретать колесо без крайней необходимости, поэтому я хотел посмотреть, как я буду рисовать такую ​​стрелку с помощью Core Graphics:

Кто-нибудь знает, как я могу с этим начать? Это то, что у меня есть до сих пор, но он рисует правильный треугольник вместо формы скобки:

    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];
  • Вот где может пригодиться Paintcodeapp. 0x8badf00d 26.04.2012
  • Чёрт возьми, это круто! Не знал, что такое существует .. Snowman 26.04.2012
  • Я бы, вероятно, нарисовал это как фигуру с шестью точками, а не создавал трехточечный путь. macserv 26.04.2012
  • Есть ли какие-нибудь другие классные приложения, такие как Paintcodeapp, которые помогают с рисованием или анимацией? Snowman 26.04.2012

iosiphoneobjective-ccore-graphics

Ответы

Ответ 1 · рейтинг 9 · Dondragmer

Если вы рисуете штрихами, как предлагает @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 точек, а затем замкнуть путь.

Ответ 2 · рейтинг 3 · NSGod

Одна потенциальная часть проблемы заключается в том, что вы использовали 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];

Это дает следующее:

Ответ 3 · рейтинг 1 · Max Alexander

Вот совместимый с Swift 3.0 класс с кредитами на исходный код, взятый из ответа @Dondragmer сверху.

Вы можете изменить:

  • lineHeight: CGFloat
  • lineColor: UIColor
  • direction: Arrow.Direction (перечисление с .up, .down, .left, .right)
class Arrow : UIView {

    enum Direction {
        case up, down, left, right
    }

    var direction : Direction = Direction.right {
        didSet {
            review()
        }
    }

    var lineColor = UIColor.red {
        didSet {
            review()
        }
    }

    var lineWidth : CGFloat = 20 {
        didSet {
            review()
        }
    }

    func review(){
        setNeedsDisplay()
    }


    static func directionToRadians(_ direction: Arrow.Direction) -> CGFloat{
        switch direction {
        case .up:
            return Arrow.degreesToRadians(90)
        case .down:
            return Arrow.degreesToRadians(-90)
        case .left:
            return Arrow.degreesToRadians(0)
        case .right:
            return Arrow.degreesToRadians(180)
        }
    }

    static func degreesToRadians(_ degrees: CGFloat) -> CGFloat {
        return degrees  * CGFloat(M_PI) / 180
    }

    override func draw(_ rect: CGRect) {
        let origin = CGPoint(x: 12, y: self.frame.height / 2)
        let path = 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

Ответ 4 · shein

Я не стою перед компьютером, чтобы писать код, но в основном вы создаете CGMutablePath, добавляете, затем делаете

CGContextStrokePath(context);

Вы можете установить ширину обводки и границу линии для достижения желаемого эффекта.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы