Я могу рисовать на каждом ViewController для редактирования оригинального ImageView. Есть ли способ это исправить? - PullRequest
1 голос
/ 25 мая 2019

Я работаю над анимационным приложением, и в каждом другом ViewController я могу рисовать изображение, которое в данный момент отображается в исходном ImageView. Есть ли способ исправить это?

Это именно то, что происходит. Я действительно не знаю, где в коде проблема существует. https://drive.google.com/file/d/1M7qWKMugaqeDjGls3zvVitoRmwpOUJFY/view?usp=sharing

Предполагается, что сможет рисовать только в DrawingFrame ViewController. Тем не менее, я могу рисовать на каждом отдельном ViewController в моем приложении

1 Ответ

0 голосов
/ 26 мая 2019

Возможно, проблема в том, что ваш распознаватель жестов все еще работает, даже если вы представили другой вид поверх текущего.

Это немного необычно.Обычно, когда вы представляете такое представление, старое (и его распознаватели жестов) удаляются из иерархии представления.Я предполагаю, что вы просто передвигаете этот второй вид поверх другого.Существует несколько решений:

  • Одним из решений будет определение этого нового представления таким образом, чтобы (а) оно принимало взаимодействие с пользователем;и (б) написать код, чтобы он обрабатывал эти жесты.Это позволит избежать того, что вид за ним подхватывает эти жесты.

  • Другое решение состоит в том, чтобы отключить распознаватель жестов при представлении меню и повторно включить его, когда менюотклонено.

  • Третье решение - изменить способ представления этого представления меню, убедившись, что при этом вы удалите текущий вид из иерархии представлений.Тем не менее, стандартный переход show / present обычно делает это, поэтому нам, возможно, понадобится посмотреть, как вы представляете этот вид меню, чтобы прокомментировать дальше.


Этосказанное, несколько несвязанных наблюдений:

  • вы должны использовать UIGraphicsBeginImageContextWithOptions вместо UIGraphicsBeginImageContext;

  • вместо

    if pencil.eraser == true { ... }
    

    вы можете

    if pencil.eraser { ... }
    
  • Я бы предложил дать pencil вычисляемое свойство:

    var color: UIColor { return UIColor(red: red, green: green, blue: blue, alpha: opacity) }
    

    Тогда вы можете просто обратитьсяpencil.color;

  • имена свойств должны начинаться со строчной буквы;И

  • drawingFrame - вводящее в заблуждение имя, ИМХО, потому что это не «фрейм», а скорее всего UIImageView.Я бы назвал это drawingImageView или что-то в этом роде.

Уступая:

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {
    guard let pencil = pencil else { return }

    //begins current context (and defer the ending of the context)
    UIGraphicsBeginImageContextWithOptions(drawingImageView.bounds.size, false, 0)
    defer { UIGraphicsEndImageContext() }

    //where to draw
    drawingImageView.image?.draw(in: drawingImageView.bounds)
    //saves context
    guard let context = UIGraphicsGetCurrentContext() else { return }

    //drawing the line
    context.move(to: fromPoint)
    context.addLine(to: toPoint)
    context.setLineCap(.round)

    if pencil.eraser {
        //Eraser
        context.setBlendMode(.clear)
        context.setLineWidth(10)
        context.setStrokeColor(UIColor.white.cgColor)
    } else {
        //opacity, brush width, etc.
        context.setBlendMode(.normal)
        context.setLineWidth(pencil.pencilWidth)
        context.setStrokeColor(pencil.color.cgColor)
    }

    context.strokePath()

    //storing context back into the imageView
    drawingImageView.image = UIGraphicsGetImageFromCurrentImageContext()
}

Или, что еще лучше, вообще удалите UIGraphicsBeginImageContext и используйте современныеUIGraphicsImageRenderer:

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {
    guard let pencil = pencil else { return }

    drawingImageView.image = UIGraphicsImageRenderer(size: drawingImageView.bounds.size).image { _ in
        drawingImageView.image?.draw(in: drawingImageView.bounds)

        let path = UIBezierPath()
        path.move(to: fromPoint)
        path.addLine(to: toPoint)
        path.lineCapStyle = .round

        if pencil.eraser {
            path.lineWidth = 10
            UIColor.white.setStroke()
        } else {
            path.lineWidth = pencil.pencilWidth
            pencil.color.setStroke()
        }

        path.stroke()
    }
}

Для получения дополнительной информации о UIGraphicsImageRenderer см. Раздел «Рисование вне экрана» WWDC 2018 Изображение иBest Practices в области графики .

Кроме того, как только вы решите эту проблему, вы можете захотеть вернуться к этой логике «обводки из точки a в точку b и повторного снимка», чтобы захватить массивуказывает и строит путь из целой серии, и никогда не повторно снимает точку, а только после добавления целой связки.Процесс создания моментальных снимков медленный, и вы обнаружите, что UX заикается немного больше, чем нужно.Я лично делаю повторный снимок через 100 пунктов или около того (в этот момент время, необходимое для повторного обрыва всего пути, достаточно медленное, чтобы оно не намного быстрее, чем процесс моментального снимка, поэтому, если я сделаю снимок и перезапущу путь с того места, где остановился,затем он снова ускоряется).

Но вы говорите:

Предполагается, что он сможет рисовать только в DrawingFrame ViewController.Тем не менее, я могу рисовать на каждом отдельном ViewController в моем приложении.

Выше следует рисовать только image из drawingImageView и штрих от fromPoint до toPoint.Ваша проблема с рисованием «каждого отдельного ViewController» лежит в другом месте.Нам действительно нужно увидеть, насколько точно вы представляете эту сцену меню.

...