Опираясь на UIImageView внутри UIScrollView

У меня есть UIImageView внутри UIScrollView который автоматически масштабируется, чтобы соответствовать предоставленному изображению. Пользователь может масштабировать, как обычно, жест щепоткой, а жест жеста устанавливается так, чтобы потребовалось два касания, поскольку чертеж имеет приоритет.

При запуске все выглядит отлично, но когда я вызываю код рисования, это происходит: enter image description here

Как вы можете видеть, когда drawLineFrom(fromPoint:toPoint:), UIImageView сжимается. После этого рисунок, похоже, работает по назначению (хотя он пропускает первую часть линии при каждом касании).

Мой переключатель UIPanGestureRecognizer:

@objc func onOneFingerDrawing(_ sender: UIPanGestureRecognizer) {
    switch sender.state {
    case .began:
        swiped = false

        lastPoint = sender.location(in: drawView.imageView)
    case .changed:
        swiped = true

        let currentPoint = sender.location(in: drawView.imageView)
        drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)

        lastPoint = currentPoint
    case .ended:
        guard drawView.scrollView.frame.contains(sender.location(in: drawView.imageView)) else {
            return
        }

        if let newImage = drawView.imageView.image {
            if history.count > historyIndex + 1 {
                history.removeLast((history.count - 1) - historyIndex)
            }

            history.append(newImage)
            historyIndex = history.count - 1
        }
    case .possible,
         .cancelled,
         .failed:
        return
    }
}

и мой drawLineFrom(fromPoint:toPoint:):

@objc func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) {
    UIGraphicsBeginImageContextWithOptions(drawView.imageView.frame.size, false, UIScreen.main.scale)
    let context = UIGraphicsGetCurrentContext()
    context?.interpolationQuality = .none

    drawView.imageView.image?.draw(in: CGRect(x: 0, y: 0, width: drawView.imageView.frame.size.width, height: drawView.imageView.frame.size.height))

    context?.move(to: fromPoint)
    context?.addLine(to: toPoint)

    context?.setLineCap(.round)
    context?.setLineWidth(lineWidth)
    context?.setStrokeColor(lineColor)
    context?.setBlendMode(blendMode)

    context?.strokePath()

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    drawView.imageView.image = newImage
}

Ответ 1

Существует проблема с ограничением изображения с помощью scrollview. Всякий раз, когда вы начинаете рендеринг изображения, его кадр меняется в соответствии с содержимым. Таким образом, вам нужно добавить ограничение соотношения сторон (как и я) или ограничение размера для представления изображения. см. gif для справки.

Перед добавлением ограничения размера изображения.

enter image description here

После добавления ограничения размера изображения.

enter image description here

Ответ 2

Рисунок пропускает первую часть строки, потому что вы используете UIPanGestureRecognizer. Они сначала определяют, что это панорама, прежде чем она отправит вам событие .began. Вы должны поменять его на общий UIGestureRecognizer чтобы он начинался немедленно. Вы захотите добавить дополнительную логику в этом случае, проверяя движение и количество пальцев.

Что касается изменения размера, его сложно сказать без дополнительной информации. Я бы покрасил фон ImageView. Первый вопрос заключается в том, что весь imageView сокращается или это просто фактическое изображение внутри него.