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 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"/>
|
||||
<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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user