Skip to content

Commit

Permalink
fix: fix the wrong mask rounded rectangle value (#124)
Browse files Browse the repository at this point in the history
* fix: fix wrong roundedRect mask issue

set the ratio to a fixed value 1 when cropShapeType is heart just like circle and square.

* chore: restore use_frameworks!

* fix: fix the wrong rounded corner
  • Loading branch information
guoyingtao authored Aug 4, 2021
1 parent f69682f commit 33a8865
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 49 deletions.
28 changes: 14 additions & 14 deletions Example/MantisExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
1F3B49FC588AD98287DE4267 /* libPods-MantisExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B8C6829EE0F5C72DC10C396B /* libPods-MantisExample.a */; };
1AC3B46DF36D97844A4CEA4E /* Pods_MantisExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B100014666B3974EEDE05B0C /* Pods_MantisExampleTests.framework */; };
37F095D77401112C083BB830 /* Pods_MantisExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A7EAB9797A43C2A34E26823 /* Pods_MantisExample.framework */; };
5F0852B5237918510031B75D /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F0852B4237918510031B75D /* ImagePicker.swift */; };
5FC10B15217A9EDF00582874 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC10B14217A9EDF00582874 /* AppDelegate.swift */; };
5FC10B17217A9EDF00582874 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC10B16217A9EDF00582874 /* ViewController.swift */; };
Expand All @@ -17,7 +18,6 @@
5FC10B2A217A9EE100582874 /* MantisTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC10B29217A9EE100582874 /* MantisTests.swift */; };
5FD045EA245619D400B9D3D2 /* CustomizedCropToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FD045E9245619D400B9D3D2 /* CustomizedCropToolbar.swift */; };
5FEBA88221961E4A0018DE62 /* EmbeddedCropViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FEBA88121961E4A0018DE62 /* EmbeddedCropViewController.swift */; };
AF2FE35191AA9D90825785AE /* libPods-MantisExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 652EE158B8C4F04DF075F81D /* libPods-MantisExampleTests.a */; };
CCBF2F602525B3050081B8FE /* CustomizedCropToolbarWithoutList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCBF2F5F2525B3050081B8FE /* CustomizedCropToolbarWithoutList.swift */; };
/* End PBXBuildFile section */

