Added uiview dropshadow extension. ColorWheelView now supports setting a border

This commit is contained in:
Jonathan Cardasis 2019-04-11 23:08:00 -04:00
parent 01f0cc0e57
commit 5a6d7b5e27
4 changed files with 96 additions and 14 deletions

View File

@ -19,6 +19,7 @@
FC1BD8C22207D7B700817AF3 /* ChromaColorPicker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3503B82F1F2689BC00750356 /* ChromaColorPicker.framework */; };
FCCA42A5226022A800BE2FF9 /* ColorWheelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A4226022A800BE2FF9 /* ColorWheelView.swift */; };
FCCA42A7226023F000BE2FF9 /* ChromaColorHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */; };
FCCA42AA2260329900BE2FF9 /* UIKit+DropShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A92260329900BE2FF9 /* UIKit+DropShadow.swift */; };
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */; };
/* End PBXBuildFile section */
@ -75,6 +76,7 @@
FC1BD8CD2207FCE100817AF3 /* ColorModeToggleButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorModeToggleButton.swift; sourceTree = "<group>"; };
FCCA42A4226022A800BE2FF9 /* ColorWheelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorWheelView.swift; sourceTree = "<group>"; };
FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorHandle.swift; sourceTree = "<group>"; };
FCCA42A92260329900BE2FF9 /* UIKit+DropShadow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+DropShadow.swift"; sourceTree = "<group>"; };
FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorPicker.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -108,6 +110,7 @@
3503B8301F2689BC00750356 /* Source */ = {
isa = PBXGroup;
children = (
FCCA42A82260325F00BE2FF9 /* Extensions */,
FCCA427822601F8800BE2FF9 /* Legacy */,
3503B8311F2689BC00750356 /* ChromaColorPicker.h */,
3503B8321F2689BC00750356 /* Info.plist */,
@ -173,6 +176,14 @@
path = Legacy;
sourceTree = "<group>";
};
FCCA42A82260325F00BE2FF9 /* Extensions */ = {
isa = PBXGroup;
children = (
FCCA42A92260329900BE2FF9 /* UIKit+DropShadow.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -322,6 +333,7 @@
buildActionMask = 2147483647;
files = (
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */,
FCCA42AA2260329900BE2FF9 /* UIKit+DropShadow.swift in Sources */,
FCCA42A7226023F000BE2FF9 /* ChromaColorHandle.swift in Sources */,
FCCA42A5226022A800BE2FF9 /* ColorWheelView.swift in Sources */,
);

View File

@ -19,7 +19,20 @@ public protocol ChromaColorPickerDelegate {
@IBDesignable
public class ChromaColorPicker: UIControl {
@IBInspectable public var borderWidth: CGFloat = 8.0 {
didSet { setNeedsLayout() }
}
@IBInspectable public var borderColor: UIColor = .white {
didSet { setNeedsLayout() }
}
@IBInspectable public var showsShadow: Bool = true {
didSet { setNeedsLayout() }
}
//MARK: - Initialization
override public init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
@ -30,14 +43,10 @@ public class ChromaColorPicker: UIControl {
self.commonInit()
}
public override func setNeedsDisplay() {
super.setNeedsDisplay()
print("called")
}
public override func layoutSubviews() {
super.layoutSubviews()
updateShadowIfNeeded()
updateBorderIfNeeded()
}
public func addHandle(at color: UIColor? = nil) -> ChromaColorHandle {
@ -51,10 +60,11 @@ public class ChromaColorPicker: UIControl {
self.backgroundColor = UIColor.clear
self.layer.masksToBounds = false
setupColorWheelView()
applySmoothingMaskToColorWheel()
setupGestures()
}
// MARK: Setup & Layout
internal func setupColorWheelView() {
colorWheelView.translatesAutoresizingMaskIntoConstraints = false
addSubview(colorWheelView)
@ -66,9 +76,18 @@ public class ChromaColorPicker: UIControl {
])
}
/// Applys a smoothing mask to the color wheel to account for CIFilter's image dithering at the edges.
internal func applySmoothingMaskToColorWheel() {
internal func updateShadowIfNeeded() {
if showsShadow {
let dropShadowHeight = bounds.height * 0.01
applyDropShadow(color: UIColor.black, opacity: 0.2, offset: CGSize(width: 0, height: dropShadowHeight), radius: 2)
} else {
removeDropShadow()
}
}
internal func updateBorderIfNeeded() {
colorWheelView.layer.borderColor = borderColor.cgColor
colorWheelView.layer.borderWidth = borderWidth
}
internal func setupGestures() {
@ -77,12 +96,16 @@ public class ChromaColorPicker: UIControl {
colorWheelView.addGestureRecognizer(tapGesture)
}
// MARK: Actions
@objc
internal func colorWheelTapped(_ gesture: UITapGestureRecognizer) {
let location = gesture.location(in: colorWheelView)
let pixelColor = colorWheelView.pixelColor(at: location)
print(pixelColor)
}
}
internal let defaultHandleColorPosition: UIColor = .black

View File

@ -22,6 +22,8 @@ public class ColorWheelView: UIView {
public override func layoutSubviews() {
super.layoutSubviews()
layer.masksToBounds = false
layer.cornerRadius = radius
let minDimensionSize = min(bounds.width, bounds.height)
if let colorWheelImage = makeColorWheelImage(radius: minDimensionSize) {
@ -29,6 +31,10 @@ public class ColorWheelView: UIView {
}
}
public var radius: CGFloat {
return max(bounds.width, bounds.height) / 2.0
}
/**
Returns the (x,y) location of the color provided within the ColorWheelView.
*/
@ -87,10 +93,6 @@ public class ColorWheelView: UIView {
// MARK: - Private
internal let imageView = UIImageView()
internal var radius: CGFloat {
return bounds.width / 2.0
}
internal func commonInit() {
backgroundColor = .clear
setupImageView()

View File

@ -0,0 +1,45 @@
//
// UIKit+DropShadow.swift
// ChromaColorPicker
//
// Created by Jon Cardasis on 4/11/19.
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
//
import UIKit
internal struct ShadowProperties {
internal let color: CGColor
internal let opacity: Float
internal let offset: CGSize
internal let radius: CGFloat
}
internal extension UIView {
internal var dropShadowProperties: ShadowProperties? {
guard let shadowColor = layer.shadowColor else { return nil }
return ShadowProperties(color: shadowColor, opacity: layer.shadowOpacity, offset: layer.shadowOffset, radius: layer.shadowRadius)
}
internal func applyDropShadow(color: UIColor, opacity: Float, offset: CGSize, radius: CGFloat) {
self.clipsToBounds = false
layer.masksToBounds = false
layer.shadowColor = color.cgColor
layer.shadowOpacity = opacity
layer.shadowOffset = offset
layer.shadowRadius = radius
layer.shouldRasterize = true
layer.rasterizationScale = UIScreen.main.scale
}
internal func applyDropShadow(_ properties: ShadowProperties) {
applyDropShadow(color: UIColor(cgColor: properties.color), opacity: properties.opacity, offset: properties.offset, radius: properties.radius)
}
internal func removeDropShadow() {
layer.shadowColor = nil
layer.shadowOpacity = 0
}
}