Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift 4 swipeable #1249

Closed
wants to merge 12 commits into from
4 changes: 4 additions & 0 deletions Eureka.xcodeproj/project.pbxproj
Expand Up @@ -83,6 +83,7 @@
49ADC7F91C8A83240073952B /* StepperRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49ADC7F81C8A83240073952B /* StepperRow.swift */; };
51729DF61B9A4F5E004A00EB /* Eureka.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51729DEB1B9A4F5E004A00EB /* Eureka.framework */; };
51729E671B9A5FA5004A00EB /* Eureka.h in Headers */ = {isa = PBXBuildFile; fileRef = 51729E661B9A5FA5004A00EB /* Eureka.h */; settings = {ATTRIBUTES = (Public, ); }; };
798C5ADA1EF1E35600A21F52 /* SwipeActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 798C5AD91EF1E35600A21F52 /* SwipeActions.swift */; };
8690E4BE1CFDE062004CDB1C /* Eureka.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8690E4BD1CFDE062004CDB1C /* Eureka.bundle */; };
B257FE2E1EC0F66900043911 /* RowsInsertionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B257FE2D1EC0F66900043911 /* RowsInsertionTests.swift */; };
B2A401161EC0BA140042EDF0 /* SectionsInsertionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2A401151EC0BA140042EDF0 /* SectionsInsertionTests.swift */; };
Expand Down Expand Up @@ -179,6 +180,7 @@
51729DF51B9A4F5E004A00EB /* EurekaTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EurekaTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
51729DFC1B9A4F5E004A00EB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Tests/Info.plist; sourceTree = "<group>"; };
51729E661B9A5FA5004A00EB /* Eureka.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Eureka.h; path = Source/Eureka.h; sourceTree = SOURCE_ROOT; };
798C5AD91EF1E35600A21F52 /* SwipeActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeActions.swift; sourceTree = "<group>"; };
8690E4BD1CFDE062004CDB1C /* Eureka.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Eureka.bundle; sourceTree = "<group>"; };
B257FE2D1EC0F66900043911 /* RowsInsertionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RowsInsertionTests.swift; path = Tests/RowsInsertionTests.swift; sourceTree = SOURCE_ROOT; };
B2A401151EC0BA140042EDF0 /* SectionsInsertionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SectionsInsertionTests.swift; path = Tests/SectionsInsertionTests.swift; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -225,6 +227,7 @@
28EEBFF71C7E241200300699 /* SelectableRowType.swift */,
2859CDBF1C7D138D0002982F /* Section.swift */,
2859CE231C7E141B0002982F /* SelectableSection.swift */,
798C5AD91EF1E35600A21F52 /* SwipeActions.swift */,
28EE0FDD1D5E889F00B91340 /* Validation.swift */,
);
name = Core;
Expand Down Expand Up @@ -530,6 +533,7 @@
49ADC7F91C8A83240073952B /* StepperRow.swift in Sources */,
28EE46AC1C7F712300EFF4A2 /* DateInlineRow.swift in Sources */,
28EEC01C1C7E3A7400300699 /* ButtonRowWithPresent.swift in Sources */,
798C5ADA1EF1E35600A21F52 /* SwipeActions.swift in Sources */,
28EEBFF41C7E240000300699 /* RowProtocols.swift in Sources */,
28EEBFFE1C7E281F00300699 /* CheckRow.swift in Sources */,
2859CDC41C7D19C50002982F /* HeaderFooterView.swift in Sources */,
Expand Down
20 changes: 20 additions & 0 deletions Example/Example/Base.lproj/Main.storyboard
Expand Up @@ -172,6 +172,7 @@
<segue destination="1By-iT-GXN" kind="push" identifier="ValidationsControllerSegue" id="e8a-Jy-4iL"/>
<segue destination="1Eh-Nv-AVS" kind="push" identifier="CustomDesignControllerSegue" id="qm6-xE-x5d"/>
<segue destination="qIY-1j-dNf" kind="push" identifier="MultivaluedSectionsControllerSegue" id="HjC-JK-Qvc"/>
<segue destination="fc5-sQ-cEm" kind="push" identifier="SwipeActionsControllerSegue" id="AxK-me-pi6"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Eoz-Jq-Zy9" userLabel="First Responder" sceneMemberID="firstResponder"/>
Expand Down Expand Up @@ -264,6 +265,25 @@
</objects>
<point key="canvasLocation" x="463" y="1077"/>
</scene>
<!--SwipeActions Example-->
<scene sceneID="h0m-5n-GTL">
<objects>
<viewController title="SwipeActions Example" id="fc5-sQ-cEm" customClass="SwipeActionsController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="ImV-ow-JvS"/>
<viewControllerLayoutGuide type="bottom" id="3OX-ei-O2d"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="BDe-QW-0vU">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<navigationItem key="navigationItem" id="KY1-r2-ar2"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="axy-1K-pFt" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-530" y="1833"/>
</scene>
<!--Multivalued Sections Example-->
<scene sceneID="zbo-bQ-HRw">
<objects>
Expand Down
70 changes: 62 additions & 8 deletions Example/Example/ViewController.swift
Expand Up @@ -106,14 +106,10 @@ class HomeViewController : FormViewController {
row.title = row.tag
row.presentationMode = .segueName(segueName: "MultivaluedSectionsControllerSegue", onDismiss: nil)
}