Expand All @@ -32,6 +32,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
3A7EAB9797A43C2A34E26823 /* Pods_MantisExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MantisExample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3FC821D838EDAC646C860226 /* Pods-MantisExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MantisExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-MantisExampleTests/Pods-MantisExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
5F0852B4237918510031B75D /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = "<group>"; };
5F21BBB22448036100B7B0C2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
Expand All @@ -50,10 +51,9 @@
5FD045E9245619D400B9D3D2 /* CustomizedCropToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomizedCropToolbar.swift; sourceTree = "<group>"; };
5FEBA88121961E4A0018DE62 /* EmbeddedCropViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmbeddedCropViewController.swift; sourceTree = "<group>"; };
61C386518C3C25E57F8C83A5 /* Pods-MantisExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MantisExampleTests.release.xcconfig"; path = "Target Support Files/Pods-MantisExampleTests/Pods-MantisExampleTests.release.xcconfig"; sourceTree = "<group>"; };
652EE158B8C4F04DF075F81D /* libPods-MantisExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MantisExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
89C5370690AB91AB238B90E9 /* Pods-MantisExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MantisExample.release.xcconfig"; path = "Target Support Files/Pods-MantisExample/Pods-MantisExample.release.xcconfig"; sourceTree = "<group>"; };
9326C1CDF121300C5CAAE2BE /* Pods-MantisExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MantisExample.debug.xcconfig"; path = "Target Support Files/Pods-MantisExample/Pods-MantisExample.debug.xcconfig"; sourceTree = "<group>"; };
B8C6829EE0F5C72DC10C396B /* libPods-MantisExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MantisExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B100014666B3974EEDE05B0C /* Pods_MantisExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MantisExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CCBF2F5F2525B3050081B8FE /* CustomizedCropToolbarWithoutList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomizedCropToolbarWithoutList.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand All @@ -62,15 +62,15 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1F3B49FC588AD98287DE4267 /* libPods-MantisExample.a in Frameworks */,
37F095D77401112C083BB830 /* Pods_MantisExample.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
5FC10B22217A9EE100582874 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
AF2FE35191AA9D90825785AE /* libPods-MantisExampleTests.a in Frameworks */,
1AC3B46DF36D97844A4CEA4E /* Pods_MantisExampleTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -80,8 +80,8 @@
5F3BE15921993A7C005C4BD8 /* Frameworks */ = {
isa = PBXGroup;
children = (
B8C6829EE0F5C72DC10C396B /* libPods-MantisExample.a */,
652EE158B8C4F04DF075F81D /* libPods-MantisExampleTests.a */,
3A7EAB9797A43C2A34E26823 /* Pods_MantisExample.framework */,
B100014666B3974EEDE05B0C /* Pods_MantisExampleTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
Expand Down Expand Up @@ -147,7 +147,7 @@
5FC10B0D217A9EDF00582874 /* Sources */,
5FC10B0E217A9EDF00582874 /* Frameworks */,
5FC10B0F217A9EDF00582874 /* Resources */,
12B88BB2DAEBCE3C6ACE78D7 /* [CP] Copy Pods Resources */,
5B5D9B6DDD60E517CAAD07B0 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -261,21 +261,21 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
12B88BB2DAEBCE3C6ACE78D7 /* [CP] Copy Pods Resources */ = {
5B5D9B6DDD60E517CAAD07B0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-MantisExample/Pods-MantisExample-resources-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-MantisExample/Pods-MantisExample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-MantisExample/Pods-MantisExample-resources-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-MantisExample/Pods-MantisExample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MantisExample/Pods-MantisExample-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MantisExample/Pods-MantisExample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
B990B0C0191568D739FE220D /* [CP] Check Pods Manifest.lock */ = {
Expand Down
2 changes: 1 addition & 1 deletion Example/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

target 'MantisExample' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
#use_frameworks!
use_frameworks!

# Pods for MantisExample
pod 'Mantis', :path => '../'
Expand Down
25 changes: 14 additions & 11 deletions Sources/Mantis/CropView/CropMaskViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,33 @@ class CropMaskViewManager {
var cropVisualEffectType: CropVisualEffectType = .blurDark

init(with superview: UIView,
cropRatio: CGFloat = 1.0,
cropShapeType: CropShapeType = .rect,
cropVisualEffectType: CropVisualEffectType = .blurDark) {

setup(in: superview)
setup(in: superview, cropRatio: cropRatio)
self.cropShapeType = cropShapeType
self.cropVisualEffectType = cropVisualEffectType
}

private func setupOverlayView(in view: UIView) {
dimmingView = CropDimmingView(cropShapeType: cropShapeType)
private func setupOverlayView(in view: UIView, cropRatio: CGFloat = 1.0) {
dimmingView = CropDimmingView(cropShapeType: cropShapeType, cropRatio: cropRatio)
dimmingView.isUserInteractionEnabled = false
dimmingView.alpha = 0
view.addSubview(dimmingView)
}

private func setupTranslucencyView(in view: UIView) {
visualEffectView = CropVisualEffectView(cropShapeType: cropShapeType, effectType: cropVisualEffectType)
private func setupTranslucencyView(in view: UIView, cropRatio: CGFloat = 1.0) {
visualEffectView = CropVisualEffectView(cropShapeType: cropShapeType,
effectType: cropVisualEffectType,
cropRatio: cropRatio)
visualEffectView.isUserInteractionEnabled = false
view.addSubview(visualEffectView)
}

func setup(in view: UIView) {
setupOverlayView(in: view)
setupTranslucencyView(in: view)
func setup(in view: UIView, cropRatio: CGFloat = 1.0) {
setupOverlayView(in: view, cropRatio: cropRatio)
setupTranslucencyView(in: view, cropRatio: cropRatio)
}

func removeMaskViews() {
Expand All @@ -66,8 +69,8 @@ class CropMaskViewManager {
}
}

func adaptMaskTo(match cropRect: CGRect) {
dimmingView.adaptMaskTo(match: cropRect)
visualEffectView.adaptMaskTo(match: cropRect)
func adaptMaskTo(match cropRect: CGRect, cropRatio: CGFloat) {
dimmingView.adaptMaskTo(match: cropRect, cropRatio: cropRatio)
visualEffectView.adaptMaskTo(match: cropRect, cropRatio: cropRatio)
}
}
11 changes: 9 additions & 2 deletions Sources/Mantis/CropView/CropView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class CropView: UIView {

lazy var scrollView = CropScrollView(frame: bounds)
lazy var cropMaskViewManager = CropMaskViewManager(with: self,
cropRatio: CGFloat(getImageRatioH()),
cropShapeType: cropShapeType,
cropVisualEffectType: cropVisualEffectType)

Expand Down Expand Up @@ -93,7 +94,13 @@ class CropView: UIView {
{ [unowned self] _, changed in
guard let cropFrame = changed.newValue else { return }
self.gridOverlayView.frame = cropFrame
self.cropMaskViewManager.adaptMaskTo(match: cropFrame)

var cropRatio: CGFloat = 1.0
if self.gridOverlayView.frame.height != 0 {
cropRatio = self.gridOverlayView.frame.width / self.gridOverlayView.frame.height
}

self.cropMaskViewManager.adaptMaskTo(match: cropFrame, cropRatio: cropRatio)
}

initalRender()
Expand Down Expand Up @@ -191,7 +198,7 @@ class CropView: UIView {

func resetUIFrame() {
cropMaskViewManager.removeMaskViews()
cropMaskViewManager.setup(in: self)
cropMaskViewManager.setup(in: self, cropRatio: CGFloat(getImageRatioH()))
viewModel.resetCropFrame(by: getInitialCropBoxRect())

scrollView.transform = .identity
Expand Down
2 changes: 1 addition & 1 deletion Sources/Mantis/CropViewController/CropViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class CropViewController: UIViewController {
self.config = config

switch config.cropShapeType {
case .circle, .square:
case .circle, .square, .heart:
self.config.presetFixedRatioType = .alwaysUsingOnePresetFixedRatio(ratio: 1)
default:
()
Expand Down
12 changes: 8 additions & 4 deletions Sources/Mantis/MaskBackground/CropDimmingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
import UIKit

class CropDimmingView: UIView, CropMaskProtocol {
var innerLayer: CALayer?

var cropShapeType: CropShapeType = .rect
var imageRatio: CGFloat = 1.0

convenience init(cropShapeType: CropShapeType = .rect) {
convenience init(cropShapeType: CropShapeType = .rect, cropRatio: CGFloat = 1.0) {
self.init(frame: CGRect.zero)
self.cropShapeType = cropShapeType
initialize()
initialize(cropRatio: cropRatio)
}

func setMask() {
let layer = createOverLayer(opacity: 0.5)
func setMask(cropRatio: CGFloat) {
let layer = createOverLayer(opacity: 0.5, cropRatio: cropRatio)
self.layer.addSublayer(layer)
innerLayer = layer
}
}
43 changes: 31 additions & 12 deletions Sources/Mantis/MaskBackground/CropMaskProtocal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ fileprivate let initialFrameLength: CGFloat = 1000

protocol CropMaskProtocol where Self: UIView {
var cropShapeType: CropShapeType { get set }
var innerLayer: CALayer? { get set }

func initialize()
func setMask()
func adaptMaskTo(match cropRect: CGRect)
func initialize(cropRatio: CGFloat)
func setMask(cropRatio: CGFloat)
func adaptMaskTo(match cropRect: CGRect, cropRatio: CGFloat)
}

extension CropMaskProtocol {
func initialize() {
func initialize(cropRatio: CGFloat = 1.0) {
setInitialFrame()
setMask()
setMask(cropRatio: cropRatio)
}

private func setInitialFrame() {
Expand All @@ -37,20 +38,38 @@ extension CropMaskProtocol {
self.frame = CGRect(x: x, y: y, width: width, height: height)
}

func adaptMaskTo(match cropRect: CGRect) {
let scaleX = cropRect.width / minOverLayerUnit
let scaleY = cropRect.height / minOverLayerUnit
func adaptMaskTo(match cropRect: CGRect, cropRatio: CGFloat) {
let scaleX: CGFloat

switch cropShapeType {
case .roundedRect:
innerLayer?.removeFromSuperlayer()
setMask(cropRatio: cropRatio)
scaleX = cropRect.width / (minOverLayerUnit * cropRatio)
default:
scaleX = cropRect.width / minOverLayerUnit
}

let scaleY = cropRect.height / minOverLayerUnit

transform = CGAffineTransform(scaleX: scaleX, y: scaleY)

self.frame.origin.x = cropRect.midX - self.frame.width / 2
self.frame.origin.y = cropRect.midY - self.frame.height / 2
}

func createOverLayer(opacity: Float) -> CAShapeLayer {
let x = bounds.midX - minOverLayerUnit / 2
func createOverLayer(opacity: Float, cropRatio: CGFloat = 1.0) -> CAShapeLayer {
let coff: CGFloat
switch cropShapeType {
case .roundedRect:
coff = cropRatio
default:
coff = 1
}

let x = bounds.midX - minOverLayerUnit * coff / 2
let y = bounds.midY - minOverLayerUnit / 2
let initialRect = CGRect(x: x, y: y, width: minOverLayerUnit, height: minOverLayerUnit)
let initialRect = CGRect(x: x, y: y, width: minOverLayerUnit * coff, height: minOverLayerUnit)

let path = UIBezierPath(rect: self.bounds)

Expand Down
15 changes: 11 additions & 4 deletions Sources/Mantis/MaskBackground/CropVisualEffectView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
import UIKit

class CropVisualEffectView: UIVisualEffectView, CropMaskProtocol {
var innerLayer: CALayer?

var cropShapeType: CropShapeType = .rect
var imageRatio: CGFloat = 1.0

fileprivate var translucencyEffect: UIVisualEffect?

convenience init(cropShapeType: CropShapeType = .rect, effectType: CropVisualEffectType = .blurDark) {
convenience init(cropShapeType: CropShapeType = .rect,
effectType: CropVisualEffectType = .blurDark,
cropRatio: CGFloat = 1.0) {

let (translucencyEffect, backgroundColor) = CropVisualEffectView.getEffect(byType: effectType)

Expand All @@ -22,16 +27,18 @@ class CropVisualEffectView: UIVisualEffectView, CropMaskProtocol {
self.translucencyEffect = translucencyEffect
self.backgroundColor = backgroundColor

initialize()
initialize(cropRatio: cropRatio)
}

func setMask() {
let layer = createOverLayer(opacity: 0.98)
func setMask(cropRatio: CGFloat) {
let layer = createOverLayer(opacity: 0.98, cropRatio: cropRatio)

let maskView = UIView(frame: self.bounds)
maskView.clipsToBounds = true
maskView.layer.addSublayer(layer)

innerLayer = layer

self.mask = maskView
}

Expand Down

0 comments on commit 33a8865

Please sign in to comment.