Как процедурно рисовать прямоугольник/линии в swift с использованием CGContext

Я тратил Интернет в течение нескольких дней, пытаясь найти простейшие примеры кода о том, как рисовать прямоугольник или линии процедурно в Swift. Я видел, как это сделать, переопределив команду DrawRect. Я считаю, что вы можете создать CGContext, а затем рисовать в изображение, но мне бы хотелось увидеть некоторые простые примеры кода. Или это ужасный подход? Спасибо.

class MenuController: UIViewController 
{

    override func viewDidLoad() 
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor.blackColor()

        var logoFrame = CGRectMake(0,0,118,40)
        var imageView = UIImageView(frame: logoFrame)
        imageView.image = UIImage(named:"Logo")
        self.view.addSubview(imageView)

        //need to draw a rectangle here
    }
}

Ответы

Ответ 1

Вот пример, который создает пользовательский UIImage, содержащий прозрачный фон и красный прямоугольник с линиями, пересекающими его по диагонали.

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad();

        let imageSize = CGSize(width: 200, height: 200)
        let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
        self.view.addSubview(imageView)
        let image = drawCustomImage(imageSize)
        imageView.image = image
    }
}

func drawCustomImage(size: CGSize) -> UIImage {
    // Setup our context
    let bounds = CGRect(origin: CGPoint.zeroPoint, size: size)
    let opaque = false
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
    let context = UIGraphicsGetCurrentContext()

    // Setup complete, do drawing here
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
    CGContextSetLineWidth(context, 2.0)

    CGContextStrokeRect(context, bounds)

    CGContextBeginPath(context)
    CGContextMoveToPoint(context, CGRectGetMinX(bounds), CGRectGetMinY(bounds))
    CGContextAddLineToPoint(context, CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))
    CGContextMoveToPoint(context, CGRectGetMaxX(bounds), CGRectGetMinY(bounds))
    CGContextAddLineToPoint(context, CGRectGetMinX(bounds), CGRectGetMaxY(bounds))
    CGContextStrokePath(context)

    // Drawing complete, retrieve the finished image and cleanup
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}

Ответ 2

Обновленный ответ с использованием Swift 3.0

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad();

        let imageSize = CGSize(width: 200, height: 200)
        let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
        self.view.addSubview(imageView)
        let image = drawCustomImage(size: imageSize)
        imageView.image = image
    }
}

func drawCustomImage(size: CGSize) -> UIImage? {
    // Setup our context
    let bounds = CGRect(origin: CGPoint.zero, size: size)
    let opaque = false
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
    guard let context = UIGraphicsGetCurrentContext() else { return nil }

    // Setup complete, do drawing here
    context.setStrokeColor(UIColor.red.cgColor)
    context.setLineWidth(5.0)

    // Would draw a border around the rectangle
    // context.stroke(bounds)

    context.beginPath()
    context.move(to: CGPoint(x: bounds.maxX, y: bounds.minY))
    context.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
    context.strokePath()

    // Drawing complete, retrieve the finished image and cleanup
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}

let imageSize = CGSize(width: 200, height: 200)
let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 100, y: 100), size: imageSize))
let image = drawCustomImage(size: imageSize)
imageView.image = image

Ответ 3

Я использовал принятый ответ на розыгрыш линий в игре Tic Tac Toe, когда один из игроков выиграл. Спасибо, хорошо, что это сработало. К сожалению, у меня возникли проблемы с тем, чтобы он работал на разных уровнях iPhone и iPad одновременно. Это, вероятно, то, что должно было быть рассмотрено. В основном, я говорю, что на самом деле это может не стоить проблем со всем этим кодом, в зависимости от вашего случая.

Мое альтернативное решение состоит в том, чтобы просто настроить пользовательскую, лучшую линию в Photoshop, а затем загрузить ее с помощью UIImageView. Для меня это было намного проще, работает лучше и выглядит лучше. Очевидно, что это действительно зависит от того, что вам нужно.

Шаги:

1: Загрузите или создайте изображение (желательно сохраненное как .PNG)

2: перетащите его в свой проект

3: перетащите представление UIImage в свою раскадровку

4: Нажмите на изображение и выберите изображение в инспекторе атрибутов

5: нажмите Ctrl и перетащите Image View в ваш .swift файл, чтобы объявить Outlet

6: Установите ограничения автоопределения, чтобы он работал на ВСЕХ устройствах ЛЕГКО

Анимация, поворот и трансформирование представлений изображений на экране и за его пределами также возможно проще

Чтобы изменить изображение:

yourImageViewOutletName.image = UIImage(named: "ImageNameHere")