+++ Section()
<<< ButtonRow() { (row: ButtonRow) -> Void in
row.title = "About"
}
.onCellSelection { [weak self] (cell, row) in
self?.showAlert()

<<< ButtonRow("Swipe Actions") { (row: ButtonRow) -> Void in
row.title = row.tag
row.presentationMode = .segueName(segueName: "SwipeActionsControllerSegue", onDismiss: nil)
}
}

Expand Down Expand Up @@ -1747,6 +1743,64 @@ class MultivaluedOnlyDeleteController: FormViewController {
}
}

class SwipeActionsController: FormViewController {

override func viewDidLoad() {
super.viewDidLoad()

form +++ Section(footer: "Eureka sets table.isEditing = false for SwipeActions.\n\nMultivaluedSections need table.isEditing = true, therefore both can't be used on the same view.")
<<< LabelRow("Actions Right: iOS >= 7") {
$0.title = $0.tag

$0.trailingSwipeConfiguration = SwipeConfiguration() {
let moreAction = SwipeAction(style: .normal, title: "More", handler: { (action, source, completionHandler) in
print("More")
completionHandler?(true)
})

let deleteAction = SwipeAction(style: .destructive, title: "Delete", handler: { (action, source, completionHandler) in
print("Delete")
completionHandler?(true)
})

$0.actions = [deleteAction,moreAction]
}
}

<<< LabelRow("Actions Left & Right: iOS >= 11") {
$0.title = $0.tag

$0.trailingSwipeConfiguration = SwipeConfiguration() {
let moreAction = SwipeAction(style: .normal, title: "More", handler: { (action, source, completionHandler) in
print("More")
completionHandler?(true)
})

let deleteAction = SwipeAction(style: .destructive, title: "Delete", handler: { (action, source, completionHandler) in
print("Delete")
completionHandler?(true)
})

$0.performsFirstActionWithFullSwipe = true
$0.actions = [deleteAction,moreAction]
}

if #available(iOS 11,*) {
$0.leadingSwipeConfiguration = SwipeConfiguration() {
let infoAction = SwipeAction(style: .normal, title: "Info", handler: { (action, source, completionHandler) in
print("Info")
completionHandler?(true)
})
infoAction.backgroundColor = .blue

$0.performsFirstActionWithFullSwipe = true
$0.actions = [infoAction]
}
}
}
}
}

