Skip to content

Commit

Permalink
feat: make CropToolBar Sizable (#171)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: refactor CropToolbarProtocol. Add heightForVerticalOrientation and widthForHorizonOrientation, remove heightForVerticalOrientationConstraint and widthForHorizonOrientationConstraint

fix example project autoLayout conflicts
  • Loading branch information
guoyingtao committed Jul 8, 2022
1 parent 42b89cd commit d01662f
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 155 deletions.
1 change: 0 additions & 1 deletion Example/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<constraints>
<constraint firstItem="vyB-So-c13" firstAttribute="top" secondItem="pUS-Eo-0ui" secondAttribute="bottom" constant="16" id="3Ig-aR-0l7"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="vyB-So-c13" secondAttribute="bottom" constant="32" id="EFp-sl-UGU"/>
<constraint firstItem="pUS-Eo-0ui" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="16" id="PSN-fn-n11"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="pUS-Eo-0ui" secondAttribute="trailing" constant="32" id="Vtc-MK-elT"/>
<constraint firstItem="pUS-Eo-0ui" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="32" id="rVC-N5-3Bn"/>
Expand Down
17 changes: 14 additions & 3 deletions Example/CustomizedCropToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import UIKit
import Mantis

class CustomizedCropToolbar: UIView, CropToolbarProtocol {
var heightForVerticalOrientation: CGFloat?

var widthForHorizonOrientation: CGFloat?

var iconProvider: CropToolbarIconProvider?

var heightForVerticalOrientationConstraint: NSLayoutConstraint?
var widthForHorizonOrientationConstraint: NSLayoutConstraint?
weak var cropToolbarDelegate: CropToolbarDelegate?

private var fixedRatioSettingButton: UIButton?
Expand Down Expand Up @@ -59,14 +61,23 @@ class CustomizedCropToolbar: UIView, CropToolbarProtocol {
fixedRatioSettingButton?.setTitle("Ratio", for: .normal)
}

func adjustUIWhenOrientationChange() {
func adjustLayoutWhenOrientationChange() {
if Orientation.isPortrait {
stackView?.axis = .horizontal
} else {
stackView?.axis = .vertical
}
}

public override var intrinsicContentSize: CGSize {
let superSize = super.intrinsicContentSize
if Orientation.isPortrait {
return CGSize(width: superSize.width, height: heightForVerticalOrientation ?? 44)
} else {
return CGSize(width: widthForHorizonOrientation ?? 44, height: superSize.height)
}
}

func getRatioListPresentSourceView() -> UIView? {
return fixedRatioSettingButton
}
Expand Down
18 changes: 14 additions & 4 deletions Example/CustomizedCropToolbarWithoutList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import UIKit
import Mantis

class CustomizedCropToolbarWithoutList: UIView, CropToolbarProtocol {
var iconProvider: CropToolbarIconProvider?
var heightForVerticalOrientation: CGFloat?

var heightForVerticalOrientationConstraint: NSLayoutConstraint?
var widthForHorizonOrientationConstraint: NSLayoutConstraint?
var widthForHorizonOrientation: CGFloat?

var iconProvider: CropToolbarIconProvider?
weak var cropToolbarDelegate: CropToolbarDelegate?

private var fixedRatioSettingButton: UIButton?
Expand Down Expand Up @@ -73,7 +74,16 @@ class CustomizedCropToolbarWithoutList: UIView, CropToolbarProtocol {
public func handleFixedRatioUnSetted() {
}

func adjustUIWhenOrientationChange() {
public override var intrinsicContentSize: CGSize {
let superSize = super.intrinsicContentSize
if Orientation.isPortrait {
return CGSize(width: superSize.width, height: heightForVerticalOrientation ?? 44)
} else {
return CGSize(width: widthForHorizonOrientation ?? 44, height: superSize.height)
}
}

func adjustLayoutWhenOrientationChange() {
if Orientation.isPortrait {
stackView?.axis = .horizontal
} else {
Expand Down
5 changes: 2 additions & 3 deletions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class ViewController: UIViewController, CropViewControllerDelegate {
}
var config = Mantis.Config()

config.cropToolbarConfig.cropToolbarHeightForVertialOrientation = 44
config.cropToolbarConfig.cropToolbarHeightForVertialOrientation = 100
config.cropToolbarConfig.cropToolbarWidthForHorizontalOrientation = 80

let cropToolbar = CustomizedCropToolbar(frame: .zero)
Expand All @@ -122,7 +122,7 @@ class ViewController: UIViewController, CropViewControllerDelegate {
}
var config = Mantis.Config()

config.cropToolbarConfig.cropToolbarHeightForVertialOrientation = 44
config.cropToolbarConfig.cropToolbarHeightForVertialOrientation = 160
config.cropToolbarConfig.cropToolbarWidthForHorizontalOrientation = 80

let cropToolbar = CustomizedCropToolbarWithoutList(frame: .zero)
Expand All @@ -133,7 +133,6 @@ class ViewController: UIViewController, CropViewControllerDelegate {
cropViewController.modalPresentationStyle = .fullScreen
cropViewController.delegate = self
present(cropViewController, animated: true)

}

@IBAction func clockwiseRotationButtonTouched(_ sender: Any) {
Expand Down
1 change: 0 additions & 1 deletion Sources/Mantis/CropView/CropView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ extension CropView {
animation: Bool = true,
zoom: Bool = true,
completion: @escaping ()->Void) {

let scaleX: CGFloat
let scaleY: CGFloat

Expand Down
225 changes: 118 additions & 107 deletions Sources/Mantis/CropViewController/CropToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public enum CropToolbarMode {
}

public class CropToolbar: UIView, CropToolbarProtocol {
public var heightForVerticalOrientation: CGFloat?
public var widthForHorizonOrientation: CGFloat?

public var iconProvider: CropToolbarIconProvider?

public var heightForVerticalOrientationConstraint: NSLayoutConstraint?
public var widthForHorizonOrientationConstraint: NSLayoutConstraint?

public weak var cropToolbarDelegate: CropToolbarDelegate?

var fixedRatioSettingButton: UIButton?
Expand All @@ -33,108 +33,11 @@ public class CropToolbar: UIView, CropToolbarProtocol {
var config: CropToolbarConfig!

private var optionButtonStackView: UIStackView?

private func createOptionButton(withTitle title: String?, andAction action: Selector) -> UIButton {
let buttonColor = UIColor.white
let buttonFontSize: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad) ?
config.optionButtonFontSizeForPad :
config.optionButtonFontSize

let buttonFont = UIFont.systemFont(ofSize: buttonFontSize)

let button = UIButton(type: .system)
button.tintColor = .white
button.titleLabel?.font = buttonFont

if let title = title {
button.setTitle(title, for: .normal)
button.setTitleColor(buttonColor, for: .normal)
}

button.addTarget(self, action: action, for: .touchUpInside)
button.contentEdgeInsets = UIEdgeInsets(top: 4, left: 10, bottom: 4, right: 10)

return button
}

private func createCancelButton() {
let cancelText = LocalizedHelper.getString("Mantis.Cancel", value: "Cancel")
cancelButton = createOptionButton(withTitle: cancelText, andAction: #selector(cancel))
}

private func createCounterClockwiseRotationButton() {
counterClockwiseRotationButton = createOptionButton(withTitle: nil, andAction: #selector(counterClockwiseRotate))
let icon = iconProvider?.getCounterClockwiseRotationIcon() ?? ToolBarButtonImageBuilder.rotateCCWImage()
counterClockwiseRotationButton?.setImage(icon, for: .normal)
}

private func createClockwiseRotationButton() {
clockwiseRotationButton = createOptionButton(withTitle: nil, andAction: #selector(clockwiseRotate))
let icon = iconProvider?.getClockwiseRotationIcon() ?? ToolBarButtonImageBuilder.rotateCWImage()
clockwiseRotationButton?.setImage(icon, for: .normal)
}

private func createAlterCropper90DegreeButton() {
alterCropper90DegreeButton = createOptionButton(withTitle: nil, andAction: #selector(alterCropper90Degree))
let icon = iconProvider?.getAlterCropper90DegreeIcon() ?? ToolBarButtonImageBuilder.alterCropper90DegreeImage()
alterCropper90DegreeButton?.setImage(icon, for: .normal)
}

private func createResetButton(with image: UIImage? = nil) {
if let image = image {
resetButton = createOptionButton(withTitle: nil, andAction: #selector(reset))
resetButton?.setImage(image, for: .normal)
} else {
let resetText = LocalizedHelper.getString("Mantis.Reset", value: "Reset")
resetButton = createOptionButton(withTitle: resetText, andAction: #selector(reset))
}
}

private func createSetRatioButton() {
fixedRatioSettingButton = createOptionButton(withTitle: nil, andAction: #selector(setRatio))
let icon = iconProvider?.getSetRatioIcon() ?? ToolBarButtonImageBuilder.clampImage()
fixedRatioSettingButton?.setImage(icon, for: .normal)
}

private func createCropButton() {
let doneText = LocalizedHelper.getString("Mantis.Done", value: "Done")
cropButton = createOptionButton(withTitle: doneText, andAction: #selector(crop))
}

private func createButtonContainer() {
optionButtonStackView = UIStackView()
addSubview(optionButtonStackView!)

optionButtonStackView?.distribution = .equalCentering
optionButtonStackView?.isLayoutMarginsRelativeArrangement = true
}

private func setButtonContainerLayout() {
optionButtonStackView?.translatesAutoresizingMaskIntoConstraints = false
optionButtonStackView?.topAnchor.constraint(equalTo: topAnchor).isActive = true
optionButtonStackView?.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
optionButtonStackView?.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
optionButtonStackView?.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}

private func addButtonsToContainer(button: UIButton?) {
if let button = button {
optionButtonStackView?.addArrangedSubview(button)
}
}

private func addButtonsToContainer(buttons: [UIButton?]) {
buttons.forEach {
if let button = $0 {
optionButtonStackView?.addArrangedSubview(button)
}
}
}


public func createToolbarUI(config: CropToolbarConfig) {
self.config = config
backgroundColor = .black

if #available(macCatalyst 14.0, iOS 14.0, *) {
if UIDevice.current.userInterfaceIdiom == .mac {
backgroundColor = .white
Expand Down Expand Up @@ -188,12 +91,21 @@ public class CropToolbar: UIView, CropToolbarProtocol {
addButtonsToContainer(button: cropButton)
}
}

public override var intrinsicContentSize: CGSize {
let superSize = super.intrinsicContentSize
if Orientation.isPortrait {
return CGSize(width: superSize.width, height: heightForVerticalOrientation ?? 44)
} else {
return CGSize(width: widthForHorizonOrientation ?? 44, height: superSize.height)
}
}

public func getRatioListPresentSourceView() -> UIView? {
return fixedRatioSettingButton
}

public func respondToOrientationChange() {
public func adjustLayoutWhenOrientationChange() {
if Orientation.isPortrait {
optionButtonStackView?.axis = .horizontal
optionButtonStackView?.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
Expand All @@ -218,11 +130,10 @@ public class CropToolbar: UIView, CropToolbarProtocol {
public func handleCropViewDidBecomeUnResettable() {
resetButton?.isHidden = true
}
}

public func initConstraints(heightForVerticalOrientation: CGFloat, widthForHorizonOrientation: CGFloat) {

}

// Objc functions
extension CropToolbar {
@objc private func cancel() {
cropToolbarDelegate?.didSelectCancel()
}
Expand Down Expand Up @@ -251,3 +162,103 @@ public class CropToolbar: UIView, CropToolbarProtocol {
cropToolbarDelegate?.didSelectCrop()
}
}

// private functions
extension CropToolbar {
private func createOptionButton(withTitle title: String?, andAction action: Selector) -> UIButton {
let buttonColor = UIColor.white
let buttonFontSize: CGFloat = (UIDevice.current.userInterfaceIdiom == .pad) ?
config.optionButtonFontSizeForPad :
config.optionButtonFontSize

let buttonFont = UIFont.systemFont(ofSize: buttonFontSize)

let button = UIButton(type: .system)
button.tintColor = .white
button.titleLabel?.font = buttonFont

if let title = title {
button.setTitle(title, for: .normal)
button.setTitleColor(buttonColor, for: .normal)
}

button.addTarget(self, action: action, for: .touchUpInside)
button.contentEdgeInsets = UIEdgeInsets(top: 4, left: 10, bottom: 4, right: 10)

return button
}

private func createCancelButton() {
let cancelText = LocalizedHelper.getString("Mantis.Cancel", value: "Cancel")
cancelButton = createOptionButton(withTitle: cancelText, andAction: #selector(cancel))
}

private func createCounterClockwiseRotationButton() {
counterClockwiseRotationButton = createOptionButton(withTitle: nil, andAction: #selector(counterClockwiseRotate))
let icon = iconProvider?.getCounterClockwiseRotationIcon() ?? ToolBarButtonImageBuilder.rotateCCWImage()
counterClockwiseRotationButton?.setImage(icon, for: .normal)
}

private func createClockwiseRotationButton() {
clockwiseRotationButton = createOptionButton(withTitle: nil, andAction: #selector(clockwiseRotate))
let icon = iconProvider?.getClockwiseRotationIcon() ?? ToolBarButtonImageBuilder.rotateCWImage()
clockwiseRotationButton?.setImage(icon, for: .normal)
}

private func createAlterCropper90DegreeButton() {
alterCropper90DegreeButton = createOptionButton(withTitle: nil, andAction: #selector(alterCropper90Degree))
let icon = iconProvider?.getAlterCropper90DegreeIcon() ?? ToolBarButtonImageBuilder.alterCropper90DegreeImage()
alterCropper90DegreeButton?.setImage(icon, for: .normal)
}

private func createResetButton(with image: UIImage? = nil) {
if let image = image {
resetButton = createOptionButton(withTitle: nil, andAction: #selector(reset))
resetButton?.setImage(image, for: .normal)
} else {
let resetText = LocalizedHelper.getString("Mantis.Reset", value: "Reset")
resetButton = createOptionButton(withTitle: resetText, andAction: #selector(reset))
}
}

private func createSetRatioButton() {
fixedRatioSettingButton = createOptionButton(withTitle: nil, andAction: #selector(setRatio))
let icon = iconProvider?.getSetRatioIcon() ?? ToolBarButtonImageBuilder.clampImage()
fixedRatioSettingButton?.setImage(icon, for: .normal)
}

private func createCropButton() {
let doneText = LocalizedHelper.getString("Mantis.Done", value: "Done")
cropButton = createOptionButton(withTitle: doneText, andAction: #selector(crop))
}

private func createButtonContainer() {
optionButtonStackView = UIStackView()
addSubview(optionButtonStackView!)

optionButtonStackView?.distribution = .equalCentering
optionButtonStackView?.isLayoutMarginsRelativeArrangement = true
}

private func setButtonContainerLayout() {
optionButtonStackView?.translatesAutoresizingMaskIntoConstraints = false
optionButtonStackView?.topAnchor.constraint(equalTo: topAnchor).isActive = true
optionButtonStackView?.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
optionButtonStackView?.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
optionButtonStackView?.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
}

private func addButtonsToContainer(button: UIButton?) {
if let button = button {
optionButtonStackView?.addArrangedSubview(button)
}
}

private func addButtonsToContainer(buttons: [UIButton?]) {
buttons.forEach {
if let button = $0 {
optionButtonStackView?.addArrangedSubview(button)
}
}
}
}

0 comments on commit d01662f

Please sign in to comment.