Skip to content

Commit 587b8c5

Browse files
Internalise dependencies
1 parent 6606775 commit 587b8c5

File tree

8 files changed

+254
-9
lines changed

8 files changed

+254
-9
lines changed

.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>SchemeUserState</key>
6+
<dict>
7+
<key>MultiSlider.xcscheme_^#shared#^_</key>
8+
<dict>
9+
<key>orderHint</key>
10+
<integer>0</integer>
11+
</dict>
12+
</dict>
13+
<key>SuppressBuildableAutocreation</key>
14+
<dict>
15+
<key>MultiSlider</key>
16+
<dict>
17+
<key>primary</key>
18+
<true/>
19+
</dict>
20+
</dict>
21+
</dict>
22+
</plist>

Package.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,14 @@ import PackageDescription
55
let package = Package(
66
name: "MultiSlider",
77
platforms: [
8-
.iOS(.v9),
8+
.iOS(.v13),
99
],
1010
products: [
1111
.library(name: "MultiSlider", targets: ["MultiSlider"]),
1212
],
13-
dependencies: [
14-
.package(url: "https://github.com/yonat/SweeterSwift", from: "1.0.2"),
15-
.package(url: "https://github.com/yonat/AvailableHapticFeedback", from: "1.0.2"),
16-
],
13+
dependencies: [],
1714
targets: [
18-
.target(name: "MultiSlider", dependencies: ["SweeterSwift", "AvailableHapticFeedback"], path: "Sources"),
15+
.target(name: "MultiSlider", dependencies: [], path: "Sources"),
1916
],
2017
swiftLanguageVersions: [.v5]
2118
)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//
2+
// AvailableHapticFeedback.swift
3+
//
4+
// Created by Yonat Sharon on 25.10.2018.
5+
//
6+
7+
import UIKit
8+
9+
/// Wrapper for UIFeedbackGenerator that compiles on iOS 9
10+
open class AvailableHapticFeedback {
11+
public enum Style: CaseIterable {
12+
case selection
13+
case impactLight, impactMedium, impactHeavy
14+
case notificationSuccess, notificationWarning, notificationError
15+
}
16+
17+
public let style: Style
18+
19+
public init(style: Style = .selection) {
20+
self.style = style
21+
}
22+
23+
open func prepare() {
24+
if #available(iOS 10.0, *) {
25+
feedbackGenerator.prepare()
26+
}
27+
}
28+
29+
open func generateFeedback() {
30+
if #available(iOS 10.0, *) {
31+
feedbackGenerator.generate(style: style)
32+
}
33+
}
34+
35+
open func end() {
36+
_anyFeedbackGenerator = nil
37+
}
38+
39+
@available(iOS 10.0, *)
40+
var feedbackGenerator: UIFeedbackGenerator & AvailableHapticFeedbackGenerator {
41+
if nil == _anyFeedbackGenerator {
42+
createFeedbackGenerator()
43+
}
44+
// swiftlint:disable force_cast force_unwrapping
45+
return _anyFeedbackGenerator! as! UIFeedbackGenerator & AvailableHapticFeedbackGenerator
46+
// swiftlint:enable force_cast force_unwrapping
47+
}
48+
49+
private var _anyFeedbackGenerator: Any?
50+
51+
@available(iOS 10.0, *)
52+
private func createFeedbackGenerator() {
53+
switch style {
54+
case .selection:
55+
_anyFeedbackGenerator = UISelectionFeedbackGenerator()
56+
case .impactLight:
57+
_anyFeedbackGenerator = UIImpactFeedbackGenerator(style: .light)
58+
case .impactMedium:
59+
_anyFeedbackGenerator = UIImpactFeedbackGenerator(style: .medium)
60+
case .impactHeavy:
61+
_anyFeedbackGenerator = UIImpactFeedbackGenerator(style: .heavy)
62+
case .notificationSuccess, .notificationWarning, .notificationError:
63+
_anyFeedbackGenerator = UINotificationFeedbackGenerator()
64+
}
65+
}
66+
}
67+
68+
protocol AvailableHapticFeedbackGenerator {
69+
func generate(style: AvailableHapticFeedback.Style)
70+
}
71+
72+
@available(iOS 10.0, *)
73+
extension UISelectionFeedbackGenerator: AvailableHapticFeedbackGenerator {
74+
func generate(style: AvailableHapticFeedback.Style) {
75+
selectionChanged()
76+
}
77+
}
78+
79+
@available(iOS 10.0, *)
80+
extension UIImpactFeedbackGenerator: AvailableHapticFeedbackGenerator {
81+
func generate(style: AvailableHapticFeedback.Style) {
82+
impactOccurred()
83+
}
84+
}
85+
86+
@available(iOS 10.0, *)
87+
extension UINotificationFeedbackGenerator: AvailableHapticFeedbackGenerator {
88+
func generate(style: AvailableHapticFeedback.Style) {
89+
let notificationFeedbackType: UINotificationFeedbackGenerator.FeedbackType
90+
switch style {
91+
case .notificationWarning:
92+
notificationFeedbackType = .warning
93+
case .notificationError:
94+
notificationFeedbackType = .error
95+
default:
96+
notificationFeedbackType = .success
97+
}
98+
notificationOccurred(notificationFeedbackType)
99+
}
100+
}

Sources/MultiSlider.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
// Copyright © 2016 Yonat Sharon. All rights reserved.
77
//
88

9-
import AvailableHapticFeedback
10-
import SweeterSwift
119
import UIKit
1210

1311
@IBDesignable

Sources/MultiSliderExtensions.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// Created by Yonat Sharon on 20.05.2018.
66
//
77

8-
import SweeterSwift
98
import UIKit
109

