forked from michiamling/SpreadsheetView
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpreadsheetView+Touches.swift
133 lines (118 loc) · 4.34 KB
/
SpreadsheetView+Touches.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// SpreadsheetView+Touches.swift
// SpreadsheetView
//
// Created by Kishikawa Katsumi on 5/1/17.
// Copyright © 2017 Kishikawa Katsumi. All rights reserved.
//
import UIKit
extension SpreadsheetView {
func touchesBegan(_ touches: Set<UITouch>, _ event: UIEvent?) {
guard currentTouch == nil else {
return
}
currentTouch = touches.first
unhighlightAllItems()
highlightItems(on: touches)
if !allowsMultipleSelection,
let touch = touches.first, let indexPath = indexPathForItem(at: touch.location(in: self)),
let cell = cellForItem(at: indexPath), cell.isUserInteractionEnabled {
selectedIndexPaths.forEach {
cellsForItem(at: $0).forEach { $0.isSelected = false }
}
}
}
func touchesEnded(_ touches: Set<UITouch>, _ event: UIEvent?) {
guard let touch = touches.first, touch === currentTouch else {
return
}
let highlightedItems = highlightedIndexPaths
unhighlightAllItems()
if allowsMultipleSelection,
let touch = touches.first, let indexPath = indexPathForItem(at: touch.location(in: self)),
selectedIndexPaths.contains(indexPath) {
if delegate?.spreadsheetView(self, shouldDeselectItemAt: indexPath) ?? true {
deselectItem(at: indexPath)
}
} else {
selectItems(on: touches, highlightedItems: highlightedItems)
}
clearCurrentTouch()
}
func touchesCancelled(_ touches: Set<UITouch>, _ event: UIEvent?) {
unhighlightAllItems()
restorePreviousSelection()
clearCurrentTouch()
}
func highlightItems(on touches: Set<UITouch>) {
guard allowsSelection else {
return
}
if let touch = touches.first {
if let indexPath = indexPathForItem(at: touch.location(in: self)) {
guard let cell = cellForItem(at: indexPath), cell.isUserInteractionEnabled else {
return
}
if delegate?.spreadsheetView(self, shouldHighlightItemAt: indexPath) ?? true {
highlightedIndexPaths.insert(indexPath)
cellsForItem(at: indexPath).forEach {
$0.isHighlighted = true
}
delegate?.spreadsheetView(self, didHighlightItemAt: indexPath)
}
}
}
}
private func unhighlightAllItems() {
highlightedIndexPaths.forEach { (indexPath) in
cellsForItem(at: indexPath).forEach {
$0.isHighlighted = false
}
delegate?.spreadsheetView(self, didUnhighlightItemAt: indexPath)
}
highlightedIndexPaths.removeAll()
}
private func selectItems(on touches: Set<UITouch>, highlightedItems: Set<IndexPath>) {
guard allowsSelection else {
return
}
if let touch = touches.first {
if let indexPath = indexPathForItem(at: touch.location(in: self)), highlightedItems.contains(indexPath) {
selectItem(at: indexPath)
}
}
}
private func selectItem(at indexPath: IndexPath) {
let cells = cellsForItem(at: indexPath)
if !cells.isEmpty && delegate?.spreadsheetView(self, shouldSelectItemAt: indexPath) ?? true {
if !allowsMultipleSelection {
selectedIndexPaths.remove(indexPath)
deselectAllItems()
}
cells.forEach {
$0.isSelected = true
}
delegate?.spreadsheetView(self, didSelectItemAt: indexPath)
selectedIndexPaths.insert(indexPath)
}
}
private func deselectItem(at indexPath: IndexPath) {
let cells = cellsForItem(at: indexPath)
cells.forEach {
$0.isSelected = false
}
delegate?.spreadsheetView(self, didDeselectItemAt: indexPath)
selectedIndexPaths.remove(indexPath)
}
private func deselectAllItems() {
selectedIndexPaths.forEach { deselectItem(at: $0) }
}
@objc func restorePreviousSelection() {
selectedIndexPaths.forEach {
cellsForItem(at: $0).forEach { $0.isSelected = true }
}
}
@objc func clearCurrentTouch() {
currentTouch = nil
}
}