Проблема:
Когда я рисую (стираю) маску внутри OverlayMaskingViewController, она отображается правильно в этом представлении, но как только я возвращаюсь на главный экран (последовательность действий:
OverlaySetup → OverlaysGradients → ИзображенияВидео → Редактировать), изменения исчезли — исходное наложение отображается снова.
Кроме того, каждый раз, когда я подтверждаю нажатием кнопки «✔» или повторно открываю редактор, слои наложения перерисовываются или дублируются (вид градиента/текста/рамки появляется несколько раз).
Видео -> https://streamable.com/e9zzpq, как теперь работа
OverlayMaskingViewController
Код: Выделить всё
@objc private func didTapApply() {
cancelPreviewHide()
clearPreview(keepMask: true)
let mask: UIImage? = {
if let currentMaskImage { return currentMaskImage }
guard let overlayView = overlayImageView else { return nil }
let size = overlayView.bounds.size
guard size.width > 0, size.height > 0 else { return nil }
let renderer = UIGraphicsImageRenderer(size: size)
return renderer.image { ctx in
UIColor.white.setFill()
ctx.fill(CGRect(origin: .zero, size: size))
}
}()
if let mask {
delegate?.overlayMaskingDidApplyMask(mask)
}
}
Код: Выделить всё
@objc
func didTapApplyButton() {
applyOverlay()
delegate?.applyOverlay(overlay: overlay)
dismissSetUpScreen()
}
private extension OverlaySetupViewController {
func applyOverlay() {
overlay.rotationAngle = rotationAngle
overlay.opacity = overlayOpacity
overlay.blendMode = overlayBlendMode
overlay.overlayFrame = mainView.overlayImageView.frame
overlay.containerSize = mainView.imageView.imageFrameInImageView().size
}
extension OverlaySetupViewController: OverlayMaskingViewControllerDelegate {
func overlayMaskingDidApplyMask(_ maskImage: UIImage) {
let layer = CALayer()
layer.contentsScale = UIScreen.main.scale
layer.frame = mainView.overlayImageView.bounds
layer.contents = maskImage.cgImage
mainView.overlayImageView.layer.mask = layer
overlay.maskPNGData = maskImage.pngData()
overlay.maskImageSize = maskImage.size
}
}
func observeProjectChanges() {
let center = NotificationCenter.default
let framesToken = center.addObserver(
forName: .framesDidChange,
object: nil,
queue: .main
) { [weak self] note in
guard let self else { return }
let pid = note.userInfo?[AdjustNotificationKey.projectId] as? String
guard pid == self.project.id else { return }
let newFrame = note.userInfo?["frame"] as? Frame
self.refreshFrame(with: newFrame)
}
notificationTokens.append(framesToken)
let overlaysToken = center.addObserver(
forName: .overlaysDidChange,
object: nil,
queue: .main
) { [weak self] note in
guard let self else { return }
let pid = note.userInfo?[AdjustNotificationKey.projectId] as? String
guard pid == self.project.id else { return }
let newOverlay = note.userInfo?["overlay"] as? Overlay
self.refreshOverlay(with: newOverlay)
}
notificationTokens.append(overlaysToken)
}
}
Код: Выделить всё
import Foundation
struct Overlay: Codable {
let id: String
let title: String
let categoryId: String
let overlayName: String
var opacity: CGFloat
var isPremium: Bool
var blendMode: BlendModeType
var overlayFrame: CGRect?
var containerSize: CGSize?
var rotationAngle: CGFloat
var maskPNGData: Data?
var maskImageSize: CGSize?
}
mainView.imageView = baseImage, mainView.overlayImageView = overlayImage.
Пользователь может изменить непрозрачность/смешение/трансформацию.
Когда пользователь открывает Masking, SetupVC добавляет MaskingVC в качестве дочернего и дает емуContainerMask + overlayImageView, поэтому маска рисуется непосредственно над тем же слоем.
applyOverlay() сохраняет параметры (rotationAngle, opacity, blendMode, overlayFrame,ContainerSize) в структуре наложения, но не маску, поскольку в модели нет поля для него и Layer.mask не экспортируется.
didTapApplyButton() вызывает applyOverlay() + делегировать?.applyOverlay(overlay:) + ignore().
В OverlayMaskingViewController:
Получает CanvasContainer, imageView, overlayImageView.
При каждом штрихе: строит альфа-маску → применяет ее к overlayImageView.layer.mask для локального Предварительный просмотр.
При применении: просто вызывает ClearPreview(keepMask: true) и отклоняет — маска никогда не передается в модель.
Структура Overlay описывает параметры наложения (имя, непрозрачность, blendMode, преобразование и т. д.), но не имеет данных маски, поэтому результат не сохраняется между экранами.>
Подробнее здесь: https://stackoverflow.com/questions/797 ... -on-reopen
Мобильная версия