Нарисуйте UIBezierPaths в UIView без подкласса?

Я новичок в использовании UIBezierPaths для рисования фигур. Все примеры, которые я нашел до сих пор, включают сначала создание подкласса представления, затем переопределение метода drawRect: и выполнение рисования внутри него, но я не смог найти ничего, что с абсолютной уверенностью говорило бы, является ли это единственный способ рисования UIBezierPaths в UIView, или, если это самый прагматичный способ.

Есть ли другой способ (кроме swizzling) нарисовать UIBezierPath в UIView без его подкласса?


person n00neimp0rtant    schedule 14.04.2015    source источник


Ответы (4)


Другой способ рисовать контуры Безье без использования drawRect - использовать CAShapeLayers. Задайте для свойства path слоя-фигуры значение CGPath, созданное на основе пути Безье. Добавьте слой-фигуру в качестве подслоя к слою вашего представления.

    UIBezierPath *shape = [UIBezierPath bezierPathWithOvalInRect:self.view.bounds];
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = shape.CGPath;
    shapeLayer.fillColor = [UIColor colorWithRed:.5 green:1 blue:.5 alpha:1].CGColor;
    shapeLayer.strokeColor = [UIColor blackColor].CGColor;
    shapeLayer.lineWidth = 2;

    [self.view.layer addSublayer:shapeLayer];
person rdelmar    schedule 14.04.2015
comment
Похоже, это именно то, что я искал! Хотел бы я знать об этом вчера = P Существуют ли какие-либо непредвиденные ограничения или возможности UIBezierPath, которые будут недоступны, если сделать это таким образом? - person n00neimp0rtant; 15.04.2015
comment
@ n00neimp0rtant Я не знаю каких-либо конкретных ограничений, и я не знаю, каковы будут последствия для памяти, особенно если вы хотите иметь несколько слоев. Чтобы узнать это, вам нужно будет провести профилирование. - person rdelmar; 15.04.2015

Быстрая версия принятого ответа:

    let shape = UIBezierPath(ovalInRect: view.bounds)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = shape.CGPath
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor
    shapeLayer.strokeColor = UIColor.blackColor().CGColor
    shapeLayer.lineWidth = 2.0
    view.layer.addSublayer(shapeLayer)
person Chris C    schedule 11.05.2016

Swift 3 принял ответ:

let shape = UIBezierPath(ovalIn: view.bounds)
let shapeLayer = CAShapeLayer()
shapeLayer.path = shape.cgPath
shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).cgColor
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.lineWidth = 2.0
view.layer.addSublayer(shapeLayer)
person stonybrooklyn    schedule 15.08.2017

Вы можете: 1) отобразить UIBezierPaths в контексте изображения. 2) Добавьте UIImageView в качестве подвида вашего представления и установите свойство изображения с визуализированным изображением. Что-то вроде этого:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:self.imageView];
    [self drawPaths];
}

- (void)drawPaths {
       UIGraphicsBeginImageContext(self.view.bounds);
       //draw...
       self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
       UIGraphicsEndImageContext();
}
person ninjaproger    schedule 14.04.2015
comment
Значит, вы по существу визуализируете путь Безье как UIImage, а затем отображаете его в UIImageView? В некоторых случаях это потенциально может быть лучше, чем создание подклассов, но это действительно кажется довольно дорогостоящим, особенно если оно перерисовывается при изменении размера представления. - person n00neimp0rtant; 15.04.2015