Skip to content

Commit

Permalink
Optimize the image editing experience
Browse files Browse the repository at this point in the history
  • Loading branch information
longitachi committed Jun 4, 2024
1 parent 603f960 commit d3afb0f
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

import UIKit

extension ZLImageEditorWrapper where Base: UIGraphicsImageRenderer {
public extension ZLImageEditorWrapper where Base: UIGraphicsImageRenderer {
static func renderImage(
size: CGSize,
formatConfig: ((UIGraphicsImageRendererFormat) -> Void)? = nil,
Expand Down
10 changes: 4 additions & 6 deletions Sources/General/ZLBaseStickerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ protocol ZLStickerViewAdditional: NSObject {
func addScale(_ scale: CGFloat)
}

class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {
public class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {
private enum Direction: Int {
case up = 0
case right = 90
Expand Down Expand Up @@ -142,7 +142,7 @@ class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {
self.originScale = originScale
self.originAngle = originAngle
self.originFrame = originFrame
self.maxGesScale = 4 / originScale
maxGesScale = 4 / originScale
super.init(frame: .zero)

self.gesScale = gesScale
Expand Down Expand Up @@ -171,7 +171,7 @@ class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
override public func layoutSubviews() {
super.layoutSubviews()

guard firstLayout else {
Expand Down Expand Up @@ -220,7 +220,6 @@ class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {
@objc func tapAction(_ ges: UITapGestureRecognizer) {
guard gesIsEnabled else { return }

superview?.bringSubviewToFront(self)
delegate?.stickerDidTap(self)
startTimer()
}
Expand Down Expand Up @@ -301,7 +300,6 @@ class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {
onOperation = true
cleanTimer()
borderView.layer.borderColor = UIColor.white.cgColor
superview?.bringSubviewToFront(self)
delegate?.stickerBeginOperation(self)
} else if !isOn, onOperation {
onOperation = false
Expand Down Expand Up @@ -350,7 +348,7 @@ class ZLBaseStickerView: UIView, UIGestureRecognizerDelegate {

// MARK: UIGestureRecognizerDelegate

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/General/ZLBaseStickertState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ZLBaseStickertState: NSObject {
let gesRotation: CGFloat
let totalTranslationPoint: CGPoint

init(
public init(
id: String,
image: UIImage,
originScale: CGFloat,
Expand Down Expand Up @@ -66,7 +66,7 @@ public class ZLTextStickerState: ZLBaseStickertState {
let font: UIFont?
let style: ZLInputTextStyle

init(
public init(
id: String,
text: String,
textColor: UIColor,
Expand Down
116 changes: 97 additions & 19 deletions Sources/General/ZLEditImageViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,19 @@
import UIKit

public struct ZLClipStatus {
var angle: CGFloat = 0
var editRect: CGRect
var angle: CGFloat = 0
var ratio: ZLImageClipRatio?

public init(
editRect: CGRect,
angle: CGFloat = 0,
ratio: ZLImageClipRatio? = nil
) {
self.editRect = editRect
self.angle = angle
self.ratio = ratio
}
}

public struct ZLAdjustStatus {
Expand All @@ -40,14 +50,24 @@ public struct ZLAdjustStatus {
var allValueIsZero: Bool {
brightness == 0 && contrast == 0 && saturation == 0
}

public init(
brightness: Float = 0,
contrast: Float = 0,
saturation: Float = 0
) {
self.brightness = brightness
self.contrast = contrast
self.saturation = saturation
}
}

public class ZLEditImageModel: NSObject {
public let drawPaths: [ZLDrawPath]

public let mosaicPaths: [ZLMosaicPath]

public let clipStatus: ZLClipStatus
public let clipStatus: ZLClipStatus?

public let adjustStatus: ZLAdjustStatus

Expand All @@ -58,13 +78,13 @@ public class ZLEditImageModel: NSObject {
public let actions: [ZLEditorAction]

public init(
drawPaths: [ZLDrawPath],
mosaicPaths: [ZLMosaicPath],
clipStatus: ZLClipStatus,
adjustStatus: ZLAdjustStatus,
selectFilter: ZLFilter,
stickers: [ZLBaseStickertState],
actions: [ZLEditorAction]
drawPaths: [ZLDrawPath] = [],
mosaicPaths: [ZLMosaicPath] = [],
clipStatus: ZLClipStatus? = nil,
adjustStatus: ZLAdjustStatus = ZLAdjustStatus(),
selectFilter: ZLFilter? = nil,
stickers: [ZLBaseStickertState] = [],
actions: [ZLEditorAction] = []
) {
self.drawPaths = drawPaths
self.mosaicPaths = mosaicPaths
Expand Down Expand Up @@ -116,7 +136,11 @@ open class ZLEditImageViewController: UIViewController {
return view
}()

open lazy var topShadowView = UIView()
open lazy var topShadowView: ZLPassThroughView = {
let shadowView = ZLPassThroughView()
shadowView.findResponderSticker = findResponderSticker(_:)
return shadowView
}()

open lazy var topShadowLayer: CAGradientLayer = {
let layer = CAGradientLayer()
Expand All @@ -125,7 +149,11 @@ open class ZLEditImageViewController: UIViewController {
return layer
}()

open lazy var bottomShadowView = UIView()
open lazy var bottomShadowView: ZLPassThroughView = {
let shadowView = ZLPassThroughView()
shadowView.findResponderSticker = findResponderSticker(_:)
return shadowView
}()

open lazy var bottomShadowLayer: CAGradientLayer = {
let layer = CAGradientLayer()
Expand Down Expand Up @@ -233,7 +261,6 @@ open class ZLEditImageViewController: UIViewController {
return imageView
}()


open lazy var ashbinView: UIView = {
let view = UIView()
view.backgroundColor = .zl.ashbinNormalBgColor
Expand Down Expand Up @@ -362,7 +389,7 @@ open class ZLEditImageViewController: UIViewController {

override open var prefersStatusBarHidden: Bool { true }

open override var prefersHomeIndicatorAutoHidden: Bool { true }
override open var prefersHomeIndicatorAutoHidden: Bool { true }

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
deviceIsiPhone() ? .portrait : .all
Expand Down Expand Up @@ -391,7 +418,7 @@ open class ZLEditImageViewController: UIViewController {
let m = ZLEditImageModel(
drawPaths: [],
mosaicPaths: [],
clipStatus: ZLClipStatus(angle: angle, editRect: editRect, ratio: ratio),
clipStatus: ZLClipStatus(editRect: editRect, angle: angle, ratio: ratio),
adjustStatus: ZLAdjustStatus(),
selectFilter: .normal,
stickers: [],
Expand Down Expand Up @@ -473,7 +500,7 @@ open class ZLEditImageViewController: UIViewController {
}
}

open override func viewDidAppear(_ animated: Bool) {
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

guard tools.contains(.draw) else { return }
Expand Down Expand Up @@ -755,7 +782,7 @@ open class ZLEditImageViewController: UIViewController {
if let selectedAdjustTool = selectedAdjustTool {
changeAdjustTool(selectedAdjustTool)
}
adjustSlider?.beginAdjust = { [weak self] in
adjustSlider?.beginAdjust = { [weak self] in
guard let `self` = self else { return }
self.preAdjustStatus = self.currentAdjustStatus
}
Expand Down Expand Up @@ -836,6 +863,19 @@ open class ZLEditImageViewController: UIViewController {
stickers.forEach { self.addSticker($0) }
}

/// 根据point查找可响应的sticker
func findResponderSticker(_ point: CGPoint) -> UIView? {
// 倒序查找subview
for sticker in stickersContainer.subviews.reversed() {
let rect = stickersContainer.convert(sticker.frame, to: view)
if rect.contains(point) {
return sticker
}
}

return nil
}

func rotationImageView() {
let transform = CGAffineTransform(rotationAngle: currentClipStatus.angle.zl.toPi)
imageView.transform = transform
Expand Down Expand Up @@ -897,7 +937,7 @@ open class ZLEditImageViewController: UIViewController {
vc.clipDoneBlock = { [weak self] angle, editRect, selectRatio in
guard let `self` = self else { return }

self.clipImage(status: ZLClipStatus(angle: angle, editRect: editRect, ratio: selectRatio))
self.clipImage(status: ZLClipStatus(editRect: editRect, angle: angle, ratio: selectRatio))
self.editorManager.storeAction(.clip(oldStatus: self.preClipStatus, newStatus: self.currentClipStatus))
}

Expand Down Expand Up @@ -1433,7 +1473,8 @@ open class ZLEditImageViewController: UIViewController {
textColor: textColor,
font: font,
style: style,
image: image, originScale: 1 / scale,
image: image,
originScale: 1 / scale,
originAngle: -currentClipStatus.angle,
originFrame: originFrame
)
Expand Down Expand Up @@ -1677,7 +1718,15 @@ extension ZLEditImageViewController: UIGestureRecognizerDelegate {
if gestureRecognizer is UITapGestureRecognizer {
if bottomShadowView.alpha == 1 {
let p = gestureRecognizer.location(in: view)
return !bottomShadowView.frame.contains(p)
let convertP = bottomShadowView.convert(p, from: view)
for subview in bottomShadowView.subviews {
if !subview.isHidden,
subview.alpha != 0,
subview.frame.contains(convertP) {
return false
}
}
return true
} else {
return true
}
Expand Down Expand Up @@ -1848,6 +1897,7 @@ extension ZLEditImageViewController: UICollectionViewDataSource, UICollectionVie

extension ZLEditImageViewController: ZLStickerViewDelegate {
func stickerBeginOperation(_ sticker: ZLBaseStickerView) {
stickersContainer.bringSubviewToFront(sticker)
preStickerState = sticker.state

setToolView(show: false)
Expand Down Expand Up @@ -1914,6 +1964,7 @@ extension ZLEditImageViewController: ZLStickerViewDelegate {
}

func stickerDidTap(_ sticker: ZLBaseStickerView) {
stickersContainer.bringSubviewToFront(sticker)
stickersContainer.subviews.forEach { view in
if view !== sticker {
(view as? ZLStickerViewAdditional)?.resetState()
Expand Down Expand Up @@ -2097,3 +2148,30 @@ extension ZLEditImageViewController: ZLEditorManagerDelegate {
adjustCollectionView.reloadData()
}
}

// MARK: 手势可透传的自定义view

public class ZLPassThroughView: UIView {
var findResponderSticker: ((CGPoint) -> UIView?)?

override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard bounds.contains(point) else {
return super.hitTest(point, with: event)
}

for view in subviews.reversed() {
let point = convert(point, to: view)
if !view.isHidden,
view.alpha != 0,
view.bounds.contains(point) {
return view.hitTest(point, with: event)
}
}

if let sticker = findResponderSticker?(convert(point, to: superview)) {
return sticker.hitTest(point, with: event)
}

return super.hitTest(point, with: event)
}
}
2 changes: 2 additions & 0 deletions Sources/General/ZLImageEditorConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ extension ZLImageClipRatio {
}

public extension ZLImageClipRatio {
@objc static let all: [ZLImageClipRatio] = [.custom, .circle, .wh1x1, .wh3x4, .wh4x3, .wh2x3, .wh3x2, .wh9x16, .wh16x9]

@objc static let custom = ZLImageClipRatio(title: "custom", whRatio: 0)

@objc static let circle = ZLImageClipRatio(title: "circle", whRatio: 1, isCircle: true)
Expand Down

0 comments on commit d3afb0f

Please sign in to comment.