Reduce redundant code, cell copy menu

This commit is contained in:
relikd
2020-09-05 21:05:12 +02:00
parent b8660c9a35
commit d2fa67e0e3
6 changed files with 93 additions and 85 deletions

View File

@@ -90,3 +90,34 @@ extension EditActionsRemove where Self: UITableViewController {
func editableRowActions(_: IndexPath) -> [(RowAction, String)] { [(.delete, "Remove")] }
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]
}
}

View File

@@ -196,7 +196,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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"/>
<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">
@@ -220,7 +220,7 @@
</subviews>
</tableViewCellContentView>
</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"/>
<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">
@@ -244,7 +244,7 @@
</subviews>
</tableViewCellContentView>
</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"/>
<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">
@@ -268,7 +268,7 @@
</subviews>
</tableViewCellContentView>
</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"/>
<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">

View File

@@ -293,12 +293,12 @@
<scene sceneID="218-uP-X7b">
<objects>
<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"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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"/>
<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">

View File

@@ -122,59 +122,52 @@ class TVCRecordingDetails: UITableViewController, EditActionsRemove {
// 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? {
if rowToCopy == indexPath.row {
UIMenuController.shared.setMenuVisible(false, animated: true)
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.menuItems = [
.init(title: "All requests", action: #selector(openInLogs)),
// .init(title: "CoOccurrence", action: #selector(openCoOccurrence))
if noResults { return nil }
let buttons = [
UIMenuItem(title: "All requests", action: #selector(openInLogs)),
// UIMenuItem(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
}
override var canBecomeFirstResponder: Bool { true }
override func copy(_ sender: Any?) {
UIPasteboard.general.string = getDomain()
rowToCopy = Int.max
if let dom = copyDomain {
UIPasteboard.general.string = dom
}
cellMenu.reset()
copyDomain = nil
}
@objc private func openInLogs() {
guard let selectedDomain = getDomain(),
let tabBar = tabBarController as? TBCMain,
let tab = tabBar.openTab(0) as? TVCDomains else {
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
if let dom = copyDomain, let req = (tabBarController as? TBCMain)?.openTab(0) as? TVCDomains {
VCDateFilter.disableFilter()
req.pushOpen(domain: dom)
}
cellMenu.reset()
copyDomain = nil
}
// @objc private func openCoOccurrence() {
// guard let vc: VCCoOccurrence = storyboard?.load("IBCoOccurrence") else {
// return
// if let dom = copyDomain, let vc: VCCoOccurrence = storyboard?.load("IBCoOccurrence") {
// vc.domainName = dom
// vc.isFQDN = true
// present(vc, animated: true)
// }
// vc.domainName = getDomain()
// vc.isFQDN = true
// present(vc, animated: true)
// cellMenu.reset()
// copyDomain = nil
// }
}

View File

@@ -66,32 +66,24 @@ class TVCOccurrenceContext: UITableViewController {
// 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? {
if firstOrLast(indexPath.row) { return nil }
if rowToCopy == indexPath.row {
UIMenuController.shared.setMenuVisible(false, animated: true)
rowToCopy = Int.max
return nil
if cellMenu.start(tableView, indexPath) {
copyDomain = cellMenu.getSelected(dataSource)?.domain
self.becomeFirstResponder()
}
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
}
override var canBecomeFirstResponder: Bool { true }
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
action == #selector(UIResponderStandardEditActions.copy)
}
override func copy(_ sender: Any?) {
guard rowToCopy < dataSource.count else { return }
UIPasteboard.general.string = dataSource[rowToCopy].domain
rowToCopy = Int.max
if let dom = copyDomain {
UIPasteboard.general.string = dom
}
cellMenu.reset()
copyDomain = nil
}
}

View File

@@ -51,9 +51,6 @@ class TVCFilter: UITableViewController, EditActionsRemove {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DomainFilterCell")!
cell.textLabel?.text = dataSource[indexPath.row]
if cell.gestureRecognizers?.isEmpty ?? true {
cell.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(didLongTap)))
}
return cell
}
@@ -75,29 +72,24 @@ class TVCFilter: UITableViewController, EditActionsRemove {
// MARK: - Long Press Gesture
private var cellTitleCopy: String?
@objc private func didLongTap(_ sender: UILongPressGestureRecognizer) {
guard let cell = sender.view as? UITableViewCell else {
return
}
if sender.state == .began {
cellTitleCopy = cell.textLabel?.text
private var cellMenu = TableCellTapMenu()
private var copyDomain: String? = nil
override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if cellMenu.start(tableView, indexPath) {
copyDomain = cellMenu.getSelected(dataSource)
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)
}
}
override var canBecomeFirstResponder: Bool { get { true } }
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
action == #selector(UIResponderStandardEditActions.copy)
return nil
}
override var canBecomeFirstResponder: Bool { true }
override func copy(_ sender: Any?) {
UIPasteboard.general.string = cellTitleCopy
cellTitleCopy = nil
if let dom = copyDomain {
UIPasteboard.general.string = dom
}
cellMenu.reset()
copyDomain = nil
}
}