mirror of
https://github.com/joncardasis/ChromaColorPicker.git
synced 2024-09-11 06:35:41 +03:00
Updated and improved tests. Fixed sync layout issue and updated UIControlEvents to events that make more sense. Added tests for brightness slider.
This commit is contained in:
parent
5046808248
commit
16b9f6aa6c
@ -23,6 +23,9 @@
|
|||||||
FC4387CB22625DA800F739F1 /* SliderHandleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4387CA22625DA800F739F1 /* SliderHandleView.swift */; };
|
FC4387CB22625DA800F739F1 /* SliderHandleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4387CA22625DA800F739F1 /* SliderHandleView.swift */; };
|
||||||
FC4387CD2262B82600F739F1 /* ChromaControlStylable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4387CC2262B82600F739F1 /* ChromaControlStylable.swift */; };
|
FC4387CD2262B82600F739F1 /* ChromaControlStylable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4387CC2262B82600F739F1 /* ChromaControlStylable.swift */; };
|
||||||
FC4387DE226974FD00F739F1 /* UIColor+Brightness.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4387DC226972EB00F739F1 /* UIColor+Brightness.swift */; };
|
FC4387DE226974FD00F739F1 /* UIColor+Brightness.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4387DC226972EB00F739F1 /* UIColor+Brightness.swift */; };
|
||||||
|
FC89B7E02325B07F00D007AB /* ChromaBrightnessSliderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC89B7DF2325B07F00D007AB /* ChromaBrightnessSliderTests.swift */; };
|
||||||
|
FC89B7E22325B8B900D007AB /* FakeTouch.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC89B7E12325B8B900D007AB /* FakeTouch.swift */; };
|
||||||
|
FC89B7E42325C24F00D007AB /* UIView+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC89B7E32325C24F00D007AB /* UIView+Utils.swift */; };
|
||||||
FCCA42A5226022A800BE2FF9 /* ColorWheelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A4226022A800BE2FF9 /* ColorWheelView.swift */; };
|
FCCA42A5226022A800BE2FF9 /* ColorWheelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A4226022A800BE2FF9 /* ColorWheelView.swift */; };
|
||||||
FCCA42A7226023F000BE2FF9 /* ChromaColorHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */; };
|
FCCA42A7226023F000BE2FF9 /* ChromaColorHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */; };
|
||||||
FCCA42AA2260329900BE2FF9 /* UIView+DropShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A92260329900BE2FF9 /* UIView+DropShadow.swift */; };
|
FCCA42AA2260329900BE2FF9 /* UIView+DropShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCCA42A92260329900BE2FF9 /* UIView+DropShadow.swift */; };
|
||||||
@ -30,7 +33,6 @@
|
|||||||
FCE07C01227B4C8B00920217 /* UIColor+TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */; };
|
FCE07C01227B4C8B00920217 /* UIColor+TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */; };
|
||||||
FCE07C04227B4DB900920217 /* UIView+DropShadowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C03227B4DB900920217 /* UIView+DropShadowTests.swift */; };
|
FCE07C04227B4DB900920217 /* UIView+DropShadowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C03227B4DB900920217 /* UIView+DropShadowTests.swift */; };
|
||||||
FCE07C06227B525000920217 /* ChromaControlStylableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */; };
|
FCE07C06227B525000920217 /* ChromaControlStylableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */; };
|
||||||
FCE07C08228A0F5C00920217 /* SliderTrackViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C07228A0F5C00920217 /* SliderTrackViewTests.swift */; };
|
|
||||||
FCE07C0A228A0F6800920217 /* SliderHandleViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */; };
|
FCE07C0A228A0F6800920217 /* SliderHandleViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */; };
|
||||||
FCE07C0C228A0F7500920217 /* ChromaColorHandleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */; };
|
FCE07C0C228A0F7500920217 /* ChromaColorHandleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */; };
|
||||||
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */; };
|
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */; };
|
||||||
@ -93,6 +95,9 @@
|
|||||||
FC4387CA22625DA800F739F1 /* SliderHandleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandleView.swift; sourceTree = "<group>"; };
|
FC4387CA22625DA800F739F1 /* SliderHandleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandleView.swift; sourceTree = "<group>"; };
|
||||||
FC4387CC2262B82600F739F1 /* ChromaControlStylable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaControlStylable.swift; sourceTree = "<group>"; };
|
FC4387CC2262B82600F739F1 /* ChromaControlStylable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaControlStylable.swift; sourceTree = "<group>"; };
|
||||||
FC4387DC226972EB00F739F1 /* UIColor+Brightness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Brightness.swift"; sourceTree = "<group>"; };
|
FC4387DC226972EB00F739F1 /* UIColor+Brightness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Brightness.swift"; sourceTree = "<group>"; };
|
||||||
|
FC89B7DF2325B07F00D007AB /* ChromaBrightnessSliderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaBrightnessSliderTests.swift; sourceTree = "<group>"; };
|
||||||
|
FC89B7E12325B8B900D007AB /* FakeTouch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeTouch.swift; sourceTree = "<group>"; };
|
||||||
|
FC89B7E32325C24F00D007AB /* UIView+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Utils.swift"; sourceTree = "<group>"; };
|
||||||
FCCA42A4226022A800BE2FF9 /* ColorWheelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorWheelView.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>"; };
|
FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorHandle.swift; sourceTree = "<group>"; };
|
||||||
FCCA42A92260329900BE2FF9 /* UIView+DropShadow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+DropShadow.swift"; sourceTree = "<group>"; };
|
FCCA42A92260329900BE2FF9 /* UIView+DropShadow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+DropShadow.swift"; sourceTree = "<group>"; };
|
||||||
@ -101,7 +106,6 @@
|
|||||||
FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+TestHelpers.swift"; sourceTree = "<group>"; };
|
FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+TestHelpers.swift"; sourceTree = "<group>"; };
|
||||||
FCE07C03227B4DB900920217 /* UIView+DropShadowTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+DropShadowTests.swift"; sourceTree = "<group>"; };
|
FCE07C03227B4DB900920217 /* UIView+DropShadowTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+DropShadowTests.swift"; sourceTree = "<group>"; };
|
||||||
FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaControlStylableTests.swift; sourceTree = "<group>"; };
|
FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaControlStylableTests.swift; sourceTree = "<group>"; };
|
||||||
FCE07C07228A0F5C00920217 /* SliderTrackViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderTrackViewTests.swift; sourceTree = "<group>"; };
|
|
||||||
FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandleViewTests.swift; sourceTree = "<group>"; };
|
FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderHandleViewTests.swift; sourceTree = "<group>"; };
|
||||||
FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorHandleTests.swift; sourceTree = "<group>"; };
|
FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorHandleTests.swift; sourceTree = "<group>"; };
|
||||||
FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorPicker.swift; sourceTree = "<group>"; };
|
FCEA4E262235AAA200C0A1B6 /* ChromaColorPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromaColorPicker.swift; sourceTree = "<group>"; };
|
||||||
@ -137,7 +141,7 @@
|
|||||||
3503B8301F2689BC00750356 /* Source */ = {
|
3503B8301F2689BC00750356 /* Source */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
FC4387C722625C5F00F739F1 /* Helpers */,
|
FC4387C722625C5F00F739F1 /* Supporting Views */,
|
||||||
FCCA42A82260325F00BE2FF9 /* Extensions */,
|
FCCA42A82260325F00BE2FF9 /* Extensions */,
|
||||||
3503B8311F2689BC00750356 /* ChromaColorPicker.h */,
|
3503B8311F2689BC00750356 /* ChromaColorPicker.h */,
|
||||||
3503B8321F2689BC00750356 /* Info.plist */,
|
3503B8321F2689BC00750356 /* Info.plist */,
|
||||||
@ -186,9 +190,10 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
FCE07BFF227B4C7A00920217 /* TestHelpers */,
|
FCE07BFF227B4C7A00920217 /* TestHelpers */,
|
||||||
FCE07C02227B4D9500920217 /* Helpers */,
|
FCE07C02227B4D9500920217 /* Supporting Views */,
|
||||||
FCCA42AD226038BD00BE2FF9 /* Extensions */,
|
FCCA42AD226038BD00BE2FF9 /* Extensions */,
|
||||||
FC1BD8BF2207D7B700817AF3 /* ChromaColorPickerTests.swift */,
|
FC1BD8BF2207D7B700817AF3 /* ChromaColorPickerTests.swift */,
|
||||||
|
FC89B7DF2325B07F00D007AB /* ChromaBrightnessSliderTests.swift */,
|
||||||
FCCA42AB226038A400BE2FF9 /* ColorWheelViewTests.swift */,
|
FCCA42AB226038A400BE2FF9 /* ColorWheelViewTests.swift */,
|
||||||
FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */,
|
FCE07C05227B525000920217 /* ChromaControlStylableTests.swift */,
|
||||||
FC1BD8C12207D7B700817AF3 /* Info.plist */,
|
FC1BD8C12207D7B700817AF3 /* Info.plist */,
|
||||||
@ -196,14 +201,14 @@
|
|||||||
path = Tests;
|
path = Tests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
FC4387C722625C5F00F739F1 /* Helpers */ = {
|
FC4387C722625C5F00F739F1 /* Supporting Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */,
|
FCCA42A6226023F000BE2FF9 /* ChromaColorHandle.swift */,
|
||||||
FC4387CA22625DA800F739F1 /* SliderHandleView.swift */,
|
FC4387CA22625DA800F739F1 /* SliderHandleView.swift */,
|
||||||
FC4387C822625C7000F739F1 /* SliderTrackView.swift */,
|
FC4387C822625C7000F739F1 /* SliderTrackView.swift */,
|
||||||
);
|
);
|
||||||
path = Helpers;
|
path = "Supporting Views";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
FCCA42A82260325F00BE2FF9 /* Extensions */ = {
|
FCCA42A82260325F00BE2FF9 /* Extensions */ = {
|
||||||
@ -211,6 +216,7 @@
|
|||||||
children = (
|
children = (
|
||||||
FC4387DC226972EB00F739F1 /* UIColor+Brightness.swift */,
|
FC4387DC226972EB00F739F1 /* UIColor+Brightness.swift */,
|
||||||
FCCA42A92260329900BE2FF9 /* UIView+DropShadow.swift */,
|
FCCA42A92260329900BE2FF9 /* UIView+DropShadow.swift */,
|
||||||
|
FC89B7E32325C24F00D007AB /* UIView+Utils.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -228,18 +234,18 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */,
|
FCE07C00227B4C8B00920217 /* UIColor+TestHelpers.swift */,
|
||||||
|
FC89B7E12325B8B900D007AB /* FakeTouch.swift */,
|
||||||
);
|
);
|
||||||
path = TestHelpers;
|
path = TestHelpers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
FCE07C02227B4D9500920217 /* Helpers */ = {
|
FCE07C02227B4D9500920217 /* Supporting Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */,
|
FCE07C0B228A0F7500920217 /* ChromaColorHandleTests.swift */,
|
||||||
FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */,
|
FCE07C09228A0F6800920217 /* SliderHandleViewTests.swift */,
|
||||||
FCE07C07228A0F5C00920217 /* SliderTrackViewTests.swift */,
|
|
||||||
);
|
);
|
||||||
path = Helpers;
|
path = "Supporting Views";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
@ -395,6 +401,7 @@
|
|||||||
files = (
|
files = (
|
||||||
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */,
|
FCEA4E272235AAA200C0A1B6 /* ChromaColorPicker.swift in Sources */,
|
||||||
FC4387CD2262B82600F739F1 /* ChromaControlStylable.swift in Sources */,
|
FC4387CD2262B82600F739F1 /* ChromaControlStylable.swift in Sources */,
|
||||||
|
FC89B7E42325C24F00D007AB /* UIView+Utils.swift in Sources */,
|
||||||
FCCA42AA2260329900BE2FF9 /* UIView+DropShadow.swift in Sources */,
|
FCCA42AA2260329900BE2FF9 /* UIView+DropShadow.swift in Sources */,
|
||||||
FC4387DE226974FD00F739F1 /* UIColor+Brightness.swift in Sources */,
|
FC4387DE226974FD00F739F1 /* UIColor+Brightness.swift in Sources */,
|
||||||
FC4387C62262556600F739F1 /* ChromaBrightnessSlider.swift in Sources */,
|
FC4387C62262556600F739F1 /* ChromaBrightnessSlider.swift in Sources */,
|
||||||
@ -419,11 +426,12 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
FCE07C06227B525000920217 /* ChromaControlStylableTests.swift in Sources */,
|
FCE07C06227B525000920217 /* ChromaControlStylableTests.swift in Sources */,
|
||||||
|
FC89B7E02325B07F00D007AB /* ChromaBrightnessSliderTests.swift in Sources */,
|
||||||
|
FC89B7E22325B8B900D007AB /* FakeTouch.swift in Sources */,
|
||||||
FCE07C0C228A0F7500920217 /* ChromaColorHandleTests.swift in Sources */,
|
FCE07C0C228A0F7500920217 /* ChromaColorHandleTests.swift in Sources */,
|
||||||
FC1BD8C02207D7B700817AF3 /* ChromaColorPickerTests.swift in Sources */,
|
FC1BD8C02207D7B700817AF3 /* ChromaColorPickerTests.swift in Sources */,
|
||||||
FCE07BFE227B4A8100920217 /* UIColor+BrightnessTests.swift in Sources */,
|
FCE07BFE227B4A8100920217 /* UIColor+BrightnessTests.swift in Sources */,
|
||||||
FCE07C0A228A0F6800920217 /* SliderHandleViewTests.swift in Sources */,
|
FCE07C0A228A0F6800920217 /* SliderHandleViewTests.swift in Sources */,
|
||||||
FCE07C08228A0F5C00920217 /* SliderTrackViewTests.swift in Sources */,
|
|
||||||
FC4387C422603AE900F739F1 /* ColorWheelViewTests.swift in Sources */,
|
FC4387C422603AE900F739F1 /* ColorWheelViewTests.swift in Sources */,
|
||||||
FCE07C01227B4C8B00920217 /* UIColor+TestHelpers.swift in Sources */,
|
FCE07C01227B4C8B00920217 /* UIColor+TestHelpers.swift in Sources */,
|
||||||
FCE07C04227B4DB900920217 /* UIView+DropShadowTests.swift in Sources */,
|
FCE07C04227B4DB900920217 /* UIView+DropShadowTests.swift in Sources */,
|
||||||
|
11
README.md
11
README.md
@ -78,17 +78,18 @@ addTarget(self, action: #selector(sliderDidValueChange(_:)), for: .valueChanged)
|
|||||||
_ChromaColorPicker_
|
_ChromaColorPicker_
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
| :-----------------:|:-------------|
|
| :-----------------:|:-------------|
|
||||||
| `.touchDown` | Called when a handle is first grabbed. |
|
| `.touchDown`(no) | Called when a handle is first grabbed. |
|
||||||
| `.touchUpInside` | Called when a handle is let go. |
|
| `.touchUpInside`(no) | Called when a handle is let go. |
|
||||||
| `.valueChanged` | Called whenever the color has changed. |
|
| `.valueChanged` | Called whenever the color has changed. |
|
||||||
| `.touchDragInside` | Called when a handle has moved via a drag action. |
|
| `.touchDragInside`(no) | Called when a handle has moved via a drag action. |
|
||||||
| `.editingDidEnd` | Called when either a handle is let go or slider is let go. |
|
| `.touchUpInside` | Called when a handle is released. |
|
||||||
|
|
||||||
_ChromaBrightnessSlider_
|
_ChromaBrightnessSlider_
|
||||||
| Event | Description |
|
| Event | Description |
|
||||||
| :-----------------:|:-------------|
|
| :-----------------:|:-------------|
|
||||||
|
| `.touchDown` | Called when a the slider is grabbed. |
|
||||||
| `.valueChanged` | Called whenever the slider is moved and the value has changed. |
|
| `.valueChanged` | Called whenever the slider is moved and the value has changed. |
|
||||||
| `.editingDidEnd` | Called when the slider handle is released. |
|
| `.touchUpInside` | Called when the slider handle is released. |
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
```Swift
|
```Swift
|
||||||
|
@ -29,15 +29,15 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
public let handle = SliderHandleView()
|
public let handle = SliderHandleView()
|
||||||
|
|
||||||
public var borderWidth: CGFloat = 4.0 {
|
public var borderWidth: CGFloat = 4.0 {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var borderColor: UIColor = .white {
|
public var borderColor: UIColor = .white {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var showsShadow: Bool = true {
|
public var showsShadow: Bool = true {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - Initialization
|
//MARK: - Initialization
|
||||||
@ -79,7 +79,11 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
|
|
||||||
public override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
|
public override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
|
||||||
let location = touch.location(in: self)
|
let location = touch.location(in: self)
|
||||||
return interactableBounds.contains(location)
|
let shouldBeginTracking = interactableBounds.contains(location)
|
||||||
|
if shouldBeginTracking {
|
||||||
|
sendActions(for: .touchDown)
|
||||||
|
}
|
||||||
|
return shouldBeginTracking
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
|
public override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
|
||||||
@ -87,13 +91,13 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
let clampedPositionX: CGFloat = max(0, min(location.x, confiningTrackFrame.width))
|
let clampedPositionX: CGFloat = max(0, min(location.x, confiningTrackFrame.width))
|
||||||
let value = clampedPositionX / confiningTrackFrame.width
|
let value = clampedPositionX / confiningTrackFrame.width
|
||||||
|
|
||||||
updateControl(to: value)
|
currentValue = value
|
||||||
sendActions(for: .valueChanged)
|
sendActions(for: .valueChanged)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
|
public override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
|
||||||
sendActions(for: .editingDidEnd)
|
sendActions(for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
public override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||||
@ -103,47 +107,6 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
return super.point(inside: point, with: event)
|
return super.point(inside: point, with: event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
|
||||||
internal let sliderTrackView = SliderTrackView()
|
|
||||||
|
|
||||||
/// The amount of padding caused by visual stylings
|
|
||||||
internal var horizontalPadding: CGFloat {
|
|
||||||
return sliderTrackView.layer.cornerRadius / 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
internal var confiningTrackFrame: CGRect {
|
|
||||||
return sliderTrackView.frame.insetBy(dx: horizontalPadding, dy: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal var interactableBounds: CGRect {
|
|
||||||
let horizontalOffset = -(handle.bounds.width / 2) + horizontalPadding
|
|
||||||
return bounds.insetBy(dx: horizontalOffset, dy: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func commonInit() {
|
|
||||||
backgroundColor = .clear
|
|
||||||
setupSliderTrackView()
|
|
||||||
setupSliderHandleView()
|
|
||||||
updateTrackColor(to: trackColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func setupSliderTrackView() {
|
|
||||||
sliderTrackView.isUserInteractionEnabled = false
|
|
||||||
sliderTrackView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
addSubview(sliderTrackView)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
sliderTrackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
||||||
sliderTrackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
||||||
sliderTrackView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.75),
|
|
||||||
sliderTrackView.centerYAnchor.constraint(equalTo: centerYAnchor),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func setupSliderHandleView() {
|
|
||||||
handle.isUserInteractionEnabled = false
|
|
||||||
addSubview(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func updateShadowIfNeeded() {
|
internal func updateShadowIfNeeded() {
|
||||||
let views = [handle, sliderTrackView]
|
let views = [handle, sliderTrackView]
|
||||||
|
|
||||||
@ -155,7 +118,48 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func updateControl(to value: CGFloat) {
|
// MARK: - Private
|
||||||
|
private let sliderTrackView = SliderTrackView()
|
||||||
|
|
||||||
|
/// The amount of padding caused by visual stylings
|
||||||
|
private var horizontalPadding: CGFloat {
|
||||||
|
return sliderTrackView.layer.cornerRadius / 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
private var confiningTrackFrame: CGRect {
|
||||||
|
return sliderTrackView.frame.insetBy(dx: horizontalPadding, dy: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var interactableBounds: CGRect {
|
||||||
|
let horizontalOffset = -(handle.bounds.width / 2) + horizontalPadding
|
||||||
|
return bounds.insetBy(dx: horizontalOffset, dy: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func commonInit() {
|
||||||
|
backgroundColor = .clear
|
||||||
|
setupSliderTrackView()
|
||||||
|
setupSliderHandleView()
|
||||||
|
updateTrackColor(to: trackColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupSliderTrackView() {
|
||||||
|
sliderTrackView.isUserInteractionEnabled = false
|
||||||
|
sliderTrackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
addSubview(sliderTrackView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
sliderTrackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
|
sliderTrackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
|
sliderTrackView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.75),
|
||||||
|
sliderTrackView.centerYAnchor.constraint(equalTo: centerYAnchor),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupSliderHandleView() {
|
||||||
|
handle.isUserInteractionEnabled = false
|
||||||
|
addSubview(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateControl(to value: CGFloat) {
|
||||||
let brightness = 1 - max(0, min(1, value))
|
let brightness = 1 - max(0, min(1, value))
|
||||||
var hue: CGFloat = 0
|
var hue: CGFloat = 0
|
||||||
var saturation: CGFloat = 0
|
var saturation: CGFloat = 0
|
||||||
@ -171,7 +175,7 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
moveHandle(to: value)
|
moveHandle(to: value)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func updateTrackColor(to color: UIColor) {
|
private func updateTrackColor(to color: UIColor) {
|
||||||
var hue: CGFloat = 0
|
var hue: CGFloat = 0
|
||||||
var saturation: CGFloat = 0
|
var saturation: CGFloat = 0
|
||||||
var brightness: CGFloat = 0
|
var brightness: CGFloat = 0
|
||||||
@ -183,14 +187,14 @@ public class ChromaBrightnessSlider: UIControl, ChromaControlStylable {
|
|||||||
currentValue = 1 - brightness
|
currentValue = 1 - brightness
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func updateTrackViewGradient(for color: UIColor) {
|
private func updateTrackViewGradient(for color: UIColor) {
|
||||||
CATransaction.begin()
|
CATransaction.begin()
|
||||||
CATransaction.setDisableActions(true)
|
CATransaction.setDisableActions(true)
|
||||||
sliderTrackView.gradientValues = (color, .black)
|
sliderTrackView.gradientValues = (color, .black)
|
||||||
CATransaction.commit()
|
CATransaction.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func moveHandle(to value: CGFloat) {
|
private func moveHandle(to value: CGFloat) {
|
||||||
let clampedValue = max(0, min(1, value))
|
let clampedValue = max(0, min(1, value))
|
||||||
let xPos = (clampedValue * confiningTrackFrame.width) + horizontalPadding
|
let xPos = (clampedValue * confiningTrackFrame.width) + horizontalPadding
|
||||||
let size = CGSize(width: bounds.height * 1.15, height: bounds.height)
|
let size = CGSize(width: bounds.height * 1.15, height: bounds.height)
|
||||||
|
@ -21,15 +21,15 @@ public class ChromaColorPicker: UIControl, ChromaControlStylable {
|
|||||||
public weak var delegate: ChromaColorPickerDelegate?
|
public weak var delegate: ChromaColorPickerDelegate?
|
||||||
|
|
||||||
@IBInspectable public var borderWidth: CGFloat = 6.0 {
|
@IBInspectable public var borderWidth: CGFloat = 6.0 {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBInspectable public var borderColor: UIColor = .white {
|
@IBInspectable public var borderColor: UIColor = .white {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBInspectable public var showsShadow: Bool = true {
|
@IBInspectable public var showsShadow: Bool = true {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A brightness slider attached via the `connect(_:)` method.
|
/// A brightness slider attached via the `connect(_:)` method.
|
||||||
@ -41,7 +41,7 @@ public class ChromaColorPicker: UIControl, ChromaControlStylable {
|
|||||||
|
|
||||||
/// The size handles should be displayed at.
|
/// The size handles should be displayed at.
|
||||||
public var handleSize: CGSize = defaultHandleSize {
|
public var handleSize: CGSize = defaultHandleSize {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An extension to handles' hitboxes in the +Y direction.
|
/// An extension to handles' hitboxes in the +Y direction.
|
||||||
@ -156,7 +156,7 @@ public class ChromaColorPicker: UIControl, ChromaControlStylable {
|
|||||||
if let handle = currentHandle {
|
if let handle = currentHandle {
|
||||||
animateHandleScale(handle, shouldGrow: false)
|
animateHandleScale(handle, shouldGrow: false)
|
||||||
}
|
}
|
||||||
sendActions(for: .editingDidEnd)
|
sendActions(for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
@ -60,6 +60,7 @@ public class ColorWheelView: UIView {
|
|||||||
Returns the color on the wheel on a given point relative to the view. nil is returned if
|
Returns the color on the wheel on a given point relative to the view. nil is returned if
|
||||||
the point does not exist within the bounds of the color wheel.
|
the point does not exist within the bounds of the color wheel.
|
||||||
*/
|
*/
|
||||||
|
// TODO: replace this function with a mathmatically based one in ChromaColorPicker
|
||||||
public func pixelColor(at point: CGPoint) -> UIColor? {
|
public func pixelColor(at point: CGPoint) -> UIColor? {
|
||||||
guard pointIsInColorWheel(point) else { return nil }
|
guard pointIsInColorWheel(point) else { return nil }
|
||||||
|
|
||||||
|
18
Source/Extensions/UIView+Utils.swift
Normal file
18
Source/Extensions/UIView+Utils.swift
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// UIView+Utils.swift
|
||||||
|
// ChromaColorPicker
|
||||||
|
//
|
||||||
|
// Created by Jon Cardasis on 9/8/19.
|
||||||
|
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
internal extension UIView {
|
||||||
|
|
||||||
|
/// Forces the view to layout synchronously and immediately
|
||||||
|
func layoutNow() {
|
||||||
|
setNeedsLayout()
|
||||||
|
layoutIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@ public class ChromaColorHandle: UIView, ChromaControlStylable {
|
|||||||
|
|
||||||
/// Current selected color of the handle.
|
/// Current selected color of the handle.
|
||||||
public var color: UIColor = .black {
|
public var color: UIColor = .black {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An image to display in the handle. Updates `accessoryView` to be a UIImageView.
|
/// An image to display in the handle. Updates `accessoryView` to be a UIImageView.
|
||||||
@ -36,19 +36,19 @@ public class ChromaColorHandle: UIView, ChromaControlStylable {
|
|||||||
|
|
||||||
/// The amount an accessory view's frame should be inset by.
|
/// The amount an accessory view's frame should be inset by.
|
||||||
public var accessoryViewEdgeInsets: UIEdgeInsets = .zero {
|
public var accessoryViewEdgeInsets: UIEdgeInsets = .zero {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var borderWidth: CGFloat = 3.0 {
|
public var borderWidth: CGFloat = 3.0 {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var borderColor: UIColor = .white {
|
public var borderColor: UIColor = .white {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var showsShadow: Bool = true {
|
public var showsShadow: Bool = true {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Initialization
|
// MARK: - Initialization
|
@ -15,11 +15,11 @@ public class SliderHandleView: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var borderWidth: CGFloat = 3.0 {
|
public var borderWidth: CGFloat = 3.0 {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
public var borderColor: UIColor = .white {
|
public var borderColor: UIColor = .white {
|
||||||
didSet { layoutIfNeeded() }
|
didSet { layoutNow() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override public init(frame: CGRect) {
|
override public init(frame: CGRect) {
|
||||||
@ -41,24 +41,18 @@ public class SliderHandleView: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
internal let handleLayer = CAShapeLayer()
|
private let handleLayer = CAShapeLayer()
|
||||||
|
|
||||||
internal struct CornerPoint {
|
private func commonInit() {
|
||||||
let center: CGPoint
|
|
||||||
let startAngle: CGFloat
|
|
||||||
let endAngle: CGFloat
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func commonInit() {
|
|
||||||
layer.addSublayer(handleLayer)
|
layer.addSublayer(handleLayer)
|
||||||
updateHandleColor(to: handleColor)
|
updateHandleColor(to: handleColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func updateHandleColor(to color: UIColor) {
|
private func updateHandleColor(to color: UIColor) {
|
||||||
handleLayer.fillColor = color.cgColor
|
handleLayer.fillColor = color.cgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func makeRoundedTrianglePath(width: CGFloat, height: CGFloat, radius: CGFloat) -> CGPath {
|
private func makeRoundedTrianglePath(width: CGFloat, height: CGFloat, radius: CGFloat) -> CGPath {
|
||||||
let point1 = CGPoint(x: -width / 2, y: height / 2)
|
let point1 = CGPoint(x: -width / 2, y: height / 2)
|
||||||
let point2 = CGPoint(x: 0, y: -height / 2)
|
let point2 = CGPoint(x: 0, y: -height / 2)
|
||||||
let point3 = CGPoint(x: width / 2, y: height / 2)
|
let point3 = CGPoint(x: width / 2, y: height / 2)
|
251
Tests/ChromaBrightnessSliderTests.swift
Normal file
251
Tests/ChromaBrightnessSliderTests.swift
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
//
|
||||||
|
// ChromaBrightnessSliderTests.swift
|
||||||
|
// ChromaColorPickerTests
|
||||||
|
//
|
||||||
|
// Created by Jon Cardasis on 9/8/19.
|
||||||
|
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import ChromaColorPicker
|
||||||
|
|
||||||
|
class ChromaBrightnessSliderTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
func testCurrentColorShouldReturnBlueWhenTrackColorIsBlueAndCurrentValueIsZero() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let expectedColor: UIColor = .blue
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.trackColor = .blue
|
||||||
|
subject.currentValue = 0.0
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(subject.currentColor, expectedColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCurrentColorShouldReturnBlackWhenTrackColorIsAnyAndCurrentValueIsOne() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let expectedColor: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.trackColor = .blue
|
||||||
|
subject.currentValue = 1.0
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(subject.currentColor, expectedColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBorderWidthShouldUpdateSliderTrack() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let sliderTrack = subject.test_sliderTrackView
|
||||||
|
let expectedBorderWidth: CGFloat = 11
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.borderWidth = expectedBorderWidth
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(sliderTrack.layer.borderWidth, expectedBorderWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBorderColorShouldUpdateSliderTrack() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let sliderTrack = subject.test_sliderTrackView
|
||||||
|
let expectedBorderColor: UIColor = .green
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.borderColor = expectedBorderColor
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(sliderTrack.layer.borderColor!, expectedBorderColor.cgColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Layout
|
||||||
|
|
||||||
|
func testShadowsAreRenderedOnBothHandleAndTrackView() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let sliderTrack = subject.test_sliderTrackView
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.showsShadow = true
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertGreaterThan(sliderTrack.layer.shadowOpacity, 0)
|
||||||
|
XCTAssertGreaterThan(subject.handle.layer.shadowOpacity, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testShadowsAreRemovedFromHandleAndTrackView() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let sliderTrack = subject.test_sliderTrackView
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.showsShadow = false
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(sliderTrack.layer.shadowOpacity, 0)
|
||||||
|
XCTAssertEqual(subject.handle.layer.shadowOpacity, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Convenience Functions
|
||||||
|
|
||||||
|
func testConnectCallsConnectFunctionOfColorPicker() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
let colorPicker = FakeColorPicker()
|
||||||
|
|
||||||
|
// When
|
||||||
|
subject.connect(to: colorPicker)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertTrue(colorPicker.didCallConnect)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testValueShouldReturn1WhenBrightnessIs0() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
|
||||||
|
// When
|
||||||
|
let value = subject.value(brightness: 0)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(value, 1, accuracy: 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testValueShouldReturn0WhenBrightnessIs1() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
|
||||||
|
// When
|
||||||
|
let value = subject.value(brightness: 1)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(value, 0, accuracy: 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testValueShouldReturn0WhenBrightnessIsLargerThan1() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
|
||||||
|
// When
|
||||||
|
let value = subject.value(brightness: 100)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(value, 0, accuracy: 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testValueShouldReturn1WhenBrightnessIsLessThan0() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
|
||||||
|
// When
|
||||||
|
let value = subject.value(brightness: -100)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(value, 1, accuracy: 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testValueShouldReturn0_25WhenBrightnessIs0_75() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider()
|
||||||
|
|
||||||
|
// When
|
||||||
|
let value = subject.value(brightness: 0.75)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertEqual(value, 0.25, accuracy: 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Control
|
||||||
|
|
||||||
|
func testBeginTrackingSendsTouchDownActionWhenTouchIsInBounds() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider(frame: CGRect(x: 0, y: 0, width: 300, height: 30))
|
||||||
|
subject.layoutIfNeeded()
|
||||||
|
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.bounds.midX,
|
||||||
|
y: subject.bounds.midY))
|
||||||
|
let eventReceiver = FakeEventReceiver(listensFor: .touchDown)
|
||||||
|
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent(_:)), for: .touchDown)
|
||||||
|
|
||||||
|
var eventDidTrigger = false
|
||||||
|
eventReceiver.eventCaught = {
|
||||||
|
eventDidTrigger = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// When
|
||||||
|
let shouldTrack = subject.beginTracking(fakeTouch, with: nil)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertTrue(eventDidTrigger)
|
||||||
|
XCTAssertTrue(shouldTrack)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBeginTrackingDoesNotSendTouchDownActionWhenTouchIsOutOfBounds() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider(frame: CGRect(x: 0, y: 0, width: 300, height: 30))
|
||||||
|
subject.layoutIfNeeded()
|
||||||
|
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: -100, y: subject.bounds.midY))
|
||||||
|
let eventReceiver = FakeEventReceiver(listensFor: .touchDown)
|
||||||
|
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent(_:)), for: .touchDown)
|
||||||
|
|
||||||
|
var eventDidTrigger = false
|
||||||
|
eventReceiver.eventCaught = {
|
||||||
|
eventDidTrigger = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// When
|
||||||
|
let shouldTrack = subject.beginTracking(fakeTouch, with: nil)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertFalse(eventDidTrigger)
|
||||||
|
XCTAssertFalse(shouldTrack)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testContinueTrackingSendsValueChangedActionAndHasClampedValue() {
|
||||||
|
// Given
|
||||||
|
let subject = ChromaBrightnessSlider(frame: CGRect(x: 0, y: 0, width: 300, height: 30))
|
||||||
|
subject.layoutIfNeeded()
|
||||||
|
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.bounds.width + 100, y: subject.bounds.midY))
|
||||||
|
let eventReceiver = FakeEventReceiver(listensFor: .valueChanged)
|
||||||
|
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent(_:)), for: .valueChanged)
|
||||||
|
|
||||||
|
var eventDidTrigger = false
|
||||||
|
var value: CGFloat?
|
||||||
|
eventReceiver.eventCaught = {
|
||||||
|
eventDidTrigger = true
|
||||||
|
value = subject.currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// When
|
||||||
|
let _ = subject.continueTracking(fakeTouch, with: nil)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
XCTAssertTrue(eventDidTrigger)
|
||||||
|
XCTAssertEqual(value, 1.0, "ChromaBrightnessSlider did not clamp value when touch is out of bounds")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEndTrackingSendsTouchUpInsideAction() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate extension ChromaBrightnessSlider {
|
||||||
|
var test_sliderTrackView: SliderTrackView {
|
||||||
|
return subviews.first(where: { $0 is SliderTrackView }) as! SliderTrackView
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fileprivate class FakeColorPicker: ChromaColorPicker {
|
||||||
|
var didCallConnect: Bool = false
|
||||||
|
|
||||||
|
override func connect(_ slider: ChromaBrightnessSlider) {
|
||||||
|
didCallConnect = true
|
||||||
|
}
|
||||||
|
}
|
@ -153,52 +153,42 @@ class ChromaColorPickerTests: XCTestCase {
|
|||||||
setCurrentHandle(to: makeFakeHandle())
|
setCurrentHandle(to: makeFakeHandle())
|
||||||
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.colorWheelView.bounds.midX,
|
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.colorWheelView.bounds.midX,
|
||||||
y: subject.colorWheelView.bounds.midY))
|
y: subject.colorWheelView.bounds.midY))
|
||||||
let eventReceiver = FakeEventReceiver()
|
let eventReceiver = FakeEventReceiver(listensFor: .valueChanged)
|
||||||
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent), for: .valueChanged)
|
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent), for: .valueChanged)
|
||||||
|
|
||||||
let expectation = XCTestExpectation(description: "event fired")
|
var eventDidTrigger = false
|
||||||
|
eventReceiver.eventCaught = {
|
||||||
eventReceiver.eventCaught = { event in
|
eventDidTrigger = true
|
||||||
if event == .valueChanged {
|
|
||||||
expectation.fulfill()
|
|
||||||
} else {
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When
|
// When
|
||||||
let _ = subject.continueTracking(fakeTouch, with: nil)
|
let _ = subject.continueTracking(fakeTouch, with: nil)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
wait(for: [expectation], timeout: 0.05)
|
XCTAssertTrue(eventDidTrigger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func testEndTrackingSendsEditingDidEndAction() {
|
func testEndTrackingSendsTouchUpInsideAction() {
|
||||||
subject.colorWheelView.layoutIfNeeded()
|
subject.colorWheelView.layoutIfNeeded()
|
||||||
|
|
||||||
// Given
|
// Given
|
||||||
setCurrentHandle(to: makeFakeHandle())
|
setCurrentHandle(to: makeFakeHandle())
|
||||||
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.colorWheelView.bounds.midX,
|
let fakeTouch = FakeUITouch(locationInParent: CGPoint(x: subject.colorWheelView.bounds.midX,
|
||||||
y: subject.colorWheelView.bounds.midY))
|
y: subject.colorWheelView.bounds.midY))
|
||||||
let eventReceiver = FakeEventReceiver()
|
let eventReceiver = FakeEventReceiver(listensFor: .touchUpInside)
|
||||||
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent), for: .editingDidEnd)
|
subject.addTarget(eventReceiver, action: #selector(FakeEventReceiver.catchEvent), for: .touchUpInside)
|
||||||
|
|
||||||
let expectation = XCTestExpectation(description: "event fired")
|
var eventDidTrigger = false
|
||||||
|
eventReceiver.eventCaught = {
|
||||||
eventReceiver.eventCaught = { event in
|
eventDidTrigger = true
|
||||||
if event == .valueChanged {
|
|
||||||
expectation.fulfill()
|
|
||||||
} else {
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When
|
// When
|
||||||
let _ = subject.endTracking(fakeTouch, with: nil)
|
let _ = subject.endTracking(fakeTouch, with: nil)
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
wait(for: [expectation], timeout: 0.05)
|
XCTAssertTrue(eventDidTrigger)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,25 +206,3 @@ extension ChromaColorPickerTests {
|
|||||||
let _ = subject.beginTracking(fakeTouch, with: nil)
|
let _ = subject.beginTracking(fakeTouch, with: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class FakeUITouch: UITouch {
|
|
||||||
|
|
||||||
let locationInParent: CGPoint
|
|
||||||
|
|
||||||
init(locationInParent: CGPoint) {
|
|
||||||
self.locationInParent = locationInParent
|
|
||||||
}
|
|
||||||
|
|
||||||
override func location(in view: UIView?) -> CGPoint {
|
|
||||||
return locationInParent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FakeEventReceiver: NSObject {
|
|
||||||
var eventCaught: ((UIControl.Event) -> ())?
|
|
||||||
|
|
||||||
@objc func catchEvent() {
|
|
||||||
eventCaught?(.valueChanged)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
//
|
|
||||||
// SliderTrackViewTests.swift
|
|
||||||
// ChromaColorPickerTests
|
|
||||||
//
|
|
||||||
// Created by Jon Cardasis on 5/13/19.
|
|
||||||
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
@ -30,7 +30,6 @@ class SliderHandleViewTests: XCTestCase {
|
|||||||
let layer = handleLayer(for: subject)
|
let layer = handleLayer(for: subject)
|
||||||
let expectedColor: UIColor = .purple
|
let expectedColor: UIColor = .purple
|
||||||
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
subject.borderColor = expectedColor
|
subject.borderColor = expectedColor
|
||||||
|
|
37
Tests/TestHelpers/FakeTouch.swift
Normal file
37
Tests/TestHelpers/FakeTouch.swift
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// FakeTouch.swift
|
||||||
|
// ChromaColorPickerTests
|
||||||
|
//
|
||||||
|
// Created by Jon Cardasis on 9/8/19.
|
||||||
|
// Copyright © 2019 Jonathan Cardasis. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class FakeUITouch: UITouch {
|
||||||
|
|
||||||
|
let locationInParent: CGPoint
|
||||||
|
|
||||||
|
init(locationInParent: CGPoint) {
|
||||||
|
self.locationInParent = locationInParent
|
||||||
|
}
|
||||||
|
|
||||||
|
override func location(in view: UIView?) -> CGPoint {
|
||||||
|
return locationInParent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeEventReceiver: NSObject {
|
||||||
|
var eventCaught: (() -> ())?
|
||||||
|
let event: UIControl.Event
|
||||||
|
|
||||||
|
init(listensFor event: UIControl.Event) {
|
||||||
|
self.event = event
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func catchEvent(_ sender: UIControl) {
|
||||||
|
if sender.allControlEvents.contains(event) {
|
||||||
|
eventCaught?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user