Reduce redundant code, cell copy menu
This commit is contained in:
@@ -90,3 +90,34 @@ extension EditActionsRemove where Self: UITableViewController {
|
|||||||
func editableRowActions(_: IndexPath) -> [(RowAction, String)] { [(.delete, "Remove")] }
|
func editableRowActions(_: IndexPath) -> [(RowAction, String)] { [(.delete, "Remove")] }
|
||||||
func editableRowActionColor(_: IndexPath, _: RowAction) -> UIColor? { nil }
|
func editableRowActionColor(_: IndexPath, _: RowAction) -> UIColor? { nil }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - Table Cell Tap Menu
|
||||||
|
|
||||||
|
struct TableCellTapMenu {
|
||||||
|
private var index: Int = Int.max
|
||||||
|
|
||||||
|
mutating func reset() { index = Int.max }
|
||||||
|
|
||||||
|
/// Create a new tap manu and shows it immediatelly. With optional buttons.
|
||||||
|
mutating func start(_ tableView: UITableView, _ indexPath: IndexPath, items: [UIMenuItem]? = nil) -> Bool {
|
||||||
|
let menu = UIMenuController.shared
|
||||||
|
if index == indexPath.row {
|
||||||
|
menu.setMenuVisible(false, animated: true)
|
||||||
|
reset()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
index = indexPath.row
|
||||||
|
let cell = tableView.cellForRow(at: indexPath)!
|
||||||
|
menu.setTargetRect(cell.bounds, in: cell)
|
||||||
|
menu.menuItems = items
|
||||||
|
menu.setMenuVisible(true, animated: true)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the item if the array index is in bounds.
|
||||||
|
func getSelected<T>(_ source: [T]) -> T? {
|
||||||
|
guard index < source.count else { return nil }
|
||||||
|
return source[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -196,7 +196,7 @@
|
|||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="RecordDetailCountedCell" textLabel="rN0-kA-Eln" detailTextLabel="xRp-XG-oKf" style="IBUITableViewCellStyleValue1" id="ceT-cF-lLF">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="RecordDetailCountedCell" textLabel="rN0-kA-Eln" detailTextLabel="xRp-XG-oKf" style="IBUITableViewCellStyleValue1" id="ceT-cF-lLF">
|
||||||
<rect key="frame" x="0.0" y="28" width="320" height="43.5"/>
|
<rect key="frame" x="0.0" y="28" width="320" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ceT-cF-lLF" id="c5Y-xg-hSL">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ceT-cF-lLF" id="c5Y-xg-hSL">
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="RecordDetailShortCell" textLabel="rIc-r4-6pg" detailTextLabel="0pW-ZC-wmh" style="IBUITableViewCellStyleValue2" id="hzU-cx-nIs">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="RecordDetailShortCell" textLabel="rIc-r4-6pg" detailTextLabel="0pW-ZC-wmh" style="IBUITableViewCellStyleValue2" id="hzU-cx-nIs">
|
||||||
<rect key="frame" x="0.0" y="71.5" width="320" height="43.5"/>
|
<rect key="frame" x="0.0" y="71.5" width="320" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hzU-cx-nIs" id="scX-pQ-E7z">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="hzU-cx-nIs" id="scX-pQ-E7z">
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="RecordDetailLongCell" textLabel="xDy-8J-JFT" detailTextLabel="kgF-BN-FdV" style="IBUITableViewCellStyleSubtitle" id="Q4T-JJ-fqY">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="RecordDetailLongCell" textLabel="xDy-8J-JFT" detailTextLabel="kgF-BN-FdV" style="IBUITableViewCellStyleSubtitle" id="Q4T-JJ-fqY">
|
||||||
<rect key="frame" x="0.0" y="115" width="320" height="57.5"/>
|
<rect key="frame" x="0.0" y="115" width="320" height="57.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Q4T-JJ-fqY" id="8hy-Rg-b6Q">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Q4T-JJ-fqY" id="8hy-Rg-b6Q">
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="RecordNoResultsCell" textLabel="bmQ-Cn-BOm" style="IBUITableViewCellStyleDefault" id="JZ4-vZ-MnG">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="RecordNoResultsCell" textLabel="bmQ-Cn-BOm" style="IBUITableViewCellStyleDefault" id="JZ4-vZ-MnG">
|
||||||
<rect key="frame" x="0.0" y="172.5" width="320" height="43.5"/>
|
<rect key="frame" x="0.0" y="172.5" width="320" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="JZ4-vZ-MnG" id="TWb-p9-EMM">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="JZ4-vZ-MnG" id="TWb-p9-EMM">
|
||||||
|
|||||||
@@ -293,12 +293,12 @@
|
|||||||
<scene sceneID="218-uP-X7b">
|
<scene sceneID="218-uP-X7b">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="q3B-Yi-1bx" customClass="TVCFilter" customModule="AppCheck" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="q3B-Yi-1bx" customClass="TVCFilter" customModule="AppCheck" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelection="NO" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="GSg-ZZ-F8J">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="GSg-ZZ-F8J">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="DomainFilterCell" textLabel="MrS-rb-RLB" style="IBUITableViewCellStyleDefault" id="EO2-ww-xuz">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" reuseIdentifier="DomainFilterCell" textLabel="MrS-rb-RLB" style="IBUITableViewCellStyleDefault" id="EO2-ww-xuz">
|
||||||
<rect key="frame" x="0.0" y="28" width="320" height="43.5"/>
|
<rect key="frame" x="0.0" y="28" width="320" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="EO2-ww-xuz" id="AtR-ce-uYs">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="EO2-ww-xuz" id="AtR-ce-uYs">
|
||||||
|
|||||||
@@ -122,59 +122,52 @@ class TVCRecordingDetails: UITableViewController, EditActionsRemove {
|
|||||||
|
|
||||||
// MARK: - Tap to Copy
|
// MARK: - Tap to Copy
|
||||||
|
|
||||||
private var rowToCopy: Int = Int.max
|
private var cellMenu = TableCellTapMenu()
|
||||||
|
private var copyDomain: String? = nil
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
||||||
if rowToCopy == indexPath.row {
|
if noResults { return nil }
|
||||||
UIMenuController.shared.setMenuVisible(false, animated: true)
|
let buttons = [
|
||||||
rowToCopy = Int.max
|
UIMenuItem(title: "All requests", action: #selector(openInLogs)),
|
||||||
return nil
|
// UIMenuItem(title: "CoOccurrence", action: #selector(openCoOccurrence))
|
||||||
}
|
|
||||||
rowToCopy = indexPath.row
|
|
||||||
self.becomeFirstResponder()
|
|
||||||
let cell = tableView.cellForRow(at: indexPath)!
|
|
||||||
UIMenuController.shared.setTargetRect(cell.bounds, in: cell)
|
|
||||||
UIMenuController.shared.menuItems = [
|
|
||||||
.init(title: "All requests", action: #selector(openInLogs)),
|
|
||||||
// .init(title: "CoOccurrence", action: #selector(openCoOccurrence))
|
|
||||||
]
|
]
|
||||||
UIMenuController.shared.setMenuVisible(true, animated: true)
|
if cellMenu.start(tableView, indexPath, items: buttons) {
|
||||||
|
if showRaw {
|
||||||
|
copyDomain = cellMenu.getSelected(dataSourceRaw)?.domain
|
||||||
|
} else {
|
||||||
|
copyDomain = cellMenu.getSelected(dataSourceSum)?.domain
|
||||||
|
}
|
||||||
|
self.becomeFirstResponder()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
override var canBecomeFirstResponder: Bool { true }
|
override var canBecomeFirstResponder: Bool { true }
|
||||||
|
|
||||||
override func copy(_ sender: Any?) {
|
override func copy(_ sender: Any?) {
|
||||||
UIPasteboard.general.string = getDomain()
|
if let dom = copyDomain {
|
||||||
rowToCopy = Int.max
|
UIPasteboard.general.string = dom
|
||||||
|
}
|
||||||
|
cellMenu.reset()
|
||||||
|
copyDomain = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func openInLogs() {
|
@objc private func openInLogs() {
|
||||||
guard let selectedDomain = getDomain(),
|
if let dom = copyDomain, let req = (tabBarController as? TBCMain)?.openTab(0) as? TVCDomains {
|
||||||
let tabBar = tabBarController as? TBCMain,
|
VCDateFilter.disableFilter()
|
||||||
let tab = tabBar.openTab(0) as? TVCDomains else {
|
req.pushOpen(domain: dom)
|
||||||
return
|
|
||||||
}
|
|
||||||
VCDateFilter.disableFilter()
|
|
||||||
tab.pushOpen(domain: selectedDomain)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getDomain() -> String? {
|
|
||||||
if showRaw {
|
|
||||||
guard rowToCopy < dataSourceRaw.count else { return nil }
|
|
||||||
return dataSourceRaw[rowToCopy].domain
|
|
||||||
} else {
|
|
||||||
guard rowToCopy < dataSourceSum.count else { return nil }
|
|
||||||
return dataSourceSum[rowToCopy].domain
|
|
||||||
}
|
}
|
||||||
|
cellMenu.reset()
|
||||||
|
copyDomain = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// @objc private func openCoOccurrence() {
|
// @objc private func openCoOccurrence() {
|
||||||
// guard let vc: VCCoOccurrence = storyboard?.load("IBCoOccurrence") else {
|
// if let dom = copyDomain, let vc: VCCoOccurrence = storyboard?.load("IBCoOccurrence") {
|
||||||
// return
|
// vc.domainName = dom
|
||||||
|
// vc.isFQDN = true
|
||||||
|
// present(vc, animated: true)
|
||||||
// }
|
// }
|
||||||
// vc.domainName = getDomain()
|
// cellMenu.reset()
|
||||||
// vc.isFQDN = true
|
// copyDomain = nil
|
||||||
// present(vc, animated: true)
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,32 +66,24 @@ class TVCOccurrenceContext: UITableViewController {
|
|||||||
|
|
||||||
// MARK: - Tap to Copy
|
// MARK: - Tap to Copy
|
||||||
|
|
||||||
private var rowToCopy: Int = Int.max
|
private var cellMenu = TableCellTapMenu()
|
||||||
|
private var copyDomain: String? = nil
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
||||||
if firstOrLast(indexPath.row) { return nil }
|
if cellMenu.start(tableView, indexPath) {
|
||||||
if rowToCopy == indexPath.row {
|
copyDomain = cellMenu.getSelected(dataSource)?.domain
|
||||||
UIMenuController.shared.setMenuVisible(false, animated: true)
|
self.becomeFirstResponder()
|
||||||
rowToCopy = Int.max
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
rowToCopy = indexPath.row
|
|
||||||
self.becomeFirstResponder()
|
|
||||||
let cell = tableView.cellForRow(at: indexPath)!
|
|
||||||
UIMenuController.shared.setTargetRect(cell.bounds, in: cell)
|
|
||||||
UIMenuController.shared.setMenuVisible(true, animated: true)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
override var canBecomeFirstResponder: Bool { true }
|
override var canBecomeFirstResponder: Bool { true }
|
||||||
|
|
||||||
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
|
||||||
action == #selector(UIResponderStandardEditActions.copy)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func copy(_ sender: Any?) {
|
override func copy(_ sender: Any?) {
|
||||||
guard rowToCopy < dataSource.count else { return }
|
if let dom = copyDomain {
|
||||||
UIPasteboard.general.string = dataSource[rowToCopy].domain
|
UIPasteboard.general.string = dom
|
||||||
rowToCopy = Int.max
|
}
|
||||||
|
cellMenu.reset()
|
||||||
|
copyDomain = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,9 +51,6 @@ class TVCFilter: UITableViewController, EditActionsRemove {
|
|||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "DomainFilterCell")!
|
let cell = tableView.dequeueReusableCell(withIdentifier: "DomainFilterCell")!
|
||||||
cell.textLabel?.text = dataSource[indexPath.row]
|
cell.textLabel?.text = dataSource[indexPath.row]
|
||||||
if cell.gestureRecognizers?.isEmpty ?? true {
|
|
||||||
cell.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(didLongTap)))
|
|
||||||
}
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,29 +72,24 @@ class TVCFilter: UITableViewController, EditActionsRemove {
|
|||||||
|
|
||||||
// MARK: - Long Press Gesture
|
// MARK: - Long Press Gesture
|
||||||
|
|
||||||
private var cellTitleCopy: String?
|
private var cellMenu = TableCellTapMenu()
|
||||||
|
private var copyDomain: String? = nil
|
||||||
|
|
||||||
@objc private func didLongTap(_ sender: UILongPressGestureRecognizer) {
|
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
|
||||||
guard let cell = sender.view as? UITableViewCell else {
|
if cellMenu.start(tableView, indexPath) {
|
||||||
return
|
copyDomain = cellMenu.getSelected(dataSource)
|
||||||
}
|
|
||||||
if sender.state == .began {
|
|
||||||
cellTitleCopy = cell.textLabel?.text
|
|
||||||
self.becomeFirstResponder()
|
self.becomeFirstResponder()
|
||||||
let menu = UIMenuController.shared
|
|
||||||
// menu.setTargetRect(CGRect(origin: sender.location(in: cell), size: CGSize.zero), in: cell)
|
|
||||||
menu.setTargetRect(cell.bounds, in: cell)
|
|
||||||
menu.setMenuVisible(true, animated: true)
|
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
override var canBecomeFirstResponder: Bool { get { true } }
|
|
||||||
|
|
||||||
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
|
|
||||||
action == #selector(UIResponderStandardEditActions.copy)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var canBecomeFirstResponder: Bool { true }
|
||||||
|
|
||||||
override func copy(_ sender: Any?) {
|
override func copy(_ sender: Any?) {
|
||||||
UIPasteboard.general.string = cellTitleCopy
|
if let dom = copyDomain {
|
||||||
cellTitleCopy = nil
|
UIPasteboard.general.string = dom
|
||||||
|
}
|
||||||
|
cellMenu.reset()
|
||||||
|
copyDomain = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user