It is common for people to want to use the stock Mail.app on Android to be able to switch between their different accounts more quickly. Since iOS users have a lot more choice in the way they receive email, it is not uncommon for people to want to use a different email client for different accounts. Using a Scroll View with a UITableViewCell/UICollectionViewCell
If you are a mail app user, then you need to know about this. It is a simple tweak which brings swipeable UITableViewCell/UICollectionViewCell to the stock Mail.app. It works on iOS 10.1+ and is a must have for your jailbroken iOS devices.
SwipeCellKit
A scrollable UITableViewCell/UICollectionViewCell based on Mail.app stock, implemented in Swift.
O
UITableViewCell or UICollectionViewCell with :
- Actions when sliding to the left and right
- Action buttons with: text only, text + image, image only
- Haptic feedback
- Customizable transitions : Bounding, dragging and expanding
- Configurable Swipe Action Button Behavior
- Animated extension when the threshold is exceeded
- Customizable animations for extensions
- Support for UITableView and UICollectionView
- Accessibility
- Dark Mode
Background
Check out my blog post on how SwipeCellKit came to be.
Demo
Transitional styles
The transition style describes how the action buttons are expanded when the mouse is dragged.
Restriction
Shoot
Read
To order
Extension types
The extension style describes the behavior when you drag your finger across a cell that exceeds a certain threshold.
No
Selection
Destroyer
To order
Requirements
- Swift 5.0
- Xcode 10.3+ (in English)
- iOS 9.0 and up
Setting
CocoaPods (recommended)
use_frameworks !
# Latest release in CocoaPods
pod ‘SwipeCellKit’.
# Get the latest version on the development server
pod ‘SwipeCellKit’, :git => ‘https://github.com/SwipeCellKit/SwipeCellKit.git’, :branch => ‘develop’.
# If you have NOT upgraded to Xcode 11, use the latest version of Xcode 10.X compatible with Swift
pod ‘SwipeCellKit’, ‘2.6.0’.
# If you have NOT upgraded to Swift 5.0, use the latest version of Swift 4.2/Xcode 10.2
pod ‘SwipeCellKit’, ‘2.5.4’.
# If you have NOT upgraded to Swift 4.2, please use the latest version that is not compatible with Swift 4.2
pod ‘SwipeCellKit’, ‘2.4.3’.
Carthago
github SwipeCellKit/SwipeCellKit
Swift Package Manager
Dependencies: [
.package(url: https://github.com/SwipeCellKit/SwipeCellKit, from: 2.7.1)
]
Documentation
Read [docs][docsLink]. Generated by jazzy. Posted to the GitHub pages.
Use for UITableView
Set the delegate property for the SwipeTableViewCell:
override func tableView(_ tableView : UITableView, cellForRowAt indexPath : IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier : Cell) as ! SwipeTableViewCell
cell.delegate = self
return cell
}
Accept the SwipeTableViewCellDelegate protocol:
func tableView(_ tableView : UITableView, editActionsForRowAt indexPath : IndexPath, for orientation : SwipeActionsOrientation) -> [SwipeAction] ? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style : .destructive, title : Delete) { action, indexPath in
// process action, update template with delete
}
// Customize the appearance of the action
deleteAction.image = UIImage(named : delete)
return [deleteAction] }
Optionally, you can implement the editActionsOptionsForRowAt method to customize the behavior of the swipe action:
func tableView(_ tableView : UITableView, editActionsOptionsForRowAt indexPath : IndexPath, for orientation : SwipeActionsOrientation) -> SwipeOptions {
var options = SwipeOptions()
options.expansionStyle = .destructive
options.transitionStyle = .border
return options
}
For use with UICollectionView
Set the delegate property for SwipeCollectionViewCell :
override collectionView(_ collectionView : UICollectionView, cellForItemAt indexPath : IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier : Cell, for : indexPath) as ! SwipeCollectionViewCell
cell.delegate = self
return cell
}
Accept the SwipeCollectionViewCellDelegate protocol:
func collectionView(_ collectionView : UICollectionView, editActionsForItemAt indexPath : IndexPath, for orientation : SwipeActionsOrientation) -> [SwipeAction] ? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style : .destructive, title : Delete) { action, indexPath in
// process action, update template with delete
}
// Customize the appearance of the action
deleteAction.image = UIImage(named : delete)
return [deleteAction] }
Optionally, you can implement the editActionsOptionsForItemAt method to customize the behavior of the swipe action:
collectionView(_ collectionView : UICollectionView, editActionsOptionsForItemAt indexPath : IndexPath, for orientation : SwipeActionsOrientation) -> SwipeOptions {
var options = SwipeOptions()
options.expansionStyle = .destructive
options.transitionStyle = .border
return options
}
Transitions
SwipeTransitionStyle offers three built-in transition styles:
- .border : The visible action area is evenly distributed over all action buttons.
- … shoot: The visible action area is attached to a cell by drag and drop, and each action button is fully expanded when unfolded.
- Reveal: The visible action area is behind the cell pushed to the edge of the table view and expands when you drag the cell to the side.
For more information about customizing the appearance of buttons when you drag the screen, see Setting Transitions.
Transitional delegate
The transition of a SwipeAction can be observed by setting SwipeActionTransitioning to the transitionDelegate property. This allows you to see what percentage is visible and access the underlying UIButton for that SwipeAction.
Extension
Four built-in expansion styles are provided by SwipeExpansionStyle:
- .selection
- .app (e.g. Mail.app)
- .destructiveAfterFill (like Mailbox/Tweetbot)
- .filling
A lot of effort has gone into making SwipeExpansionStyle highly customizable. If these built-in styles don’t meet your needs, see Customizing Extensions for more information on creating your own styles.
The built-in extension style .fill requires manual intervention. This means that at some point during or after the call, your action handler must call SwipeAction.fulfill(style:) to trigger the fill extension. The ExpansionFulfillmentStyle provided allows the cell to be removed or reset later (possibly after a new user interaction).
The built-in .destructive and .destructiveAfterFill extension styles are configured to automatically remove rows when the action handler is called (auto-run). Removing it may require coordination with other string animations (for example, in beginUpdates and endUpdates). In this case, you can just create a custom SwipeExpansionStyle that requires manual execution to trigger the removal:
var options = SwipeTableOptions()
options.expansionStyle = .destructive(automaticallyDelete : false)
OPINION: You must call SwipeAction.fulfill(with style 🙂 at some point during/after the action handler call to trigger the delete. Do not call deleteRows directly.
let delete = SwipeAction(style : .destructive, title : nil) { action, indexPath in
// update template
self.emails.remove(at : indexPath.row)
action.fulfill(with : .delete)
}
Range
For more information on configuration, see the Advanced Features guide.
GitHub
https://github.com/SwipeCellKit/SwipeCellKit