Das Problem:
Wenn ich eine Maske in OverlayMaskingViewController zeichne (lösche), wird sie in dieser Ansicht korrekt angezeigt, aber sobald ich zum Hauptbildschirm zurückkehre (der Ablauf ist
OverlaySetup → OverlaysGradients → ImagesVideos → Bearbeiten), die Änderungen sind verschwunden – das ursprüngliche Overlay wird wieder angezeigt.
Außerdem scheinen die Overlay-Ebenen jedes Mal, wenn ich mit der Schaltfläche „✔“ bestätige oder den Editor erneut öffne, neu gezeichnet oder dupliziert zu werden (Verlaufs-/Text-/Rahmenansichten werden mehrmals angezeigt).
Video -> https://streamable.com/e9zzpq, wie es jetzt funktioniert
OverlayMaskingViewController
Code: Select all
 @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)
}
}
Code: Select all
 @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)
}
}
Code: Select all
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.
Benutzer kann Deckkraft/Mischung/Transformation ändern.
Wenn der Benutzer Masking öffnet, fügt SetupVC MaskingVC als untergeordnetes Element hinzu und gibt ihm containerMask + overlayImageView, sodass die Maske direkt über derselben Ebene gezeichnet wird.
applyOverlay() speichert Parameter (rotationAngle, opacity, blendMode, overlayFrame, containerSize) in der Overlay-Struktur – aber nicht die Maske, da das Modell kein Feld dafür hat und layer.mask nicht exportiert wird.
didTapApplyButton() ruft applyOverlay() + auf elegate?.applyOverlay(overlay:) + dismiss().
In OverlayMaskingViewController:
Empfangt canvasContainer, imageView, overlayImageView.
Bei jedem Strich: Erstellt eine Alpha-Maske → wendet sie auf overlayImageView.layer.mask für lokal an Vorschau.
Beim Anwenden: ruft nur „clearPreview(keepMask: true)“ auf und verwirft – die Maske wird nie an das Modell übergeben.
Overlay-Struktur beschreibt Overlay-Parameter (Name, Deckkraft, BlendMode, Transformation usw.), hat aber keine Maskendaten, sodass das Ergebnis nicht zwischen Bildschirmen gespeichert wird.
 Mobile version
 Mobile version