-
Notifications
You must be signed in to change notification settings - Fork 52
/
AdjustedHitBoxColorControl.swift
84 lines (74 loc) · 4.05 KB
/
AdjustedHitBoxColorControl.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//
// AdjustedHitBoxColorControl.swift
// FlexColorPicker
//
// Created by Rastislav Mirek on 6/6/18.
//
// MIT License
// Copyright (c) 2018 Rastislav Mirek
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import UIKit
let defaultHitBoxInset: CGFloat = 16
public let colorControlWithThumbViewDefaultHitBoxInsets = UIEdgeInsets(top: defaultHitBoxInset, left: defaultHitBoxInset, bottom: defaultHitBoxInset, right: defaultHitBoxInset)
/// Color control with frame (and hit box) extended beyond its alignment rectangle.
///
/// It is generally recomeneded to subclass this class rather than `AbstractColorControl` when creating custom color controls to have better control over your control's hit box.
///
/// Any subvies must be added to `contentView` only for this to work correctly inside `UIScrollView` and iOS 13 modal view controllers.
///
/// If you directly subclass this rather than `ColorPaletteControl` or `ColorSliderControl` override `gestureRecognizerShouldBegin(:)` to ensure that your custom color control works correctly inside `UIScrollView` and iOS 13 modal view controllers (that can be dragged to down to dismiss). Default implementation of the method disables any `UIPanGestureRecognizer`. E.g. you might want to allow some pan directions.
///
/// - Important: The disproportion between the `AdjustedHitBoxColorControl`'s frame (and bounds) and its alignment rectangle means that when aligning it using autolayout the frame might extend behond rectangle specified by layout constraits. When using lautolayout mind that the frame might therefore overlap other views.
///
/// See README for more information on subclassing.
open class AdjustedHitBoxColorControl: AbstractColorControl {
/// The alighnment rectangle of the color control in its own coordinate system.
public var contentBounds: CGRect {
layoutIfNeeded()
return contentView.frame
}
/// A single hit box inset value for all inset directions (top, bottom, left, right) meant to only be used from interface builder.
/// - Important: Do **not** use this property from code. Use hitBoxInset**s** property instead.
@IBInspectable
public var hitBoxInset: CGFloat {
get {
return (hitBoxInsets.bottom + hitBoxInsets.left + hitBoxInsets.top + hitBoxInsets.right) / 4
}
set {
hitBoxInsets = UIEdgeInsets(top: newValue, left: newValue, bottom: newValue, right: newValue)
}
}
/// Insets of the alignment rectangle relative to frame (frame is also hit box rectangle).
///
/// Applying this insets to `frame` results in alignment rectangle.
public var hitBoxInsets = colorControlWithThumbViewDefaultHitBoxInsets {
didSet {
setNeedsLayout()
}
}
open override var alignmentRectInsets: UIEdgeInsets {
return hitBoxInsets
}
override func locationForTouches(_ touches: Set<UITouch>) -> CGPoint? {
guard let location = super.locationForTouches(touches) else {
return nil
}
return convert(location, to: contentView)
}
}