class EurekaLogoViewNib: UIView {

@IBOutlet weak var imageView: UIImageView!
Expand Down
11 changes: 11 additions & 0 deletions Source/Core/BaseRow.swift
Expand Up @@ -99,6 +99,17 @@ open class BaseRow: BaseRowType {

/// The section to which this row belongs.
public weak var section: Section?

public var trailingSwipeConfiguration: SwipeConfiguration?

//needs the accessor because if marked directly this throws "Stored properties cannot be marked potentially unavailable with '@available'"
private var _leadingSwipeConfiguration: SwipeConfiguration?

@available(iOS 11,*)
public var leadingSwipeConfiguration: SwipeConfiguration?{
get{ return self._leadingSwipeConfiguration }
set{ self._leadingSwipeConfiguration = newValue }
}

public required init(tag: String? = nil) {
self.tag = tag
Expand Down
40 changes: 32 additions & 8 deletions Source/Core/Core.swift
Expand Up @@ -462,9 +462,7 @@ open class FormViewController: UIViewController, FormViewControllerProtocol, For
tableView.dataSource = self
}
tableView.estimatedRowHeight = BaseRow.estimatedRowHeight

tableView.setEditing(true, animated: false)
tableView.allowsSelectionDuringEditing = true
tableView.allowsSelectionDuringEditing = true
}

open override func viewWillAppear(_ animated: Bool) {
Expand Down Expand Up @@ -502,6 +500,10 @@ open class FormViewController: UIViewController, FormViewControllerProtocol, For

NotificationCenter.default.addObserver(self, selector: #selector(FormViewController.keyboardWillShow(_:)), name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(FormViewController.keyboardWillHide(_:)), name: Notification.Name.UIKeyboardWillHide, object: nil)

if form.containsMultivaluedSection{
tableView.setEditing(true, animated: false)
}
}

open override func viewWillDisappear(_ animated: Bool) {
Expand Down Expand Up @@ -789,8 +791,13 @@ extension FormViewController : UITableViewDelegate {
}

open func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
guard let section = form[indexPath.section] as? MultivaluedSection else { return false }
let row = form[indexPath]
let row = form[indexPath]
if let actions = row.trailingSwipeConfiguration?.actions.count, actions > 0{
return true
} else if #available(iOS 11,*), let actions = row.leadingSwipeConfiguration?.actions.count, actions > 0{
return true
}
guard let section = form[indexPath.section] as? MultivaluedSection else { return false }
guard !row.isDisabled else { return false }
guard !(indexPath.row == section.count - 1 && section.multivaluedOptions.contains(.Insert) && section.showInsertIconInAddButton) else {
return true
Expand Down Expand Up @@ -849,12 +856,12 @@ extension FormViewController : UITableViewDelegate {
open func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
guard let section = form[sourceIndexPath.section] as? MultivaluedSection else { return sourceIndexPath }
guard sourceIndexPath.section == proposedDestinationIndexPath.section else { return sourceIndexPath }

let destRow = form[proposedDestinationIndexPath]
if destRow is BaseInlineRowType && destRow._inlineRow != nil {
return IndexPath(row: proposedDestinationIndexPath.row + (sourceIndexPath.row < proposedDestinationIndexPath.row ? 1 : -1), section:sourceIndexPath.section)
}

if proposedDestinationIndexPath.row > 0 {
let previousRow = form[IndexPath(row: proposedDestinationIndexPath.row - 1, section: proposedDestinationIndexPath.section)]
if previousRow is BaseInlineRowType && previousRow._inlineRow != nil {
Expand All @@ -871,7 +878,7 @@ extension FormViewController : UITableViewDelegate {

guard var section = form[sourceIndexPath.section] as? MultivaluedSection else { return }
if sourceIndexPath.row < section.count && destinationIndexPath.row < section.count && sourceIndexPath.row != destinationIndexPath.row {

let sourceRow = form[sourceIndexPath]
animateTableView = false
section.remove(at: sourceIndexPath.row)
Expand All @@ -884,6 +891,9 @@ extension FormViewController : UITableViewDelegate {

open func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
guard let section = form[indexPath.section] as? MultivaluedSection else {
if let actions = form[indexPath].trailingSwipeConfiguration?.actions.count, actions > 0{
return .delete
}
return .none
}
if section.multivaluedOptions.contains(.Insert) && indexPath.row == section.count - 1 {
Expand All @@ -898,6 +908,20 @@ extension FormViewController : UITableViewDelegate {
open func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return self.tableView(tableView, editingStyleForRowAt: indexPath) != .none
}

@available(iOS 11,*)
public func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
return form[indexPath].leadingSwipeConfiguration?.contextualConfiguration as? UISwipeActionsConfiguration
}

@available(iOS 11,*)
public func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
return form[indexPath].trailingSwipeConfiguration?.contextualConfiguration as? UISwipeActionsConfiguration
}

public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?{
return form[indexPath].trailingSwipeConfiguration?.contextualActions as? [UITableViewRowAction]
}
}

extension FormViewController : UITableViewDataSource {
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/Form.swift
Expand Up @@ -352,6 +352,12 @@ extension Form {
}
kvoWrapper.sections.insert(section, at: formIndex == NSNotFound ? 0 : formIndex + 1 )
}

var containsMultivaluedSection: Bool{
return kvoWrapper.sections.contains { (section) -> Bool in
return section is MultivaluedSection
}
}

func getValues(for rows: [BaseRow]) -> [String: Any?] {
return rows.reduce([String: Any?]()) {
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Section.swift
Expand Up @@ -455,7 +455,7 @@ open class MultivaluedSection: Section {
let addRow = addButtonProvider(self)
addRow.onCellSelection { cell, row in
guard let tableView = cell.formViewController()?.tableView, let indexPath = row.indexPath else { return }
cell.formViewController()?.tableView(tableView, commit: .insert, forRowAt: indexPath)
cell.formViewController()?.tableView(tableView, commit: .insert, forRowAt: indexPath)
}
self <<< addRow
}
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/SelectableSection.swift
Expand Up @@ -84,7 +84,9 @@ extension SelectableSectionType where Self: Section {
for row in rows {
if let row = row as? SelectableRow {
row.onCellSelection { [weak self] cell, row in
guard let s = self, !row.isDisabled else { return }
guard let s = self, !row.isDisabled else {
return
}
switch s.selectionType {
case .multipleSelection:
row.value = row.value == nil ? row.selectableValue : nil
Expand Down