1110
extension CGFloat {
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//
2+
// UIView+Sweeter.swift
3+
//
4+
// Created by Yonat Sharon on 2019-02-08.
5+
//
6+
7+
import UIKit
8+
9+
public extension UIView {
10+
/// Sweeter: Set constant attribute. Example: `constrain(.width, to: 17)`
11+
@discardableResult func constrain(
12+
_ at: NSLayoutConstraint.Attribute,
13+
to: CGFloat = 0,
14+
ratio: CGFloat = 1,
15+
relation: NSLayoutConstraint.Relation = .equal,
16+
priority: UILayoutPriority = .required,
17+
identifier: String? = nil
18+
) -> NSLayoutConstraint {
19+
let constraint = NSLayoutConstraint(
20+
item: self, attribute: at, relatedBy: relation,
21+
toItem: nil, attribute: .notAnAttribute, multiplier: ratio, constant: to
22+
)
23+
constraint.priority = priority
24+
constraint.identifier = identifier
25+
addConstraintWithoutConflict(constraint)
26+
return constraint
27+
}
28+
29+
/// Sweeter: Pin subview at a specific place. Example: `constrain(label, at: .top)`
30+
@discardableResult func constrain(
31+
_ subview: UIView,
32+
at: NSLayoutConstraint.Attribute,
33+
diff: CGFloat = 0,
34+
ratio: CGFloat = 1,
35+
relation: NSLayoutConstraint.Relation = .equal,
36+
priority: UILayoutPriority = .required,
37+
identifier: String? = nil
38+
) -> NSLayoutConstraint {
39+
let constraint = NSLayoutConstraint(
40+
item: subview, attribute: at, relatedBy: relation,
41+
toItem: self, attribute: at, multiplier: ratio, constant: diff
42+
)
43+
constraint.priority = priority
44+
constraint.identifier = identifier
45+
addConstraintWithoutConflict(constraint)
46+
return constraint
47+
}
48+
49+
/// Sweeter: Pin two subviews to each other. Example:
50+
///
51+
/// `constrain(label, at: .leading, to: textField)`
52+
///
53+
/// `constrain(textField, at: .top, to: label, at: .bottom, diff: 8)`
54+
@discardableResult func constrain(
55+
_ subview: UIView,
56+
at: NSLayoutConstraint.Attribute,
57+
to subview2: UIView,
58+
at at2: NSLayoutConstraint.Attribute = .notAnAttribute,
59+
diff: CGFloat = 0,
60+
ratio: CGFloat = 1,
61+
relation: NSLayoutConstraint.Relation = .equal,
62+
priority: UILayoutPriority = .required,
63+
identifier: String? = nil
64+
) -> NSLayoutConstraint {
65+
let at2real = at2 == .notAnAttribute ? at : at2
66+
let constraint = NSLayoutConstraint(
67+
item: subview, attribute: at, relatedBy: relation,
68+
toItem: subview2, attribute: at2real, multiplier: ratio, constant: diff
69+
)
70+
constraint.priority = priority
71+
constraint.identifier = identifier
72+
addConstraintWithoutConflict(constraint)
73+
return constraint
74+
}
75+
76+
/// Sweeter: Add subview pinned to specific places. Example: `addConstrainedSubview(button, constrain: .centerX, .centerY)`
77+
@discardableResult func addConstrainedSubview(_ subview: UIView, constrain: NSLayoutConstraint.Attribute...) -> [NSLayoutConstraint] {
78+
return addConstrainedSubview(subview, constrainedAttributes: constrain)
79+
}
80+
81+
@discardableResult internal func addConstrainedSubview(_ subview: UIView, constrainedAttributes: [NSLayoutConstraint.Attribute]) -> [NSLayoutConstraint] {
82+
subview.translatesAutoresizingMaskIntoConstraints = false
83+
addSubview(subview)
84+
return constrainedAttributes.map { self.constrain(subview, at: $0) }
85+
}
86+
87+
internal func addConstraintWithoutConflict(_ constraint: NSLayoutConstraint) {
88+
removeConstraints(constraints.filter {
89+
constraint.firstItem === $0.firstItem
90+
&& constraint.secondItem === $0.secondItem
91+
&& constraint.firstAttribute == $0.firstAttribute
92+
&& constraint.secondAttribute == $0.secondAttribute
93+
})
94+
addConstraint(constraint)
95+
}
96+
97+
/// Sweeter: Search the view hierarchy recursively for a subview that conforms to `predicate`
98+
func viewInHierarchy(frontFirst: Bool = true, where predicate: (UIView) -> Bool) -> UIView? {
99+
if predicate(self) { return self }
100+
let views = frontFirst ? subviews.reversed() : subviews
101+
for subview in views {
102+
if let found = subview.viewInHierarchy(frontFirst: frontFirst, where: predicate) {
103+
return found
104+
}
105+
}
106+
return nil
107+
}
108+
109+
/// Sweeter: Search the view hierarchy recursively for a subview with `aClass`
110+
func viewWithClass<T>(_ aClass: T.Type, frontFirst: Bool = true) -> T? {
111+
return viewInHierarchy(frontFirst: frontFirst, where: { $0 is T }) as? T
112+
}
113+
114+
/// Sweeter: The color used to tint the view, as inherited from its superviews.
115+
var actualTintColor: UIColor {
116+
var tintedView: UIView? = self
117+
while let currentView = tintedView, nil == currentView.tintColor {
118+
tintedView = currentView.superview
119+
}
120+
return tintedView?.tintColor ?? UIColor(red: 0, green: 0.5, blue: 1, alpha: 1)
121+
}
122+
}

0 commit comments

Comments
 (0)