├── .gitignore
├── .swift-version
├── .travis.yml
├── Example
├── AppDelegate.swift
├── Info.plist
├── Resources
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ └── Base.lproj
│ │ └── LaunchScreen.storyboard
└── Sources
│ ├── MainTableViewCell.swift
│ └── MainViewController.swift
├── FluidHighlighter.h
├── FluidHighlighter.podspec
├── FluidHighlighter.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ └── FluidHighlighter.xcscheme
├── Info.plist
├── LICENSE
├── README.md
└── Sources
└── FluidHighlighter
├── FluidHighlighter.swift
├── UIControl+FH.swift
└── UIView+FH.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.xcuserstate
3 | project.xcworkspace/
4 | xcuserdata/
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.0
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | osx_image: xcode10.2
2 | language: objective-c
3 | env:
4 | global:
5 | - PROJECT="FluidHighlighter.xcodeproj"
6 | - IOS_SDK="iphonesimulator"
7 | matrix:
8 | - SDK="$IOS_SDK" DESTINATION="platform=iOS Simulator,OS=12.2,name=iPhone X"
9 |
10 | install:
11 | - swift --version
12 |
13 | before_script:
14 | - set -o pipefail
15 |
16 | script:
17 | - xcodebuild clean build
18 | -project "$PROJECT"
19 | -scheme FluidHighlighter
20 | -sdk "$SDK"
21 | -destination "$DESTINATION" | xcpretty -c
22 | - xcodebuild clean build
23 | -project "$PROJECT"
24 | -scheme Example
25 | -sdk "$SDK"
26 | -destination "$DESTINATION" | xcpretty -c
--------------------------------------------------------------------------------
/Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Example
4 | //
5 | // Created by DongHeeKang on 30/01/2019.
6 | // Copyright © 2019 k-lpmg. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | let rootViewController = MainViewController()
18 | let window = UIWindow(frame: UIScreen.main.bounds)
19 | window.rootViewController = rootViewController
20 | window.makeKeyAndVisible()
21 | self.window = window
22 | return true
23 | }
24 |
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Example/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/Resources/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Example/Sources/MainTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainTableViewCell.swift
3 | // Example
4 | //
5 | // Created by DongHeeKang on 06/02/2019.
6 | // Copyright © 2019 k-lpmg. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | import FluidHighlighter
12 |
13 | final class MainTableViewCell: UITableViewCell {
14 |
15 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
16 | super.init(style: style, reuseIdentifier: reuseIdentifier)
17 |
18 | selectionStyle = .none
19 | setFluidHighlighter()
20 | }
21 |
22 | required init?(coder aDecoder: NSCoder) {
23 | fatalError("init(coder:) has not been implemented")
24 | }
25 |
26 | private func setFluidHighlighter() {
27 | fh.enable(normalColor: .white, highlightedColor: UIColor.gray.withAlphaComponent(0.5))
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/Example/Sources/MainViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainViewController.swift
3 | // Example
4 | //
5 | // Created by DongHeeKang on 30/01/2019.
6 | // Copyright © 2019 k-lpmg. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | import FluidHighlighter
12 |
13 | final class MainViewController: UIViewController {
14 |
15 | private enum Const {
16 | static let cellId = "cell"
17 | }
18 |
19 | private let view1: UIView = {
20 | let view = UIView()
21 | view.translatesAutoresizingMaskIntoConstraints = false
22 | view.layer.borderColor = UIColor.gray.cgColor
23 | view.layer.borderWidth = 0.5
24 | return view
25 | }()
26 | private let control: UIControl = {
27 | let control = UIControl()
28 | control.translatesAutoresizingMaskIntoConstraints = false
29 | control.layer.borderColor = UIColor.gray.cgColor
30 | control.layer.borderWidth = 0.5
31 | return control
32 | }()
33 | private let button: UIButton = {
34 | let button = UIButton()
35 | button.translatesAutoresizingMaskIntoConstraints = false
36 | button.setTitle("Button", for: .normal)
37 | button.setTitleColor(UIColor.gray, for: .normal)
38 | return button
39 | }()
40 | private lazy var tableView: UITableView = {
41 | let tableView = UITableView()
42 | tableView.translatesAutoresizingMaskIntoConstraints = false
43 | tableView.register(MainTableViewCell.self, forCellReuseIdentifier: Const.cellId)
44 | tableView.dataSource = self
45 | return tableView
46 | }()
47 |
48 | override func viewDidLoad() {
49 | super.viewDidLoad()
50 |
51 | view.backgroundColor = .white
52 | setFluidHighlighter()
53 | view.addSubview(view1)
54 | view.addSubview(control)
55 | view.addSubview(button)
56 | view.addSubview(tableView)
57 | layout()
58 | }
59 |
60 | private func setFluidHighlighter() {
61 | view1.fh.enable(normalColor: .white, highlightedColor: UIColor.gray.withAlphaComponent(0.5))
62 | control.fh.controlEnable(normalColor: .white, highlightedColor: UIColor.yellow.withAlphaComponent(0.5))
63 | button.fh.controlEnable(normalColor: .white, highlightedColor: UIColor.darkGray.withAlphaComponent(0.5))
64 | }
65 |
66 | }
67 |
68 | extension MainViewController {
69 |
70 | private func layout() {
71 | view1.trailingAnchor.constraint(equalTo: control.leadingAnchor, constant: -8).isActive = true
72 | view1.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 16).isActive = true
73 | view1.heightAnchor.constraint(equalToConstant: 100).isActive = true
74 | view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
75 |
76 | control.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
77 | control.topAnchor.constraint(equalTo: view1.topAnchor).isActive = true
78 | control.heightAnchor.constraint(equalTo: view1.heightAnchor).isActive = true
79 | control.widthAnchor.constraint(equalToConstant: 100).isActive = true
80 |
81 | button.leadingAnchor.constraint(equalTo: control.trailingAnchor, constant: 8).isActive = true
82 | button.centerYAnchor.constraint(equalTo: view1.centerYAnchor).isActive = true
83 | button.widthAnchor.constraint(equalToConstant: 80).isActive = true
84 |
85 | tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
86 | tableView.topAnchor.constraint(equalTo: view1.bottomAnchor, constant: 32).isActive = true
87 | tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
88 | tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
89 | }
90 |
91 | }
92 |
93 | extension MainViewController: UITableViewDataSource {
94 |
95 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
96 | return 30
97 | }
98 |
99 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
100 | let cell = tableView.dequeueReusableCell(withIdentifier: Const.cellId, for: indexPath)
101 | cell.textLabel?.text = "\(indexPath.row)"
102 | return cell
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/FluidHighlighter.h:
--------------------------------------------------------------------------------
1 | //
2 | // FluidHighlighter.h
3 | // FluidHighlighter
4 | //
5 | // Created by DongHeeKang on 30/01/2019.
6 | // Copyright © 2019 k-lpmg. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for FluidHighlighter.
12 | FOUNDATION_EXPORT double FluidHighlighterVersionNumber;
13 |
14 | //! Project version string for FluidHighlighter.
15 | FOUNDATION_EXPORT const unsigned char FluidHighlighterVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/FluidHighlighter.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "FluidHighlighter"
3 | s.version = "2.0.0"
4 | s.summary = "FluidHighlighter easily implements the Fluid Interface based highlighting effect on UIView and UIControl."
5 | s.homepage = "https://github.com/k-lpmg/FluidHighlighter"
6 | s.license = { :type => 'MIT', :file => 'LICENSE' }
7 | s.author = { "DongHee Kang" => "kanglpmg@gmail.com" }
8 | s.source = { :git => "https://github.com/k-lpmg/FluidHighlighter.git", :tag => s.version.to_s }
9 | s.documentation_url = "https://github.com/k-lpmg/FluidHighlighter/blob/master/README.md"
10 |
11 | s.ios.source_files = "Sources/**/*.swift"
12 | s.ios.deployment_target = "8.0"
13 | end
14 |
--------------------------------------------------------------------------------
/FluidHighlighter.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 650D4A3A2201CF4B008B0D71 /* FluidHighlighter.h in Headers */ = {isa = PBXBuildFile; fileRef = 650D4A382201CF4B008B0D71 /* FluidHighlighter.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 650D4A432201D02C008B0D71 /* FluidHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650D4A422201D02C008B0D71 /* FluidHighlighter.swift */; };
12 | 650D4A452201D075008B0D71 /* UIControl+FH.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650D4A442201D075008B0D71 /* UIControl+FH.swift */; };
13 | 650D4A472201D0D8008B0D71 /* UIView+FH.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650D4A462201D0D8008B0D71 /* UIView+FH.swift */; };
14 | 650D4A4F2201D161008B0D71 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650D4A4E2201D161008B0D71 /* AppDelegate.swift */; };
15 | 650D4A562201D162008B0D71 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 650D4A552201D162008B0D71 /* Assets.xcassets */; };
16 | 650D4A592201D162008B0D71 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 650D4A572201D162008B0D71 /* LaunchScreen.storyboard */; };
17 | 650D4A612201D1EC008B0D71 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650D4A602201D1EC008B0D71 /* MainViewController.swift */; };
18 | 658E8B7E226ED22F008423C5 /* FluidHighlighter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 650D4A352201CF4B008B0D71 /* FluidHighlighter.framework */; };
19 | 65C48291220B210000623AFF /* MainTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C48290220B210000623AFF /* MainTableViewCell.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXFileReference section */
23 | 650D4A352201CF4B008B0D71 /* FluidHighlighter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FluidHighlighter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
24 | 650D4A382201CF4B008B0D71 /* FluidHighlighter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FluidHighlighter.h; sourceTree = ""; };
25 | 650D4A392201CF4B008B0D71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
26 | 650D4A422201D02C008B0D71 /* FluidHighlighter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FluidHighlighter.swift; sourceTree = ""; };
27 | 650D4A442201D075008B0D71 /* UIControl+FH.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIControl+FH.swift"; sourceTree = ""; };
28 | 650D4A462201D0D8008B0D71 /* UIView+FH.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+FH.swift"; sourceTree = ""; };
29 | 650D4A4C2201D161008B0D71 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
30 | 650D4A4E2201D161008B0D71 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
31 | 650D4A552201D162008B0D71 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
32 | 650D4A582201D162008B0D71 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
33 | 650D4A5A2201D162008B0D71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | 650D4A602201D1EC008B0D71 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; };
35 | 65C48290220B210000623AFF /* MainTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTableViewCell.swift; sourceTree = ""; };
36 | /* End PBXFileReference section */
37 |
38 | /* Begin PBXFrameworksBuildPhase section */
39 | 650D4A322201CF4B008B0D71 /* Frameworks */ = {
40 | isa = PBXFrameworksBuildPhase;
41 | buildActionMask = 2147483647;
42 | files = (
43 | );
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | 650D4A492201D161008B0D71 /* Frameworks */ = {
47 | isa = PBXFrameworksBuildPhase;
48 | buildActionMask = 2147483647;
49 | files = (
50 | 658E8B7E226ED22F008423C5 /* FluidHighlighter.framework in Frameworks */,
51 | );
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | /* End PBXFrameworksBuildPhase section */
55 |
56 | /* Begin PBXGroup section */
57 | 650D4A2B2201CF4B008B0D71 = {
58 | isa = PBXGroup;
59 | children = (
60 | 650D4A382201CF4B008B0D71 /* FluidHighlighter.h */,
61 | 650D4A392201CF4B008B0D71 /* Info.plist */,
62 | 650D4A402201CF93008B0D71 /* Sources */,
63 | 650D4A4D2201D161008B0D71 /* Example */,
64 | 650D4A362201CF4B008B0D71 /* Products */,
65 | 658E8B7D226ED22F008423C5 /* Frameworks */,
66 | );
67 | sourceTree = "";
68 | };
69 | 650D4A362201CF4B008B0D71 /* Products */ = {
70 | isa = PBXGroup;
71 | children = (
72 | 650D4A352201CF4B008B0D71 /* FluidHighlighter.framework */,
73 | 650D4A4C2201D161008B0D71 /* Example.app */,
74 | );
75 | name = Products;
76 | sourceTree = "";
77 | };
78 | 650D4A402201CF93008B0D71 /* Sources */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 650D4A412201CF93008B0D71 /* FluidHighlighter */,
82 | );
83 | path = Sources;
84 | sourceTree = "";
85 | };
86 | 650D4A412201CF93008B0D71 /* FluidHighlighter */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 650D4A422201D02C008B0D71 /* FluidHighlighter.swift */,
90 | 650D4A442201D075008B0D71 /* UIControl+FH.swift */,
91 | 650D4A462201D0D8008B0D71 /* UIView+FH.swift */,
92 | );
93 | path = FluidHighlighter;
94 | sourceTree = "";
95 | };
96 | 650D4A4D2201D161008B0D71 /* Example */ = {
97 | isa = PBXGroup;
98 | children = (
99 | 650D4A5F2201D1AE008B0D71 /* Resources */,
100 | 650D4A5E2201D1A8008B0D71 /* Sources */,
101 | 650D4A4E2201D161008B0D71 /* AppDelegate.swift */,
102 | 650D4A5A2201D162008B0D71 /* Info.plist */,
103 | );
104 | path = Example;
105 | sourceTree = "";
106 | };
107 | 650D4A5E2201D1A8008B0D71 /* Sources */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 650D4A602201D1EC008B0D71 /* MainViewController.swift */,
111 | 65C48290220B210000623AFF /* MainTableViewCell.swift */,
112 | );
113 | path = Sources;
114 | sourceTree = "";
115 | };
116 | 650D4A5F2201D1AE008B0D71 /* Resources */ = {
117 | isa = PBXGroup;
118 | children = (
119 | 650D4A552201D162008B0D71 /* Assets.xcassets */,
120 | 650D4A572201D162008B0D71 /* LaunchScreen.storyboard */,
121 | );
122 | path = Resources;
123 | sourceTree = "";
124 | };
125 | 658E8B7D226ED22F008423C5 /* Frameworks */ = {
126 | isa = PBXGroup;
127 | children = (
128 | );
129 | name = Frameworks;
130 | sourceTree = "";
131 | };
132 | /* End PBXGroup section */
133 |
134 | /* Begin PBXHeadersBuildPhase section */
135 | 650D4A302201CF4B008B0D71 /* Headers */ = {
136 | isa = PBXHeadersBuildPhase;
137 | buildActionMask = 2147483647;
138 | files = (
139 | 650D4A3A2201CF4B008B0D71 /* FluidHighlighter.h in Headers */,
140 | );
141 | runOnlyForDeploymentPostprocessing = 0;
142 | };
143 | /* End PBXHeadersBuildPhase section */
144 |
145 | /* Begin PBXNativeTarget section */
146 | 650D4A342201CF4B008B0D71 /* FluidHighlighter */ = {
147 | isa = PBXNativeTarget;
148 | buildConfigurationList = 650D4A3D2201CF4B008B0D71 /* Build configuration list for PBXNativeTarget "FluidHighlighter" */;
149 | buildPhases = (
150 | 650D4A302201CF4B008B0D71 /* Headers */,
151 | 650D4A312201CF4B008B0D71 /* Sources */,
152 | 650D4A322201CF4B008B0D71 /* Frameworks */,
153 | 650D4A332201CF4B008B0D71 /* Resources */,
154 | );
155 | buildRules = (
156 | );
157 | dependencies = (
158 | );
159 | name = FluidHighlighter;
160 | productName = FluidHighlighter;
161 | productReference = 650D4A352201CF4B008B0D71 /* FluidHighlighter.framework */;
162 | productType = "com.apple.product-type.framework";
163 | };
164 | 650D4A4B2201D161008B0D71 /* Example */ = {
165 | isa = PBXNativeTarget;
166 | buildConfigurationList = 650D4A5B2201D162008B0D71 /* Build configuration list for PBXNativeTarget "Example" */;
167 | buildPhases = (
168 | 650D4A482201D161008B0D71 /* Sources */,
169 | 650D4A492201D161008B0D71 /* Frameworks */,
170 | 650D4A4A2201D161008B0D71 /* Resources */,
171 | );
172 | buildRules = (
173 | );
174 | dependencies = (
175 | );
176 | name = Example;
177 | productName = Example;
178 | productReference = 650D4A4C2201D161008B0D71 /* Example.app */;
179 | productType = "com.apple.product-type.application";
180 | };
181 | /* End PBXNativeTarget section */
182 |
183 | /* Begin PBXProject section */
184 | 650D4A2C2201CF4B008B0D71 /* Project object */ = {
185 | isa = PBXProject;
186 | attributes = {
187 | LastSwiftUpdateCheck = 1010;
188 | LastUpgradeCheck = 1010;
189 | ORGANIZATIONNAME = "k-lpmg";
190 | TargetAttributes = {
191 | 650D4A342201CF4B008B0D71 = {
192 | CreatedOnToolsVersion = 10.1;
193 | LastSwiftMigration = 1010;
194 | };
195 | 650D4A4B2201D161008B0D71 = {
196 | CreatedOnToolsVersion = 10.1;
197 | };
198 | };
199 | };
200 | buildConfigurationList = 650D4A2F2201CF4B008B0D71 /* Build configuration list for PBXProject "FluidHighlighter" */;
201 | compatibilityVersion = "Xcode 9.3";
202 | developmentRegion = en;
203 | hasScannedForEncodings = 0;
204 | knownRegions = (
205 | en,
206 | Base,
207 | );
208 | mainGroup = 650D4A2B2201CF4B008B0D71;
209 | productRefGroup = 650D4A362201CF4B008B0D71 /* Products */;
210 | projectDirPath = "";
211 | projectRoot = "";
212 | targets = (
213 | 650D4A342201CF4B008B0D71 /* FluidHighlighter */,
214 | 650D4A4B2201D161008B0D71 /* Example */,
215 | );
216 | };
217 | /* End PBXProject section */
218 |
219 | /* Begin PBXResourcesBuildPhase section */
220 | 650D4A332201CF4B008B0D71 /* Resources */ = {
221 | isa = PBXResourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | );
225 | runOnlyForDeploymentPostprocessing = 0;
226 | };
227 | 650D4A4A2201D161008B0D71 /* Resources */ = {
228 | isa = PBXResourcesBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | 650D4A592201D162008B0D71 /* LaunchScreen.storyboard in Resources */,
232 | 650D4A562201D162008B0D71 /* Assets.xcassets in Resources */,
233 | );
234 | runOnlyForDeploymentPostprocessing = 0;
235 | };
236 | /* End PBXResourcesBuildPhase section */
237 |
238 | /* Begin PBXSourcesBuildPhase section */
239 | 650D4A312201CF4B008B0D71 /* Sources */ = {
240 | isa = PBXSourcesBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | 650D4A472201D0D8008B0D71 /* UIView+FH.swift in Sources */,
244 | 650D4A452201D075008B0D71 /* UIControl+FH.swift in Sources */,
245 | 650D4A432201D02C008B0D71 /* FluidHighlighter.swift in Sources */,
246 | );
247 | runOnlyForDeploymentPostprocessing = 0;
248 | };
249 | 650D4A482201D161008B0D71 /* Sources */ = {
250 | isa = PBXSourcesBuildPhase;
251 | buildActionMask = 2147483647;
252 | files = (
253 | 650D4A4F2201D161008B0D71 /* AppDelegate.swift in Sources */,
254 | 65C48291220B210000623AFF /* MainTableViewCell.swift in Sources */,
255 | 650D4A612201D1EC008B0D71 /* MainViewController.swift in Sources */,
256 | );
257 | runOnlyForDeploymentPostprocessing = 0;
258 | };
259 | /* End PBXSourcesBuildPhase section */
260 |
261 | /* Begin PBXVariantGroup section */
262 | 650D4A572201D162008B0D71 /* LaunchScreen.storyboard */ = {
263 | isa = PBXVariantGroup;
264 | children = (
265 | 650D4A582201D162008B0D71 /* Base */,
266 | );
267 | name = LaunchScreen.storyboard;
268 | sourceTree = "";
269 | };
270 | /* End PBXVariantGroup section */
271 |
272 | /* Begin XCBuildConfiguration section */
273 | 650D4A3B2201CF4B008B0D71 /* Debug */ = {
274 | isa = XCBuildConfiguration;
275 | buildSettings = {
276 | ALWAYS_SEARCH_USER_PATHS = NO;
277 | CLANG_ANALYZER_NONNULL = YES;
278 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
280 | CLANG_CXX_LIBRARY = "libc++";
281 | CLANG_ENABLE_MODULES = YES;
282 | CLANG_ENABLE_OBJC_ARC = YES;
283 | CLANG_ENABLE_OBJC_WEAK = YES;
284 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
285 | CLANG_WARN_BOOL_CONVERSION = YES;
286 | CLANG_WARN_COMMA = YES;
287 | CLANG_WARN_CONSTANT_CONVERSION = YES;
288 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
290 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
291 | CLANG_WARN_EMPTY_BODY = YES;
292 | CLANG_WARN_ENUM_CONVERSION = YES;
293 | CLANG_WARN_INFINITE_RECURSION = YES;
294 | CLANG_WARN_INT_CONVERSION = YES;
295 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
296 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
297 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
298 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
299 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
300 | CLANG_WARN_STRICT_PROTOTYPES = YES;
301 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
302 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
303 | CLANG_WARN_UNREACHABLE_CODE = YES;
304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
305 | CODE_SIGN_IDENTITY = "iPhone Developer";
306 | COPY_PHASE_STRIP = NO;
307 | CURRENT_PROJECT_VERSION = 1;
308 | DEBUG_INFORMATION_FORMAT = dwarf;
309 | ENABLE_STRICT_OBJC_MSGSEND = YES;
310 | ENABLE_TESTABILITY = YES;
311 | GCC_C_LANGUAGE_STANDARD = gnu11;
312 | GCC_DYNAMIC_NO_PIC = NO;
313 | GCC_NO_COMMON_BLOCKS = YES;
314 | GCC_OPTIMIZATION_LEVEL = 0;
315 | GCC_PREPROCESSOR_DEFINITIONS = (
316 | "DEBUG=1",
317 | "$(inherited)",
318 | );
319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
320 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
321 | GCC_WARN_UNDECLARED_SELECTOR = YES;
322 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
323 | GCC_WARN_UNUSED_FUNCTION = YES;
324 | GCC_WARN_UNUSED_VARIABLE = YES;
325 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
326 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
327 | MTL_FAST_MATH = YES;
328 | ONLY_ACTIVE_ARCH = YES;
329 | SDKROOT = iphoneos;
330 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
331 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
332 | VERSIONING_SYSTEM = "apple-generic";
333 | VERSION_INFO_PREFIX = "";
334 | };
335 | name = Debug;
336 | };
337 | 650D4A3C2201CF4B008B0D71 /* Release */ = {
338 | isa = XCBuildConfiguration;
339 | buildSettings = {
340 | ALWAYS_SEARCH_USER_PATHS = NO;
341 | CLANG_ANALYZER_NONNULL = YES;
342 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
343 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
344 | CLANG_CXX_LIBRARY = "libc++";
345 | CLANG_ENABLE_MODULES = YES;
346 | CLANG_ENABLE_OBJC_ARC = YES;
347 | CLANG_ENABLE_OBJC_WEAK = YES;
348 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
349 | CLANG_WARN_BOOL_CONVERSION = YES;
350 | CLANG_WARN_COMMA = YES;
351 | CLANG_WARN_CONSTANT_CONVERSION = YES;
352 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
354 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
355 | CLANG_WARN_EMPTY_BODY = YES;
356 | CLANG_WARN_ENUM_CONVERSION = YES;
357 | CLANG_WARN_INFINITE_RECURSION = YES;
358 | CLANG_WARN_INT_CONVERSION = YES;
359 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
360 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
361 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
362 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
363 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
364 | CLANG_WARN_STRICT_PROTOTYPES = YES;
365 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
366 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
367 | CLANG_WARN_UNREACHABLE_CODE = YES;
368 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
369 | CODE_SIGN_IDENTITY = "iPhone Developer";
370 | COPY_PHASE_STRIP = NO;
371 | CURRENT_PROJECT_VERSION = 1;
372 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
373 | ENABLE_NS_ASSERTIONS = NO;
374 | ENABLE_STRICT_OBJC_MSGSEND = YES;
375 | GCC_C_LANGUAGE_STANDARD = gnu11;
376 | GCC_NO_COMMON_BLOCKS = YES;
377 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
378 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
379 | GCC_WARN_UNDECLARED_SELECTOR = YES;
380 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
381 | GCC_WARN_UNUSED_FUNCTION = YES;
382 | GCC_WARN_UNUSED_VARIABLE = YES;
383 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
384 | MTL_ENABLE_DEBUG_INFO = NO;
385 | MTL_FAST_MATH = YES;
386 | SDKROOT = iphoneos;
387 | SWIFT_COMPILATION_MODE = wholemodule;
388 | SWIFT_OPTIMIZATION_LEVEL = "-O";
389 | VALIDATE_PRODUCT = YES;
390 | VERSIONING_SYSTEM = "apple-generic";
391 | VERSION_INFO_PREFIX = "";
392 | };
393 | name = Release;
394 | };
395 | 650D4A3E2201CF4B008B0D71 /* Debug */ = {
396 | isa = XCBuildConfiguration;
397 | buildSettings = {
398 | CLANG_ENABLE_MODULES = YES;
399 | CODE_SIGN_IDENTITY = "";
400 | CODE_SIGN_STYLE = Manual;
401 | DEFINES_MODULE = YES;
402 | DEVELOPMENT_TEAM = "";
403 | DYLIB_COMPATIBILITY_VERSION = 1;
404 | DYLIB_CURRENT_VERSION = 1;
405 | DYLIB_INSTALL_NAME_BASE = "@rpath";
406 | INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
407 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
408 | LD_RUNPATH_SEARCH_PATHS = (
409 | "$(inherited)",
410 | "@executable_path/Frameworks",
411 | "@loader_path/Frameworks",
412 | );
413 | PRODUCT_BUNDLE_IDENTIFIER = "com.k-lpmg.FluidHighlighter";
414 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
415 | PROVISIONING_PROFILE_SPECIFIER = "";
416 | SKIP_INSTALL = YES;
417 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
418 | SWIFT_VERSION = 5.0;
419 | TARGETED_DEVICE_FAMILY = "1,2";
420 | };
421 | name = Debug;
422 | };
423 | 650D4A3F2201CF4B008B0D71 /* Release */ = {
424 | isa = XCBuildConfiguration;
425 | buildSettings = {
426 | CLANG_ENABLE_MODULES = YES;
427 | CODE_SIGN_IDENTITY = "";
428 | CODE_SIGN_STYLE = Manual;
429 | DEFINES_MODULE = YES;
430 | DEVELOPMENT_TEAM = "";
431 | DYLIB_COMPATIBILITY_VERSION = 1;
432 | DYLIB_CURRENT_VERSION = 1;
433 | DYLIB_INSTALL_NAME_BASE = "@rpath";
434 | INFOPLIST_FILE = "$(SRCROOT)/Info.plist";
435 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
436 | LD_RUNPATH_SEARCH_PATHS = (
437 | "$(inherited)",
438 | "@executable_path/Frameworks",
439 | "@loader_path/Frameworks",
440 | );
441 | PRODUCT_BUNDLE_IDENTIFIER = "com.k-lpmg.FluidHighlighter";
442 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
443 | PROVISIONING_PROFILE_SPECIFIER = "";
444 | SKIP_INSTALL = YES;
445 | SWIFT_VERSION = 5.0;
446 | TARGETED_DEVICE_FAMILY = "1,2";
447 | };
448 | name = Release;
449 | };
450 | 650D4A5C2201D162008B0D71 /* Debug */ = {
451 | isa = XCBuildConfiguration;
452 | buildSettings = {
453 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
454 | CODE_SIGN_IDENTITY = "";
455 | CODE_SIGN_STYLE = Manual;
456 | DEVELOPMENT_TEAM = "";
457 | INFOPLIST_FILE = Example/Info.plist;
458 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
459 | LD_RUNPATH_SEARCH_PATHS = (
460 | "$(inherited)",
461 | "@executable_path/Frameworks",
462 | );
463 | PRODUCT_BUNDLE_IDENTIFIER = "com.k-lpmg.Example";
464 | PRODUCT_NAME = "$(TARGET_NAME)";
465 | PROVISIONING_PROFILE_SPECIFIER = "";
466 | SWIFT_VERSION = 5.0;
467 | TARGETED_DEVICE_FAMILY = "1,2";
468 | };
469 | name = Debug;
470 | };
471 | 650D4A5D2201D162008B0D71 /* Release */ = {
472 | isa = XCBuildConfiguration;
473 | buildSettings = {
474 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
475 | CODE_SIGN_IDENTITY = "";
476 | CODE_SIGN_STYLE = Manual;
477 | DEVELOPMENT_TEAM = "";
478 | INFOPLIST_FILE = Example/Info.plist;
479 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
480 | LD_RUNPATH_SEARCH_PATHS = (
481 | "$(inherited)",
482 | "@executable_path/Frameworks",
483 | );
484 | PRODUCT_BUNDLE_IDENTIFIER = "com.k-lpmg.Example";
485 | PRODUCT_NAME = "$(TARGET_NAME)";
486 | PROVISIONING_PROFILE_SPECIFIER = "";
487 | SWIFT_VERSION = 5.0;
488 | TARGETED_DEVICE_FAMILY = "1,2";
489 | };
490 | name = Release;
491 | };
492 | /* End XCBuildConfiguration section */
493 |
494 | /* Begin XCConfigurationList section */
495 | 650D4A2F2201CF4B008B0D71 /* Build configuration list for PBXProject "FluidHighlighter" */ = {
496 | isa = XCConfigurationList;
497 | buildConfigurations = (
498 | 650D4A3B2201CF4B008B0D71 /* Debug */,
499 | 650D4A3C2201CF4B008B0D71 /* Release */,
500 | );
501 | defaultConfigurationIsVisible = 0;
502 | defaultConfigurationName = Release;
503 | };
504 | 650D4A3D2201CF4B008B0D71 /* Build configuration list for PBXNativeTarget "FluidHighlighter" */ = {
505 | isa = XCConfigurationList;
506 | buildConfigurations = (
507 | 650D4A3E2201CF4B008B0D71 /* Debug */,
508 | 650D4A3F2201CF4B008B0D71 /* Release */,
509 | );
510 | defaultConfigurationIsVisible = 0;
511 | defaultConfigurationName = Release;
512 | };
513 | 650D4A5B2201D162008B0D71 /* Build configuration list for PBXNativeTarget "Example" */ = {
514 | isa = XCConfigurationList;
515 | buildConfigurations = (
516 | 650D4A5C2201D162008B0D71 /* Debug */,
517 | 650D4A5D2201D162008B0D71 /* Release */,
518 | );
519 | defaultConfigurationIsVisible = 0;
520 | defaultConfigurationName = Release;
521 | };
522 | /* End XCConfigurationList section */
523 | };
524 | rootObject = 650D4A2C2201CF4B008B0D71 /* Project object */;
525 | }
526 |
--------------------------------------------------------------------------------
/FluidHighlighter.xcodeproj/xcshareddata/xcschemes/FluidHighlighter.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 2.0.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 DongHee Kang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FluidHighlighter
2 | [](https://travis-ci.org/k-lpmg/FluidHighlighter)
3 | 
4 | [](https://cocoapods.org/pods/FluidHighlighter)
5 | [](https://github.com/Carthage/Carthage)
6 |
7 | FluidHighlighter easily implements the Fluid Interface based highlighting effect on UIView and UIControl.
8 |
9 | ## Introduction
10 |
11 |
12 | ## Usage
13 |
14 | #### Highlighting enable
15 | ```swift
16 | let view = UIView()
17 | view.fh.enable(normalColor: UIColor.white, highlightedColor: UIColor.gray)
18 |
19 | let control = UIControl()
20 | control.fh.controlEnable(normalColor: UIColor.white, highlightedColor: UIColor.gray)
21 | ```
22 |
23 | #### Highlighting disable
24 | ```swift
25 | let view = UIView()
26 | view.fh.disable()
27 |
28 | let control = UIControl()
29 | control.fh.controlDisable()
30 | ```
31 |
32 | #### Enable Parameters
33 |
34 | | Parameter | Type | Description |
35 | | --- | --- | --- |
36 | | `normalColor` | `UIColor` | Background color |
37 | | `highlightedColor` | `UIColor`
38 | | `selectedColor` | `UIColor` | Background color of selected state, only in UIControl |
39 | | `highlightedOptions` | `AnimationOptions`
40 | | `highlightedDelay` | `TimeInterval`
41 | | `highlightedDuration` | `TimeInterval`
42 |
43 |
44 | ## Installation
45 |
46 | #### CocoaPods (iOS 8+)
47 |
48 | ```ruby
49 | platform :ios, '8.0'
50 | use_frameworks!
51 |
52 | target '' do
53 | pod 'FluidHighlighter'
54 | end
55 | ```
56 |
57 | #### Carthage (iOS 8+)
58 |
59 | ```ruby
60 | github "k-lpmg/FluidHighlighter"
61 | ```
62 |
63 |
64 | ## LICENSE
65 |
66 | These works are available under the MIT license. See the [LICENSE][license] file
67 | for more info.
68 |
69 | [license]: LICENSE
70 |
--------------------------------------------------------------------------------
/Sources/FluidHighlighter/FluidHighlighter.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | public class FluidHighlighter {
4 | public let base: Base
5 | public init(_ base: Base) {
6 | self.base = base
7 | }
8 | }
9 |
10 | public protocol FluidHighlighterCompatible {
11 | associatedtype FluidHighlighterCompatibleType
12 | var fh: FluidHighlighterCompatibleType { get }
13 | }
14 |
15 | public extension FluidHighlighterCompatible {
16 | var fh: FluidHighlighter {
17 | return FluidHighlighter(self)
18 | }
19 | }
20 |
21 | extension UIView: FluidHighlighterCompatible {}
22 |
--------------------------------------------------------------------------------
/Sources/FluidHighlighter/UIControl+FH.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | private var touchProxyContext: UInt8 = 0
4 | private var normalColorContext: UInt8 = 0
5 | private var highlightedColorContext: UInt8 = 0
6 | private var selectedColorContext: UInt8 = 0
7 | private var highlightedOptionsContext: UInt8 = 0
8 | private var highlightedDelayContext: UInt8 = 0
9 | private var highlightedDurationContext: UInt8 = 0
10 |
11 | public extension FluidHighlighter where Base: UIControl {
12 |
13 | // MARK: - Properties
14 |
15 | private var touchProxy: TouchProxy? {
16 | get {
17 | return objc_getAssociatedObject(base, &touchProxyContext) as? TouchProxy
18 | }
19 | set {
20 | objc_setAssociatedObject(base, &touchProxyContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
21 | }
22 | }
23 |
24 | private(set) var normalColor: UIColor? {
25 | get {
26 | return objc_getAssociatedObject(base, &normalColorContext) as? UIColor
27 | }
28 | set {
29 | objc_setAssociatedObject(base, &normalColorContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
30 | }
31 | }
32 |
33 | private(set) var highlightedColor: UIColor? {
34 | get {
35 | return objc_getAssociatedObject(base, &highlightedColorContext) as? UIColor
36 | }
37 | set {
38 | objc_setAssociatedObject(base, &highlightedColorContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
39 | }
40 | }
41 |
42 | private(set) var selectedColor: UIColor? {
43 | get {
44 | return objc_getAssociatedObject(base, &selectedColorContext) as? UIColor
45 | }
46 | set {
47 | objc_setAssociatedObject(base, &selectedColorContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
48 | }
49 | }
50 |
51 | private(set) var highlightedOptions: UIView.AnimationOptions? {
52 | get {
53 | return objc_getAssociatedObject(base, &highlightedOptionsContext) as? UIView.AnimationOptions
54 | }
55 | set {
56 | objc_setAssociatedObject(base, &highlightedOptionsContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
57 | }
58 | }
59 |
60 | private(set) var highlightedDelay: TimeInterval {
61 | get {
62 | guard let delay = objc_getAssociatedObject(base, &highlightedDelayContext) as? TimeInterval else {return 0.0}
63 | return delay
64 | }
65 | set {
66 | objc_setAssociatedObject(base, &highlightedDelayContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
67 | }
68 | }
69 |
70 | private(set) var highlightedDuration: TimeInterval {
71 | get {
72 | guard let duration = objc_getAssociatedObject(base, &highlightedDurationContext) as? TimeInterval else {return 0.0}
73 | return duration
74 | }
75 | set {
76 | objc_setAssociatedObject(base, &highlightedDurationContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
77 | }
78 | }
79 |
80 | // MARK: - Public methods
81 |
82 | func controlEnable(normalColor: UIColor,
83 | highlightedColor: UIColor,
84 | selectedColor: UIColor? = nil,
85 | highlightedOptions: UIView.AnimationOptions? = nil,
86 | highlightedDelay: TimeInterval = 0.0,
87 | highlightedDuration: TimeInterval = 0.5) {
88 | self.normalColor = normalColor
89 | self.highlightedColor = highlightedColor
90 | self.selectedColor = selectedColor
91 |
92 | self.highlightedOptions = highlightedOptions
93 | self.highlightedDelay = highlightedDelay
94 | self.highlightedDuration = highlightedDuration
95 |
96 | base.backgroundColor = base.isSelected ? selectedColor ?? normalColor : normalColor
97 |
98 | if touchProxy == nil {
99 | touchProxy = TouchProxy(control: base)
100 | touchProxy?.addTarget()
101 | }
102 | }
103 |
104 | func controlDisable() {
105 | normalColor = nil
106 | highlightedColor = nil
107 | highlightedOptions = nil
108 | highlightedDelay = 0
109 | highlightedDuration = 0
110 |
111 | touchProxy?.removeTarget()
112 | touchProxy = nil
113 | }
114 |
115 | func refreshBackgroundColor() {
116 | touchProxy?.refreshBackgroundColor()
117 | }
118 |
119 | // MARK: - Proxy
120 |
121 | fileprivate final class TouchProxy {
122 |
123 | // MARK: - Properties
124 |
125 | private let control: UIControl
126 |
127 | // MARK: - Constructor
128 |
129 | init(control: UIControl) {
130 | self.control = control
131 | }
132 |
133 | // MARK: - Public methods
134 |
135 | public func addTarget() {
136 | control.addTarget(self, action: #selector(touchDown), for: [.touchDown, .touchDragEnter])
137 | control.addTarget(self, action: #selector(touchUp), for: [.touchUpInside, .touchDragExit, .touchCancel])
138 | }
139 |
140 | public func removeTarget() {
141 | control.removeTarget(self, action: #selector(touchDown), for: [.touchDown, .touchDragEnter])
142 | control.removeTarget(self, action: #selector(touchUp), for: [.touchUpInside, .touchDragExit, .touchCancel])
143 | }
144 |
145 | public func refreshBackgroundColor() {
146 | UIView.animate(withDuration: control.fh.highlightedDuration, delay: control.fh.highlightedDelay, options: control.fh.highlightedOptions ?? [], animations: {
147 | self.control.backgroundColor = self.control.isSelected ? self.control.fh.selectedColor ?? self.control.fh.normalColor : self.control.fh.normalColor
148 | })
149 | }
150 |
151 | // MARK: - Private selector
152 |
153 | @objc private func touchDown() {
154 | control.backgroundColor = control.fh.highlightedColor
155 | }
156 |
157 | @objc private func touchUp() {
158 | refreshBackgroundColor()
159 | }
160 |
161 | }
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/Sources/FluidHighlighter/UIView+FH.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | private var normalColorContext: UInt8 = 0
4 | private var highlightedColorContext: UInt8 = 0
5 | private var highlightedOptionsContext: UInt8 = 0
6 | private var highlightedDelayContext: UInt8 = 0
7 | private var highlightedDurationContext: UInt8 = 0
8 |
9 | public extension FluidHighlighter where Base: UIView {
10 |
11 | // MARK: - Properties
12 |
13 | private(set) var normalColor: UIColor? {
14 | get {
15 | return objc_getAssociatedObject(base, &normalColorContext) as? UIColor
16 | }
17 | set {
18 | objc_setAssociatedObject(base, &normalColorContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
19 | }
20 | }
21 |
22 | private(set) var highlightedColor: UIColor? {
23 | get {
24 | return objc_getAssociatedObject(base, &highlightedColorContext) as? UIColor
25 | }
26 | set {
27 | objc_setAssociatedObject(base, &highlightedColorContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
28 | }
29 | }
30 |
31 | private(set) var highlightedOptions: UIView.AnimationOptions? {
32 | get {
33 | return objc_getAssociatedObject(base, &highlightedOptionsContext) as? UIView.AnimationOptions
34 | }
35 | set {
36 | objc_setAssociatedObject(base, &highlightedOptionsContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
37 | }
38 | }
39 |
40 | private(set) var highlightedDelay: TimeInterval {
41 | get {
42 | guard let delay = objc_getAssociatedObject(base, &highlightedDelayContext) as? TimeInterval else {return 0.0}
43 | return delay
44 | }
45 | set {
46 | objc_setAssociatedObject(base, &highlightedDelayContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
47 | }
48 | }
49 |
50 | private(set) var highlightedDuration: TimeInterval {
51 | get {
52 | guard let duration = objc_getAssociatedObject(base, &highlightedDurationContext) as? TimeInterval else {return 0.0}
53 | return duration
54 | }
55 | set {
56 | objc_setAssociatedObject(base, &highlightedDurationContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
57 | }
58 | }
59 |
60 | // MARK: - Public methods
61 |
62 | func enable(normalColor: UIColor,
63 | highlightedColor: UIColor,
64 | highlightedOptions: UIView.AnimationOptions? = nil,
65 | highlightedDelay: TimeInterval = 0.0,
66 | highlightedDuration: TimeInterval = 0.5) {
67 | self.normalColor = normalColor
68 | self.highlightedColor = highlightedColor
69 | self.highlightedOptions = highlightedOptions
70 | self.highlightedDelay = highlightedDelay
71 | self.highlightedDuration = highlightedDuration
72 |
73 | base.backgroundColor = normalColor
74 | }
75 |
76 | func disable() {
77 | normalColor = nil
78 | highlightedColor = nil
79 | highlightedOptions = nil
80 | highlightedDelay = 0
81 | highlightedDuration = 0
82 | }
83 |
84 | func touchDown() {
85 | guard let highlightedColor = highlightedColor else {return}
86 |
87 | base.backgroundColor = highlightedColor
88 | }
89 |
90 | func touchUp() {
91 | guard let normalColor = normalColor else {return}
92 |
93 | UIView.animate(withDuration: highlightedDuration, delay: highlightedDelay, options: highlightedOptions ?? [], animations: {
94 | self.base.backgroundColor = normalColor
95 | })
96 | }
97 |
98 | }
99 |
100 | extension UIView {
101 |
102 | // MARK: - Overridden: UIView
103 |
104 | override open func touchesBegan(_ touches: Set, with event: UIEvent?) {
105 | super.touchesBegan(touches, with: event)
106 |
107 | fh.touchDown()
108 | }
109 |
110 | override open func touchesEnded(_ touches: Set, with event: UIEvent?) {
111 | super.touchesEnded(touches, with: event)
112 |
113 | fh.touchUp()
114 | }
115 |
116 | override open func touchesMoved(_ touches: Set, with event: UIEvent?) {
117 | super.touchesMoved(touches, with: event)
118 |
119 | if let touch = touches.first {
120 | let position = touch.location(in: self)
121 | isInside(position: position) ? fh.touchDown() : fh.touchUp()
122 | }
123 | }
124 |
125 | override open func touchesCancelled(_ touches: Set, with event: UIEvent?) {
126 | super.touchesCancelled(touches, with: event)
127 |
128 | fh.touchUp()
129 | }
130 |
131 | // MARK: - Private methods
132 |
133 | private func isInside(position: CGPoint) -> Bool {
134 | let x = position.x
135 | let y = position.y
136 | let xIsInFrame = bounds.origin.x <= x && x <= bounds.origin.x + bounds.width*1.5
137 | let yIsInFrame = bounds.origin.y <= y && y <= bounds.origin.y + bounds.height*1.5
138 | return xIsInFrame && yIsInFrame
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------