Browse Source

update project

Marino Faggiana 6 years ago
parent
commit
fe44acc499
68 changed files with 3093 additions and 77 deletions
  1. 1 0
      Cartfile
  2. 1 0
      Cartfile.resolved
  3. 26 0
      Carthage/Checkouts/MGSwipeTableCell/.gitignore
  4. 142 0
      Carthage/Checkouts/MGSwipeTableCell/CHANGELOG.md
  5. 21 0
      Carthage/Checkouts/MGSwipeTableCell/LICENSE
  6. 13 0
      Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell.podspec
  7. 26 0
      Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/Info.plist
  8. 0 0
      Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeButton.h
  9. 23 1
      Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeButton.m
  10. 6 1
      Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeTableCell.h
  11. 164 52
      Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeTableCell.m
  12. 12 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/AppDelegate.h
  13. 52 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/AppDelegate.m
  14. 14 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/DemoViewController.h
  15. 257 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/DemoViewController.m
  16. 58 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/Images.xcassets/AppIcon.appiconset/Contents.json
  17. 51 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/Images.xcassets/LaunchImage.launchimage/Contents.json
  18. 44 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/LaunchScreen.xib
  19. 47 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/MGSwipeDemo-Info.plist
  20. 16 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/MGSwipeDemo-Prefix.pch
  21. 23 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/TestData.h
  22. 75 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/TestData.m
  23. BIN
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/background.jpg
  24. BIN
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/cat@2x.png
  25. BIN
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/check@2x.png
  26. BIN
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/fav@2x.png
  27. BIN
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/menu@2x.png
  28. 76 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/autolayout_test.storyboard
  29. 2 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/en.lproj/InfoPlist.strings
  30. 18 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/main.m
  31. 14 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/AppDelegate.h
  32. 48 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/AppDelegate.m
  33. 68 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/Images.xcassets/AppIcon.appiconset/Contents.json
  34. 89 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/Images.xcassets/LaunchImage.launchimage/Contents.json
  35. 45 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/Info.plist
  36. 25 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailTableCell.h
  37. 99 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailTableCell.m
  38. 14 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailViewController.h
  39. 316 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailViewController.m
  40. 16 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/main.m
  41. 52 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/AppDelegate.swift
  42. 41 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/Base.lproj/LaunchScreen.xib
  43. 68 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/Images.xcassets/AppIcon.appiconset/Contents.json
  44. 45 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/Info.plist
  45. 120 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/MailTableCell.swift
  46. 277 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/MailViewController.swift
  47. 2 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/ObjCBridgingHeader.h
  48. 24 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwiftTests/Info.plist
  49. 36 0
      Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwiftTests/MailAppDemoSwiftTests.swift
  50. 14 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/AppDelegate.h
  51. 48 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/AppDelegate.m
  52. 68 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/Images.xcassets/AppIcon.appiconset/Contents.json
  53. 89 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/Images.xcassets/LaunchImage.launchimage/Contents.json
  54. 47 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/Info.plist
  55. 14 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/SpotifyViewController.h
  56. 223 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/SpotifyViewController.m
  57. 16 0
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/main.m
  58. BIN
      Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/more@2x.png
  59. BIN
      Carthage/Checkouts/MGSwipeTableCell/readme-assets/3d.gif
  60. BIN
      Carthage/Checkouts/MGSwipeTableCell/readme-assets/RoundTableViewCell.png
  61. BIN
      Carthage/Checkouts/MGSwipeTableCell/readme-assets/border.gif
  62. BIN
      Carthage/Checkouts/MGSwipeTableCell/readme-assets/clip.gif
  63. BIN
      Carthage/Checkouts/MGSwipeTableCell/readme-assets/drag.gif
  64. BIN
      Carthage/Checkouts/MGSwipeTableCell/readme-assets/static.gif
  65. 5 20
      Nextcloud.xcodeproj/project.pbxproj
  66. 0 1
      iOSClient/Favorites/CCFavorites.h
  67. 1 1
      iOSClient/Main/CCMain.h
  68. 1 1
      iOSClient/Main/Cell/CCCellMain.h

+ 1 - 0
Cartfile

@@ -2,3 +2,4 @@ github "tilltue/TLPhotoPicker"
 github "kishikawakatsumi/UICKeyChainStore"
 github "danielsaidi/Sheeeeeeeeet"
 github "sgr-ksmt/PDFGenerator" ~> 2.1
+github "MortimerGoro/MGSwipeTableCell"

+ 1 - 0
Cartfile.resolved

@@ -1,3 +1,4 @@
+github "MortimerGoro/MGSwipeTableCell" "1.6.7"
 github "danielsaidi/Sheeeeeeeeet" "1.0.1"
 github "kishikawakatsumi/UICKeyChainStore" "v2.1.2"
 github "sgr-ksmt/PDFGenerator" "2.1"

+ 26 - 0
Carthage/Checkouts/MGSwipeTableCell/.gitignore

@@ -0,0 +1,26 @@
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+
+# CocoaPods
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
+#
+# Pods/

+ 142 - 0
Carthage/Checkouts/MGSwipeTableCell/CHANGELOG.md

@@ -0,0 +1,142 @@
+# Changelog
+
+## 1.6.7
+
+- Fix quality loss in snapshot image.
+- Got rid from Block implicitly warning.
+
+## 1.6.6
+
+- Improve notch code to better handle edge cases like orientation changes while swiping.
+- Correctly handle safeAreaInsets for RTL language.
+- Add allowsButtonWithDifferentWidth property to MGSwipeSettings and deprecate the one in MGSwipeTableCell.
+
+## 1.6.5
+
+- Expand the first or last button width to make appearance look good with a notch (e.g. iPhone X).
+- Add expandLastButtonBySafeAreaInsets property to optionally enable/disable the default behaviour.
+
+## 1.6.4
+
+- Backwards compatibility with XCode 8 compilation
+
+## 1.6.2
+
+- Handle iOS 11 safeAreaInsets.
+- Fix issue #302: Right Buttons are covered iPhone X when landscape.
+- Use availability checks for Objective-C to remove some warings in XCode 9.
+
+## 1.6.1
+
+- Fix issue #294: iOS 11 crash.
+
+## 1.6.0
+
+- Fix glitch when dragging before animation completes.
+- Fix cell separator overlap when swiping.
+- Add buttonsDistance property to MGSwipeSettings: allows to control distance between the buttons.
+- Add MGSwipeExpansionLayoutNone type that allows not to performont button layout in expansions.
+- Improved AppExtension and RTL language support.
+- Improved Swift interoperation.
+
+## 1.5.6
+
+- Improve iOS 10.0 support
+- Objective-C nullable annotations to improve Swift 3.0 interoperation. Add Swift 3.0 sample.
+- Improve accesibility implementation to allow recording UI Tests
+- Add preprocessor macro to allow compilations on App Extension projects
+- Add swipeBounceRate property. Coefficient applied to cell movement in bounce zone
+- Fix issue #216: Crash when combining programmatically created offset animations in consecutive block callbacks
+- Fix issue #139: Accessing Buttons in UITests does not work
+- Fix issue #134: Crash due to zombie object in expansion
+- Fix button text alignment for RTL languages
+
+## 1.5.5
+
+- Fix iOS 8.0 compatibility issue
+- Fix issue #190: duplicate callback
+
+## 1.5.4
+
+- Safer animation and callbacks checks after a cell is deleted. Fixes issue #91 caused by a null cell.indexPath because the callback was called while/after a cell is deleted
+- Fix issue #168: problem with devices that read right to left (Arabic and Hebrew)
+- Fix swipe issues after reloading a table
+- Fix issue #163: Swipe not working after deleting a cell
+- Add enableSwipeBounces property. Enabled by default, if disabled the swipe bounces will be disabled and the swipe motion will stop right after the button.
+- Add allowsOppositeSwipe property. Controls whether swipe gesture is allowed in opposite directions. NO value disables swiping in opposite direction once started in one direction
+- Add topMargin and bottomMargin properties to MGSwipeSettings
+- Add touchOnDismissSwipe property. Controls whether dismissing a swiped cell when clicking outside of the cell generates a real touch event on the other cell. Default behaviour is the same as the Mail app on iOS. Enable it if you want to allow to start a new swipe while a cell is already in swiped.
+- Add a 'BOOL finished' parameter to completion animation callbacks
+
+## 1.5.3
+
+- Fix duplicated callbacks with reused button instances among many cells
+- Fix Carthage header for normal projects
+
+## 1.5.2
+
+- Add Carthage support
+- Fix issues #160 and #162: Delegate call multiple time on single touch on iOS 9
+- Fix programmatic call to setSwipeOffset when swipeView is not yet created
+- Fix Swipe backgroundColor change without re-initializing the cell
+- Fix UITableCellSelectionStyle on end swipe
+- centerIconOverText now takes a spacing argument
+
+## 1.5.1
+
+- Fix default animation values
+
+## 1.5.0
+
+- Feature: Add predefined and configurable easing functions to the API. Swipe animations are now splitted into different settings so you can now use different animations (easing function, duration, etc) for each kind of animations: show swipe, hide swipe, stretch cell from already swiped buttons and more.
+- Feature: Full support for Spotify App like swipe animations. Create new Spotify Demo project.
+- Feature: add onlySwipeButtons property that allows to only swipe the buttons and keep the cell content static
+- Feature: add fromOffset argument to the canSwipe delegate method. Useful for supporting sidebar menus with swipe to open. You can use it to restrict the cell from being swiped if the offset is to close to the edge.
+- Feature: add preservesSelectionStatus property that allows to control whether selection/highlight is changed when swiped.
+- Feature: add keepButtonsSwiped property to Swipe settings
+- Feature: new delegate method: shouldHideSwipeOnTap:(CGPoint) point. Now you can cancel to hide opened swipe depending on the tap point
+- Feature: new delegate methods: swipeTableCellWillBeginSwiping & swipeTableCellWillEndSwiping. Useful to make cell changes that only are shown after the cell is swiped open
+- Fixed issue #113: Bug when changing the orientation of the device
+- Fixed typo throughout readme and source of "swiping"
+- Fixed issue #100: canSwipe not working when swipe to the allowed direction and swipe with inertia to the forbidden direction
+- Fixed clip mask when animating expansion
+- Keep expansion color while expansion is animating to 0
+
+
+## 1.4.3
+
+- Fixed crash with different class cells in multiple section tables
+- Add completion handlers to convenience show/hide methods
+
+## 1.4.2
+
+- Fixed issue #89: Swipe fails after table reload while swipping gesture is active
+
+## 1.4.1
+
+- Implemented Spotify App style cell expansion: added expansionLayout and expansionColor properties to MGSwipeExpansionSettings
+- New property allowsSwipeWhenTappingButtons. Fixed issue #80: swiping the cell when you swipe the buttons in the cell
+- Fixed issue #78: Swift problem with one enum
+- Fixed issue #82: fillOnTrigger not working properly with UITableViewCellAccessoryDisclosureIndicator
+- Fixed issue #84: can't compile in xcode 6.3
+- Fixed issue #76: Swiped cell state issue when table view is scrolling
+
+## 1.4.0
+
+- Implemented allowsButtonsWithDifferentWidth property to support buttons with different widths
+- Implemented allowsMultipleSwipe feature 
+- Allow starting swiping on one cell while another one is open 
+- Keep cell's selection state when swipe is closed
+- Fixed flash of the cell in its default state before the cell is deleted when fillOnTrigger is set.
+- Improved MGSwipeButton. New utility methods to Center image over text, set edge insets, set a fixed with and more.
+- Other minor bugfixes
+
+## 1.3.6
+
+- Improved gestureRecognizer ending detection. Fixed issue #50: Not able to swipe to reveal right after scrolling collection view children of cell content view
+- Fixed the white background issue when the cell.backgroundColor is set to UIColor.clearColor
+- Added utility method to perform swipe expansions programmatically
+
+## 1.3.5
+
+- Fixed issue #43: Two Cell Can Swipe simultaneously

+ 21 - 0
Carthage/Checkouts/MGSwipeTableCell/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Imanol Fernandez @MortimerGoro
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 13 - 0
Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell.podspec

@@ -0,0 +1,13 @@
+Pod::Spec.new do |s|
+  s.name     = 'MGSwipeTableCell'
+  s.version  = '1.6.7'
+  s.author   = { 'Imanol Fernandez' => 'mortimergoro@gmail.com' }
+  s.homepage = 'https://github.com/MortimerGoro/MGSwipeTableCell'
+  s.summary  = 'An easy to use UITableViewCell subclass that allows to display swipeable buttons with a variety of transitions'
+  s.license  = 'MIT'
+  s.source   = { :git => 'https://github.com/MortimerGoro/MGSwipeTableCell.git', :tag => s.version.to_s }
+  s.source_files = 'MGSwipeTableCell'
+  s.platform = :ios
+  s.ios.deployment_target = '7.0'
+  s.requires_arc = true
+end

+ 26 - 0
Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/Info.plist

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>$(CURRENT_PROJECT_VERSION)</string>
+	<key>NSPrincipalClass</key>
+	<string></string>
+</dict>
+</plist>

+ 0 - 0
Libraries external/MGSwipeTableCell/MGSwipeButton.h → Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeButton.h


+ 23 - 1
Libraries external/MGSwipeTableCell/MGSwipeButton.m → Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeButton.m

@@ -94,7 +94,7 @@
 -(void) centerIconOverTextWithSpacing: (CGFloat) spacing {
   CGSize size = self.imageView.image.size;
   
-  if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0 && [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
+  if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0 && [self isRTLLocale]) {
     self.titleEdgeInsets = UIEdgeInsetsMake(0.0,
                                             0.0,
                                             -(size.height + spacing),
@@ -156,4 +156,26 @@
     self.tintColor = tintColor;
 }
 
+- (BOOL)isAppExtension
+{
+    return [[NSBundle mainBundle].executablePath rangeOfString:@".appex/"].location != NSNotFound;
+}
+
+-(BOOL) isRTLLocale
+{
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+    if (@available(iOS 9, *)) {
+#else
+    if ([[UIView class] respondsToSelector:@selector(userInterfaceLayoutDirectionForSemanticContentAttribute:)]) {
+#endif
+        return [UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft;
+    }
+    else if ([self isAppExtension]) {
+        return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
+    } else {
+        UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
+        return application.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft;
+    }
+}
+
 @end

+ 6 - 1
Libraries external/MGSwipeTableCell/MGSwipeTableCell.h → Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeTableCell.h

@@ -88,6 +88,8 @@ typedef NS_ENUM(NSInteger, MGSwipeEasingFunction) {
 @property (nonatomic, assign) CGFloat bottomMargin;
 /** Distance between the buttons. Default value : 0 */
 @property (nonatomic, assign) CGFloat buttonsDistance;
+/** If true, expands the last button length by safeAreaInsets. Useful for devices with a notch (e.g. iPhone X) */
+@property (nonatomic, assign) BOOL expandLastButtonBySafeAreaInsets;
 
 /** Animation settings when the swipe buttons are shown */
 @property (nonatomic, strong, nonnull) MGSwipeAnimation * showAnimation;
@@ -114,6 +116,9 @@ typedef NS_ENUM(NSInteger, MGSwipeEasingFunction) {
     to make the cell 'resist' swiping after buttons are revealed. Default is 1.0 */
 @property (nonatomic, assign) CGFloat swipeBounceRate;
 
+// default is NO. Controls whether buttons with different width are allowed. Buttons are resized to have the same size by default.
+@property (nonatomic) BOOL allowsButtonsWithDifferentWidth;
+
 @end
 
 
@@ -239,7 +244,7 @@ typedef NS_ENUM(NSInteger, MGSwipeEasingFunction) {
 // default is NO. Controls whether multiple cells can be swiped simultaneously
 @property (nonatomic) BOOL allowsMultipleSwipe;
 // default is NO. Controls whether buttons with different width are allowed. Buttons are resized to have the same size by default.
-@property (nonatomic) BOOL allowsButtonsWithDifferentWidth;
+@property (nonatomic) BOOL allowsButtonsWithDifferentWidth DEPRECATED_MSG_ATTRIBUTE("Use MGSwipeSettings.allowsButtonsWithDifferentWidth instead");
 //default is YES. Controls whether swipe gesture is allowed when the touch starts into the swiped buttons
 @property (nonatomic) BOOL allowsSwipeWhenTappingButtons;
 //default is YES. Controls whether swipe gesture is allowed in opposite directions. NO value disables swiping in opposite direction once started in one direction

+ 164 - 52
Libraries external/MGSwipeTableCell/MGSwipeTableCell.m → Carthage/Checkouts/MGSwipeTableCell/MGSwipeTableCell/MGSwipeTableCell.m

@@ -64,34 +64,38 @@
     UIView * _expansionBackground;
     UIView * _expansionBackgroundAnimated;
     CGRect _expandedButtonBoundsCopy;
+    MGSwipeDirection _direction;
     MGSwipeExpansionLayout _expansionLayout;
     CGFloat _expansionOffset;
     CGFloat _buttonsDistance;
+    CGFloat _safeInset;
     BOOL _autoHideExpansion;
 }
 
 #pragma mark Layout
 
--(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction differentWidth:(BOOL) differentWidth buttonsDistance:(CGFloat) buttonsDistance
+-(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction swipeSettings:(MGSwipeSettings*) settings safeInset: (CGFloat) safeInset
 {
     CGFloat containerWidth = 0;
     CGSize maxSize = CGSizeZero;
     UIView* lastButton = [buttonsArray lastObject];
     for (UIView * button in buttonsArray) {
-        containerWidth += button.bounds.size.width + (lastButton == button ? 0 : buttonsDistance);
+        containerWidth += button.bounds.size.width + (lastButton == button ? 0 : settings.buttonsDistance);
         maxSize.width = MAX(maxSize.width, button.bounds.size.width);
         maxSize.height = MAX(maxSize.height, button.bounds.size.height);
     }
-    if (!differentWidth) {
-        containerWidth = maxSize.width * buttonsArray.count + buttonsDistance * (buttonsArray.count - 1);
+    if (!settings.allowsButtonsWithDifferentWidth) {
+        containerWidth = maxSize.width * buttonsArray.count + settings.buttonsDistance * (buttonsArray.count - 1);
     }
     
-    if (self = [super initWithFrame:CGRectMake(0, 0, containerWidth, maxSize.height)]) {
+    if (self = [super initWithFrame:CGRectMake(0, 0, containerWidth + safeInset, maxSize.height)]) {
         _fromLeft = direction == MGSwipeDirectionLeftToRight;
-        _buttonsDistance = buttonsDistance;
+        _buttonsDistance = settings.buttonsDistance;
         _container = [[UIView alloc] initWithFrame:self.bounds];
         _container.clipsToBounds = YES;
         _container.backgroundColor = [UIColor clearColor];
+        _direction = direction;
+        _safeInset = safeInset;
         [self addSubview:_container];
         _buttons = _fromLeft ? buttonsArray: [[buttonsArray reverseObjectEnumerator] allObjects];
         for (UIView * button in _buttons) {
@@ -100,12 +104,18 @@
                 [btn removeTarget:nil action:@selector(mgButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; //Remove all targets to avoid problems with reused buttons among many cells
                 [btn addTarget:self action:@selector(mgButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
             }
-            if (!differentWidth) {
+            if (!settings.allowsButtonsWithDifferentWidth) {
                 button.frame = CGRectMake(0, 0, maxSize.width, maxSize.height);
             }
             button.autoresizingMask = UIViewAutoresizingFlexibleHeight;
             [_container insertSubview:button atIndex: _fromLeft ? 0: _container.subviews.count];
         }
+        // Expand last button to make it look good with a notch.
+        if (safeInset > 0 && settings.expandLastButtonBySafeAreaInsets && _buttons.count > 0) {
+            UIView * notchButton = _direction == MGSwipeDirectionRightToLeft ? [_buttons lastObject] : [_buttons firstObject];
+            notchButton.frame = CGRectMake(0, 0, notchButton.frame.size.width + safeInset, notchButton.frame.size.height);
+            [self adjustContentEdge:notchButton edgeDelta:safeInset];
+        }
         [self resetButtons];
     }
     return self;
@@ -131,6 +141,51 @@
     }
 }
 
+-(void) setSafeInset:(CGFloat)safeInset extendEdgeButton:(BOOL) extendEdgeButton isRTL: (BOOL) isRTL {
+    CGFloat diff = safeInset - _safeInset;
+    if (diff != 0) {
+        _safeInset = safeInset;
+        // Adjust last button length (fit the safeInset to make it look good with a notch)
+        if (extendEdgeButton) {
+            UIView * edgeButton = _direction == MGSwipeDirectionRightToLeft ? [_buttons lastObject] : [_buttons firstObject];
+            edgeButton.frame = CGRectMake(0, 0, edgeButton.bounds.size.width + diff, edgeButton.frame.size.height);
+            // Adjust last button content edge (to correctly align the text/icon)
+            [self adjustContentEdge:edgeButton edgeDelta:diff];
+        }
+
+        CGRect frame = self.frame;
+        CGAffineTransform transform = self.transform;
+        self.transform = CGAffineTransformIdentity;
+        // Adjust container width
+        frame.size.width += diff;
+        // Adjust position to match width and safeInsets chages
+        if (_direction == MGSwipeDirectionLeftToRight) {
+            frame.origin.x = -frame.size.width + safeInset * (isRTL ? 1 : -1);
+        }
+        else {
+            frame.origin.x = self.superview.bounds.size.width + safeInset * (isRTL ? 1 : -1);
+        }
+        
+        self.frame = frame;
+        self.transform = transform;
+        [self resetButtons];
+    }
+}
+
+-(void) adjustContentEdge: (UIView *) view edgeDelta:(CGFloat) delta {
+    if ([view isKindOfClass:[UIButton class]]) {
+        UIButton * btn = (UIButton *) view;
+        UIEdgeInsets contentInsets = btn.contentEdgeInsets;
+        if (_direction == MGSwipeDirectionRightToLeft) {
+            contentInsets.right += delta;
+        }
+        else {
+            contentInsets.left += delta;
+        }
+        btn.contentEdgeInsets = contentInsets;
+    }
+}
+
 -(void) layoutExpansion: (CGFloat) offset
 {
     _expansionOffset = offset;
@@ -198,30 +253,30 @@
         
         CGFloat duration = _fromLeft ? _cell.leftExpansion.animationDuration : _cell.rightExpansion.animationDuration;
         [UIView animateWithDuration: duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
-            _expandedButton.hidden = NO;
-
-            if (_expansionLayout == MGSwipeExpansionLayoutCenter) {
-                _expandedButtonBoundsCopy = _expandedButton.bounds;
-                _expandedButton.layer.mask = nil;
-                _expandedButton.layer.transform = CATransform3DIdentity;
-                _expandedButton.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
-                [_expandedButton.superview bringSubviewToFront:_expandedButton];
-                _expandedButton.frame = _container.bounds;
-                _expansionBackground.frame = [self expansionBackgroundRect:_expandedButton];
+            self->_expandedButton.hidden = NO;
+
+            if (self->_expansionLayout == MGSwipeExpansionLayoutCenter) {
+                self->_expandedButtonBoundsCopy = self->_expandedButton.bounds;
+                self->_expandedButton.layer.mask = nil;
+                self->_expandedButton.layer.transform = CATransform3DIdentity;
+                self->_expandedButton.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
+                [self->_expandedButton.superview bringSubviewToFront:self->_expandedButton];
+                self->_expandedButton.frame = self->_container.bounds;
+                self->_expansionBackground.frame = [self expansionBackgroundRect:self->_expandedButton];
             }
-            else if (_expansionLayout == MGSwipeExpansionLayoutNone) {
-                [_expandedButton.superview bringSubviewToFront:_expandedButton];
-                _expansionBackground.frame = _container.bounds;
+            else if (self->_expansionLayout == MGSwipeExpansionLayoutNone) {
+                [self->_expandedButton.superview bringSubviewToFront:self->_expandedButton];
+                self->_expansionBackground.frame = self->_container.bounds;
             }
-            else if (_fromLeft) {
-                _expandedButton.frame = CGRectMake(_container.bounds.size.width - _expandedButton.bounds.size.width, 0, _expandedButton.bounds.size.width, _expandedButton.bounds.size.height);
-                _expandedButton.autoresizingMask|= UIViewAutoresizingFlexibleLeftMargin;
-                _expansionBackground.frame = [self expansionBackgroundRect:_expandedButton];
+            else if (self->_fromLeft) {
+                self->_expandedButton.frame = CGRectMake(self->_container.bounds.size.width - self->_expandedButton.bounds.size.width, 0, self->_expandedButton.bounds.size.width, self->_expandedButton.bounds.size.height);
+                self->_expandedButton.autoresizingMask|= UIViewAutoresizingFlexibleLeftMargin;
+                self->_expansionBackground.frame = [self expansionBackgroundRect:self->_expandedButton];
             }
             else {
-                _expandedButton.frame = CGRectMake(0, 0, _expandedButton.bounds.size.width, _expandedButton.bounds.size.height);
-                _expandedButton.autoresizingMask|= UIViewAutoresizingFlexibleRightMargin;
-                _expansionBackground.frame = [self expansionBackgroundRect:_expandedButton];
+                self->_expandedButton.frame = CGRectMake(0, 0, self->_expandedButton.bounds.size.width, self->_expandedButton.bounds.size.height);
+                self->_expandedButton.autoresizingMask|= UIViewAutoresizingFlexibleRightMargin;
+                self->_expansionBackground.frame = [self expansionBackgroundRect:self->_expandedButton];
             }
 
         } completion:^(BOOL finished) {
@@ -248,14 +303,14 @@
         }
         CGFloat duration = _fromLeft ? _cell.leftExpansion.animationDuration : _cell.rightExpansion.animationDuration;
         [UIView animateWithDuration: animated ? duration : 0.0 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
-            _container.frame = self.bounds;
-            if (_expansionLayout == MGSwipeExpansionLayoutCenter) {
-                _expandedButtonAnimated.frame = _expandedButtonBoundsCopy;
+            self->_container.frame = self.bounds;
+            if (self->_expansionLayout == MGSwipeExpansionLayoutCenter) {
+                self->_expandedButtonAnimated.frame = self->_expandedButtonBoundsCopy;
             }
             [self resetButtons];
-            _expansionBackgroundAnimated.frame = [self expansionBackgroundRect:_expandedButtonAnimated];
+            self->_expansionBackgroundAnimated.frame = [self expansionBackgroundRect:self->_expandedButtonAnimated];
         } completion:^(BOOL finished) {
-            [_expansionBackgroundAnimated removeFromSuperview];
+            [self->_expansionBackgroundAnimated removeFromSuperview];
         }];
     }
     else if (_expansionBackground) {
@@ -406,6 +461,7 @@
         self.transition = MGSwipeTransitionBorder;
         self.threshold = 0.5;
         self.offset = 0;
+        self.expandLastButtonBySafeAreaInsets = YES;
         self.keepButtonsSwiped = YES;
         self.enableSwipeBounces = YES;
         self.swipeBounceRate = 1.0;
@@ -564,7 +620,6 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
 
     MGSwipeTableInputOverlay * _tableInputOverlay;
     bool _overlayEnabled;
-    __weak UITableView * _cachedParentTable;
     UITableViewCellSelectionStyle _previusSelectionStyle;
     NSMutableSet * _previusHiddenViews;
     BOOL _triggerStateChanges;
@@ -651,18 +706,27 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
     }
 }
 
+- (BOOL)isAppExtension
+{
+    return [[NSBundle mainBundle].executablePath rangeOfString:@".appex/"].location != NSNotFound;
+}
+
+
 -(BOOL) isRTLLocale
 {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+    if (@available(iOS 9, *)) {
+#else
     if ([[UIView class] respondsToSelector:@selector(userInterfaceLayoutDirectionForSemanticContentAttribute:)]) {
+#endif
         return [UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft;
     }
-#ifndef TARGET_IS_EXTENSION
-    else {
-        return [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft;
+    else if ([self isAppExtension]) {
+        return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
+    } else {
+        UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
+        return application.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft;
     }
-#else
-    return NO;
-#endif
 }
 
 -(void) fixRegionAndAccesoryViews
@@ -673,6 +737,19 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
     }
 }
 
+-(UIEdgeInsets) getSafeInsets {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+    if (@available(iOS 11, *)) {
+        return self.safeAreaInsets;
+    }
+    else {
+        return UIEdgeInsetsZero;
+    }
+#else
+    return UIEdgeInsetsZero;
+#endif
+}
+
 -(UIView *) swipeContentView
 {
     if (!_swipeContentView) {
@@ -696,6 +773,25 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
         _swipeOverlay.frame = CGRectMake(0, 0, self.bounds.size.width, self.contentView.bounds.size.height);
         [self fixRegionAndAccesoryViews];
         if (_swipeView.image &&  !CGSizeEqualToSize(prevSize, _swipeOverlay.bounds.size)) {
+            //refresh safeInsets in situations like layout change, orientation change, table resize, etc.
+            UIEdgeInsets safeInsets = [self getSafeInsets];
+            // Refresh safe insets
+            if (_leftView) {
+                CGFloat width = _leftView.bounds.size.width;
+                [_leftView setSafeInset:safeInsets.left extendEdgeButton:_leftSwipeSettings.expandLastButtonBySafeAreaInsets isRTL: [self isRTLLocale]];
+                if (_swipeOffset > 0 && _leftView.bounds.size.width != width) {
+                    // Adapt offset to the view change size due to safeInsets
+                    _swipeOffset += _leftView.bounds.size.width - width;
+                }
+            }
+            if (_rightView) {
+                CGFloat width = _rightView.bounds.size.width;
+                [_rightView setSafeInset:safeInsets.right extendEdgeButton:_rightSwipeSettings.expandLastButtonBySafeAreaInsets isRTL: [self isRTLLocale]];
+                if (_swipeOffset < 0 && _rightView.bounds.size.width != width) {
+                    // Adapt offset to the view change size due to safeInsets
+                    _swipeOffset -= _rightView.bounds.size.width - width;
+                }
+            }
             //refresh contentView in situations like layout change, orientation chage, table resize, etc.
             [self refreshContentView];
         }
@@ -714,6 +810,7 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
 
 -(void) createSwipeViewIfNeeded
 {
+    UIEdgeInsets safeInsets = [self getSafeInsets];
     if (!_swipeOverlay) {
         _swipeOverlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.contentView.bounds.size.height)];
         [self fixRegionAndAccesoryViews];
@@ -730,19 +827,36 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
     
     [self fetchButtonsIfNeeded];
     if (!_leftView && _leftButtons.count > 0) {
-        _leftView = [[MGSwipeButtonsView alloc] initWithButtons:_leftButtons direction:MGSwipeDirectionLeftToRight differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_leftSwipeSettings.buttonsDistance];
+        _leftSwipeSettings.allowsButtonsWithDifferentWidth = _leftSwipeSettings.allowsButtonsWithDifferentWidth || _allowsButtonsWithDifferentWidth;
+        _leftView = [[MGSwipeButtonsView alloc] initWithButtons:_leftButtons direction:MGSwipeDirectionLeftToRight swipeSettings:_leftSwipeSettings safeInset:safeInsets.left];
         _leftView.cell = self;
-        _leftView.frame = CGRectMake(-_leftView.bounds.size.width, _leftSwipeSettings.topMargin, _leftView.bounds.size.width, _swipeOverlay.bounds.size.height - _leftSwipeSettings.topMargin - _leftSwipeSettings.bottomMargin);
+        _leftView.frame = CGRectMake(-_leftView.bounds.size.width + safeInsets.left * ([self isRTLLocale] ? 1 : -1),
+                                     _leftSwipeSettings.topMargin,
+                                     _leftView.bounds.size.width,
+                                     _swipeOverlay.bounds.size.height - _leftSwipeSettings.topMargin - _leftSwipeSettings.bottomMargin);
         _leftView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
         [_swipeOverlay addSubview:_leftView];
     }
     if (!_rightView && _rightButtons.count > 0) {
-        _rightView = [[MGSwipeButtonsView alloc] initWithButtons:_rightButtons direction:MGSwipeDirectionRightToLeft differentWidth:_allowsButtonsWithDifferentWidth buttonsDistance:_rightSwipeSettings.buttonsDistance];
+        _rightSwipeSettings.allowsButtonsWithDifferentWidth = _rightSwipeSettings.allowsButtonsWithDifferentWidth || _allowsButtonsWithDifferentWidth;
+        _rightView = [[MGSwipeButtonsView alloc] initWithButtons:_rightButtons direction:MGSwipeDirectionRightToLeft swipeSettings:_rightSwipeSettings safeInset:safeInsets.right];
         _rightView.cell = self;
-        _rightView.frame = CGRectMake(_swipeOverlay.bounds.size.width, _rightSwipeSettings.topMargin, _rightView.bounds.size.width, _swipeOverlay.bounds.size.height - _rightSwipeSettings.topMargin - _rightSwipeSettings.bottomMargin);
+        _rightView.frame = CGRectMake(_swipeOverlay.bounds.size.width + safeInsets.right * ([self isRTLLocale] ? 1 : -1),
+                                      _rightSwipeSettings.topMargin,
+                                      _rightView.bounds.size.width,
+                                      _swipeOverlay.bounds.size.height - _rightSwipeSettings.topMargin - _rightSwipeSettings.bottomMargin);
         _rightView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
         [_swipeOverlay addSubview:_rightView];
     }
+    
+    // Refresh safeInsets if required
+    if (_leftView) {
+        [_leftView setSafeInset:safeInsets.left extendEdgeButton:_leftSwipeSettings.expandLastButtonBySafeAreaInsets isRTL: [self isRTLLocale]];
+    }
+    
+    if (_rightView) {
+        [_rightView setSafeInset:safeInsets.right extendEdgeButton:_rightSwipeSettings.expandLastButtonBySafeAreaInsets isRTL: [self isRTLLocale]];
+    }
 }
 
 
@@ -912,8 +1026,8 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
 #pragma mark Some utility methods
 
 - (UIImage *)imageFromView:(UIView *)view cropSize:(CGSize)cropSize{
-    UIGraphicsBeginImageContextWithOptions(cropSize, NO, [[UIScreen mainScreen] scale]);
-    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
+    UIGraphicsBeginImageContextWithOptions(cropSize, NO, 0);
+    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
     UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     return image;
@@ -962,18 +1076,14 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
 
 -(UITableView *) parentTable
 {
-    if (_cachedParentTable) {
-        return _cachedParentTable;
-    }
-    
     UIView * view = self.superview;
     while(view != nil) {
         if([view isKindOfClass:[UITableView class]]) {
-            _cachedParentTable = (UITableView*) view;
+            return (UITableView*) view;
         }
         view = view.superview;
     }
-    return _cachedParentTable;
+    return nil;
 }
 
 -(void) updateState: (MGSwipeState) newState;
@@ -1029,7 +1139,9 @@ static inline CGFloat mgEaseInOutBounce(CGFloat t, CGFloat b, CGFloat c) {
     }
     
     BOOL onlyButtons = activeSettings.onlySwipeButtons;
-    _swipeView.transform = CGAffineTransformMakeTranslation(onlyButtons ? 0 : _swipeOffset, 0);
+    UIEdgeInsets safeInsets = [self getSafeInsets];
+    CGFloat safeInset = [self isRTLLocale] ? safeInsets.right :  -safeInsets.left;
+    _swipeView.transform = CGAffineTransformMakeTranslation(safeInset + (onlyButtons ? 0 : _swipeOffset), 0);
     
     //animate existing buttons
     MGSwipeButtonsView* but[2] = {_leftView, _rightView};

+ 12 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/AppDelegate.h

@@ -0,0 +1,12 @@
+/*
+ * MGSwipeTableCell is licensed under MIT licensed. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end

+ 52 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/AppDelegate.m

@@ -0,0 +1,52 @@
+/*
+ * MGSwipeTableCell is licensed under MIT licensed. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "AppDelegate.h"
+#import "DemoViewController.h"
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+    
+    DemoViewController * vc = [[DemoViewController alloc] init];
+    UINavigationController * navigation = [[UINavigationController alloc] initWithRootViewController:vc];
+    navigation.navigationBar.translucent = NO;
+    self.window.rootViewController = navigation;
+    
+    self.window.backgroundColor = [UIColor whiteColor];
+    [self.window makeKeyAndVisible];
+    return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
+    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end

+ 14 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/DemoViewController.h

@@ -0,0 +1,14 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <UIKit/UIKit.h>
+#import "MGSwipeTableCell.h"
+
+@interface DemoViewController : UIViewController<UITableViewDataSource, UITableViewDelegate, MGSwipeTableCellDelegate, UIActionSheetDelegate>
+
+@property (nonatomic, assign) BOOL testingStoryboardCell;
+@property (strong, nonatomic) IBOutlet UITableView *tableView;
+
+@end

+ 257 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/DemoViewController.m

@@ -0,0 +1,257 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "DemoViewController.h"
+#import "TestData.h"
+#import "MGSwipeButton.h"
+
+#define TEST_USE_MG_DELEGATE 1
+
+@implementation DemoViewController
+{
+    NSMutableArray * tests;
+    UIBarButtonItem * prevButton;
+    UITableViewCellAccessoryType accessory;
+    UIImageView * background; //used for transparency test
+    BOOL allowMultipleSwipe;
+}
+
+
+-(void) cancelTableEditClick: (id) sender
+{
+    [_tableView setEditing: NO animated: YES];
+    self.navigationItem.rightBarButtonItem = prevButton;
+    prevButton = nil;
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    if (buttonIndex == actionSheet.cancelButtonIndex) {
+        return;
+    }
+    
+    if (buttonIndex == 1) {
+        tests = [TestData data];
+        [_tableView reloadData];
+    }
+    else if (buttonIndex == 2) {
+        _tableView.allowsMultipleSelectionDuringEditing = YES;
+        [_tableView setEditing: YES animated: YES];
+        prevButton = self.navigationItem.rightBarButtonItem;
+        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStyleDone target:self action:@selector(cancelTableEditClick:)];
+    }
+    else if (buttonIndex == 3) {
+        accessory++;
+        if (accessory >=4) {
+            accessory = 0;
+        }
+        [_tableView reloadData];
+    }
+    else if (buttonIndex == 4) {
+        if (background) {
+            [background removeFromSuperview];
+            _tableView.backgroundColor = [UIColor whiteColor];
+        }
+        else {
+            background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.jpg"]];
+            background.frame = self.view.bounds;
+            background.contentMode = UIViewContentModeScaleToFill;
+            background.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+            [self.view insertSubview:background belowSubview:_tableView];
+            _tableView.backgroundColor = [UIColor clearColor];
+        }
+        [_tableView reloadData];
+    }
+    else if (buttonIndex == 5) {
+        allowMultipleSwipe = !allowMultipleSwipe;
+        [_tableView reloadData];
+    }
+    else {
+        UIStoryboard *sb = [UIStoryboard storyboardWithName:@"autolayout_test" bundle:nil];
+        DemoViewController *vc = [sb instantiateInitialViewController];
+        vc.testingStoryboardCell = YES;
+        [self.navigationController pushViewController:vc animated:YES];
+    }
+}
+
+-(void) actionClick: (id) sender
+{
+    
+    UIActionSheet * sheet = [[UIActionSheet alloc] initWithTitle:@"Select action" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles: nil];
+    [sheet addButtonWithTitle:@"Reload test"];
+    [sheet addButtonWithTitle:@"Multiselect test"];
+    [sheet addButtonWithTitle:@"Change accessory button"];
+    [sheet addButtonWithTitle:@"Transparency test"];
+    [sheet addButtonWithTitle: allowMultipleSwipe ?  @"Single Swipe" : @"Multiple Swipe"];
+    if (!_testingStoryboardCell) {
+        [sheet addButtonWithTitle:@"Storyboard test"];
+    }
+    [sheet showInView:self.view];
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    
+    tests = [TestData data];
+    self.title = @"MGSwipeCell";
+    
+    if (!_testingStoryboardCell) {
+        _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
+        _tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+        _tableView.dataSource = self;
+        _tableView.delegate = self;
+        [self.view addSubview:_tableView];
+    }
+    
+    self.navigationItem.rightBarButtonItem =  [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(actionClick:)];
+}
+
+
+-(NSArray *) createLeftButtons: (int) number
+{
+    NSMutableArray * result = [NSMutableArray array];
+    UIColor * colors[3] = {[UIColor greenColor],
+        [UIColor colorWithRed:0 green:0x99/255.0 blue:0xcc/255.0 alpha:1.0],
+        [UIColor colorWithRed:0.59 green:0.29 blue:0.08 alpha:1.0]};
+    UIImage * icons[3] = {[UIImage imageNamed:@"check.png"], [UIImage imageNamed:@"fav.png"], [UIImage imageNamed:@"menu.png"]};
+    for (int i = 0; i < number; ++i)
+    {
+        MGSwipeButton * button = [MGSwipeButton buttonWithTitle:@"" icon:icons[i] backgroundColor:colors[i] padding:15 callback:^BOOL(MGSwipeTableCell * sender){
+            NSLog(@"Convenience callback received (left).");
+            return YES;
+        }];
+        [result addObject:button];
+    }
+    return result;
+}
+
+
+-(NSArray *) createRightButtons: (int) number
+{
+    NSMutableArray * result = [NSMutableArray array];
+    NSString* titles[2] = {@"Delete", @"More"};
+    UIColor * colors[2] = {[UIColor redColor], [UIColor lightGrayColor]};
+    for (int i = 0; i < number; ++i)
+    {
+        MGSwipeButton * button = [MGSwipeButton buttonWithTitle:titles[i] backgroundColor:colors[i] callback:^BOOL(MGSwipeTableCell * sender){
+            NSLog(@"Convenience callback received (right).");
+            BOOL autoHide = i != 0;
+            return autoHide; //Don't autohide in delete button to improve delete expansion animation
+        }];
+        [result addObject:button];
+    }
+    return result;
+}
+
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
+{
+    return tests.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    MGSwipeTableCell * cell;
+    
+    if (_testingStoryboardCell) {
+        /**
+         * Test using storyboard and prototype cell that uses autolayout
+         **/
+        cell = [_tableView dequeueReusableCellWithIdentifier:@"prototypeCell"];
+    }
+    else {
+        /**
+         * Test using programmatically created cells
+         **/
+        static NSString * reuseIdentifier = @"programmaticCell";
+        cell = [_tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
+        if (!cell) {
+            cell = [[MGSwipeTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
+        }
+    }
+    
+    TestData * data = [tests objectAtIndex:indexPath.row];
+    
+    cell.textLabel.text = data.title;
+    cell.textLabel.font = [UIFont systemFontOfSize:16];
+    cell.detailTextLabel.text = data.detailTitle;
+    cell.accessoryType = accessory;
+    cell.delegate = self;
+    cell.allowsMultipleSwipe = allowMultipleSwipe;
+    
+    if (background) { //transparency test
+        cell.backgroundColor = [UIColor clearColor];
+        cell.selectedBackgroundView = [[UIView alloc] init];
+        cell.selectedBackgroundView.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:0.3];
+        cell.contentView.backgroundColor = [UIColor clearColor];
+        cell.swipeBackgroundColor = [UIColor clearColor];
+        cell.textLabel.textColor = [UIColor yellowColor];
+        cell.detailTextLabel.textColor = [UIColor yellowColor];
+    }
+
+#if !TEST_USE_MG_DELEGATE
+    cell.leftSwipeSettings.transition = data.transition;
+    cell.rightSwipeSettings.transition = data.transition;
+    cell.leftExpansion.buttonIndex = data.leftExpandableIndex;
+    cell.leftExpansion.fillOnTrigger = NO;
+    cell.rightExpansion.buttonIndex = data.rightExpandableIndex;
+    cell.rightExpansion.fillOnTrigger = YES;
+    cell.leftButtons = [self createLeftButtons:data.leftButtonsCount];
+    cell.rightButtons = [self createRightButtons:data.rightButtonsCount];
+#endif
+    
+    return cell;
+}
+
+#if TEST_USE_MG_DELEGATE
+-(NSArray*) swipeTableCell:(MGSwipeTableCell*) cell swipeButtonsForDirection:(MGSwipeDirection)direction
+             swipeSettings:(MGSwipeSettings*) swipeSettings expansionSettings:(MGSwipeExpansionSettings*) expansionSettings;
+{
+    TestData * data = [tests objectAtIndex:[_tableView indexPathForCell:cell].row];
+    swipeSettings.transition = data.transition;
+    
+    if (direction == MGSwipeDirectionLeftToRight) {
+        expansionSettings.buttonIndex = data.leftExpandableIndex;
+        expansionSettings.fillOnTrigger = NO;
+        return [self createLeftButtons:data.leftButtonsCount];
+    }
+    else {
+        expansionSettings.buttonIndex = data.rightExpandableIndex;
+        expansionSettings.fillOnTrigger = YES;
+        return [self createRightButtons:data.rightButtonsCount];
+    }
+}
+#endif
+
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    return 60;
+}
+
+-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion
+{
+    NSLog(@"Delegate: button tapped, %@ position, index %d, from Expansion: %@",
+          direction == MGSwipeDirectionLeftToRight ? @"left" : @"right", (int)index, fromExpansion ? @"YES" : @"NO");
+    
+    if (direction == MGSwipeDirectionRightToLeft && index == 0) {
+        //delete button
+        NSIndexPath * path = [_tableView indexPathForCell:cell];
+        [tests removeObjectAtIndex:path.row];
+        [_tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
+        return NO; //Don't autohide to improve delete expansion animation
+    }
+    
+    return YES;
+}
+
+-(void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
+{
+    NSLog(@"Tapped accessory button");
+}
+
+@end

+ 58 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,58 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 51 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/Images.xcassets/LaunchImage.launchimage/Contents.json

@@ -0,0 +1,51 @@
+{
+  "images" : [
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "subtype" : "retina4",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "full-screen",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 44 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/LaunchScreen.xib

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2015 Imanol Fernandez Gorostizaga. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
+                    <rect key="frame" x="20" y="439" width="441" height="21"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                    <nil key="highlightedColor"/>
+                    <variation key="widthClass=compact">
+                        <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                    </variation>
+                </label>
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MGSwipeDemo" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
+                    <rect key="frame" x="20" y="140" width="441" height="43"/>
+                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+            <constraints>
+                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="Kid-kn-2rF"/>
+                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
+                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
+                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
+                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
+                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
+            </constraints>
+            <nil key="simulatedStatusBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="404" y="445"/>
+        </view>
+    </objects>
+</document>

+ 47 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/MGSwipeDemo-Info.plist

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>

+ 16 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/MGSwipeDemo-Prefix.pch

@@ -0,0 +1,16 @@
+//
+//  Prefix header
+//
+//  The contents of this file are implicitly included at the beginning of every source file.
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_3_0
+#warning "This project uses features only available in iOS SDK 3.0 and later."
+#endif
+
+#ifdef __OBJC__
+    #import <UIKit/UIKit.h>
+    #import <Foundation/Foundation.h>
+#endif

+ 23 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/TestData.h

@@ -0,0 +1,23 @@
+/*
+ * MGSwipeTableCell is licensed under MIT licensed. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "MGSwipeTableCell.h"
+
+@interface TestData : NSObject
+
+@property (nonatomic) MGSwipeTransition transition;
+@property (nonatomic) int leftButtonsCount;
+@property (nonatomic) int rightButtonsCount;
+@property (nonatomic) int leftExpandableIndex;
+@property (nonatomic) int rightExpandableIndex;
+
+
+-(NSString *) title;
+-(NSString *) detailTitle;
+
++(NSMutableArray*) data;
+
+
+@end

+ 75 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/TestData.m

@@ -0,0 +1,75 @@
+/*
+ * MGSwipeTableCell is licensed under MIT licensed. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "TestData.h"
+#import "MGSwipeButton.h"
+
+@implementation TestData
+
+
+-(NSString *) title
+{
+    NSString * modeTitle;
+    switch (_transition) {
+        case MGSwipeTransition3D: modeTitle = @"3D"; break;
+        case MGSwipeTransitionClipCenter: modeTitle = @"clip"; break;
+        case MGSwipeTransitionDrag: modeTitle = @"drag"; break;
+        case MGSwipeTransitionBorder: modeTitle = @"border"; break;
+        case MGSwipeTransitionStatic: modeTitle = @"static";break;
+    }
+    modeTitle = [NSString stringWithFormat:@"%@ transition", modeTitle];
+    NSString * buttons;
+    if (_leftButtonsCount <= 0 && _rightButtonsCount <= 0) {
+        return @"No buttons";
+    }
+    else if (_leftButtonsCount > 0 && _rightButtonsCount > 0) {
+        buttons = [NSString stringWithFormat:@"%d left, %d right", _leftButtonsCount, _rightButtonsCount];
+    }
+    else if (_leftButtonsCount > 0) {
+        buttons = [NSString stringWithFormat:@"%d left", _leftButtonsCount];
+    }
+    else {
+        buttons = [NSString stringWithFormat:@"%d right", _rightButtonsCount];
+    }
+    
+    return [NSString stringWithFormat:@"%@, %@", buttons, modeTitle];
+}
+
+-(NSString *) detailTitle
+{
+    return _leftExpandableIndex >=0 || _rightExpandableIndex >= 0 ? @"Expandable" : @"Not expandable";
+}
+
+
++(NSMutableArray *) data
+{
+    NSMutableArray * tests = [NSMutableArray array];
+    
+    MGSwipeTransition transitions[] = {MGSwipeTransitionBorder, MGSwipeTransitionStatic, MGSwipeTransitionClipCenter, MGSwipeTransitionDrag, MGSwipeTransition3D};
+    int numTransitions = sizeof(transitions)/sizeof(MGSwipeTransition);
+    
+    int buttonCombinations[] = {3,2, 2,1, 0,2, 2,0};
+    int numCombinations = sizeof(buttonCombinations) / (sizeof(int) * 2);
+    
+    int expansionCombinations[] = {-1, -1,  0, 0};
+    int numExpansions = sizeof(expansionCombinations)/ (sizeof(int) * 2);
+    
+    for (int i = 0; i < numCombinations; ++i) {
+        for (int j = 0; j < numTransitions; ++j) {
+            for (int z = 0; z < numExpansions; ++z) {
+                TestData * data = [[TestData alloc] init];
+                data.leftButtonsCount = buttonCombinations[2 * i];
+                data.rightButtonsCount = buttonCombinations[2 * i + 1];
+                data.transition = transitions[j];
+                data.leftExpandableIndex =  data.leftButtonsCount ? expansionCombinations[2 * z] : -1;
+                data.rightExpandableIndex = data.rightButtonsCount ? expansionCombinations[2 * z + 1] : -1;
+                [tests addObject:data];
+            }
+        }
+    }
+    return tests;
+}
+
+@end

BIN
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/background.jpg


BIN
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/cat@2x.png


BIN
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/check@2x.png


BIN
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/fav@2x.png


BIN
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/assets/menu@2x.png


+ 76 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/autolayout_test.storyboard

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13189.4" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="obU-ao-dp2">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment version="1792" identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13165.3"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Demo View Controller-->
+        <scene sceneID="RzA-6l-jmH">
+            <objects>
+                <viewController id="obU-ao-dp2" customClass="DemoViewController" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="e1m-rV-Rw8"/>
+                        <viewControllerLayoutGuide type="bottom" id="gW7-Px-uIu"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="iVC-tC-ekG">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="Icz-Ez-2qz">
+                                <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                                <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <prototypes>
+                                    <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="prototypeCell" id="jfa-oN-DSo" customClass="MGSwipeTableCell">
+                                        <rect key="frame" x="0.0" y="22" width="375" height="44"/>
+                                        <autoresizingMask key="autoresizingMask"/>
+                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jfa-oN-DSo" id="RQ7-Fg-6FO">
+                                            <rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                            <subviews>
+                                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cat.png" translatesAutoresizingMaskIntoConstraints="NO" id="O4J-Sj-TY1">
+                                                    <rect key="frame" x="320" y="5" width="50" height="33"/>
+                                                    <constraints>
+                                                        <constraint firstAttribute="width" constant="50" id="daW-gL-ohF"/>
+                                                    </constraints>
+                                                </imageView>
+                                            </subviews>
+                                            <constraints>
+                                                <constraint firstItem="O4J-Sj-TY1" firstAttribute="top" secondItem="RQ7-Fg-6FO" secondAttribute="top" constant="5" id="3Zu-DA-YOR"/>
+                                                <constraint firstAttribute="bottom" secondItem="O4J-Sj-TY1" secondAttribute="bottom" constant="5" id="Q2G-mI-5px"/>
+                                                <constraint firstAttribute="trailing" secondItem="O4J-Sj-TY1" secondAttribute="trailing" constant="5" id="ysY-dn-d6d"/>
+                                            </constraints>
+                                        </tableViewCellContentView>
+                                    </tableViewCell>
+                                </prototypes>
+                                <connections>
+                                    <outlet property="dataSource" destination="obU-ao-dp2" id="JOX-nm-3T6"/>
+                                    <outlet property="delegate" destination="obU-ao-dp2" id="LiV-OP-8qX"/>
+                                </connections>
+                            </tableView>
+                        </subviews>
+                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="trailing" secondItem="Icz-Ez-2qz" secondAttribute="trailing" id="6Nz-7o-Ccb"/>
+                            <constraint firstItem="Icz-Ez-2qz" firstAttribute="top" secondItem="iVC-tC-ekG" secondAttribute="top" id="ALD-sU-fMf"/>
+                            <constraint firstItem="gW7-Px-uIu" firstAttribute="top" secondItem="Icz-Ez-2qz" secondAttribute="bottom" id="T3Z-fm-eYh"/>
+                            <constraint firstItem="Icz-Ez-2qz" firstAttribute="leading" secondItem="iVC-tC-ekG" secondAttribute="leading" id="Vxd-vE-2Uo"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="tableView" destination="Icz-Ez-2qz" id="B0t-eF-mMH"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="dKY-xM-hks" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="712" y="157"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="cat.png" width="128" height="128"/>
+    </resources>
+</document>

+ 2 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/en.lproj/InfoPlist.strings

@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+

+ 18 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MGSwipeDemo/MGSwipeDemo/main.m

@@ -0,0 +1,18 @@
+//
+//  main.m
+//  MGSwipeDemo
+//
+//  Created by Imanol Fernandez Gorostizag on 09/08/14.
+//  Copyright (c) 2014 Imanol Fernandez Gorostizaga. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[])
+{
+    @autoreleasepool {
+        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+    }
+}

+ 14 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/AppDelegate.h

@@ -0,0 +1,14 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+

+ 48 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/AppDelegate.m

@@ -0,0 +1,48 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "AppDelegate.h"
+#import "MailViewController.h"
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+
+    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+    
+    MailViewController * vc = [[MailViewController alloc] init];
+    UINavigationController * navigation = [[UINavigationController alloc] initWithRootViewController:vc];
+    navigation.navigationBar.translucent = NO;
+    self.window.rootViewController = navigation;
+    
+    self.window.backgroundColor = [UIColor whiteColor];
+    [self.window makeKeyAndVisible];
+    return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end

+ 68 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 89 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/Images.xcassets/LaunchImage.launchimage/Contents.json

@@ -0,0 +1,89 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "scale" : "1x",
+      "orientation" : "portrait"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "2x",
+      "orientation" : "portrait"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "subtype" : "retina4",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "minimum-system-version" : "7.0",
+      "subtype" : "retina4",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 45 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/Info.plist

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>

+ 25 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailTableCell.h

@@ -0,0 +1,25 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <Foundation/Foundation.h>
+#import "MGSwipeTableCell.h"
+
+
+@interface MailIndicatorView : UIView
+@property (nonatomic, strong) UIColor * indicatorColor;
+@property (nonatomic, strong) UIColor * innerColor;
+@end
+
+@interface MailTableCell : MGSwipeTableCell
+
+@property (nonatomic, strong) UILabel * mailFrom;
+@property (nonatomic, strong) UILabel * mailSubject;
+@property (nonatomic, strong) UITextView * mailMessage;
+@property (nonatomic, strong) UILabel * mailTime;
+@property (nonatomic, strong) MailIndicatorView * indicatorView;
+
+-(instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
+
+@end

+ 99 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailTableCell.m

@@ -0,0 +1,99 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "MailTableCell.h"
+
+@implementation MailIndicatorView
+
+-(void) drawRect:(CGRect)rect
+{
+    CGContextRef ctx = UIGraphicsGetCurrentContext();
+    CGContextAddEllipseInRect(ctx, rect);
+    CGContextSetFillColor(ctx, CGColorGetComponents(_indicatorColor.CGColor));
+    CGContextFillPath(ctx);
+    
+    if (_innerColor) {
+        CGFloat innerSize = rect.size.width * 0.5;
+        CGRect innerRect = CGRectMake(rect.origin.x + rect.size.width * 0.5 - innerSize * 0.5,
+                                      rect.origin.y + rect.size.height * 0.5 - innerSize * 0.5,
+                                      innerSize, innerSize);
+        CGContextAddEllipseInRect(ctx, innerRect);
+        CGContextSetFillColor(ctx, CGColorGetComponents(_innerColor.CGColor));
+        CGContextFillPath(ctx);
+    }
+}
+
+-(void) setIndicatorColor:(UIColor *)indicatorColor
+{
+    _indicatorColor = indicatorColor;
+    [self setNeedsDisplay];
+}
+
+-(void) setInnerColor:(UIColor *)innerColor
+{
+    _innerColor = innerColor;
+    [self setNeedsDisplay];
+}
+
+@end
+
+@implementation MailTableCell
+
+-(instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
+{
+    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
+        _mailFrom = [[UILabel alloc] initWithFrame:CGRectZero];
+        _mailMessage = [[UITextView alloc] initWithFrame:CGRectZero];
+        _mailSubject = [[UILabel alloc] initWithFrame:CGRectZero];
+        _mailTime = [[UILabel alloc] initWithFrame:CGRectZero];
+        
+        _mailFrom.font = [UIFont fontWithName:@"HelveticaNeue" size:18.0f];
+        _mailSubject.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:15.0f];
+        _mailMessage.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14.0f];
+        _mailTime.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:13.0f];
+        
+        _mailMessage.scrollEnabled = NO;
+        _mailMessage.editable = NO;
+        _mailMessage.backgroundColor = [UIColor clearColor];
+        _mailMessage.contentInset = UIEdgeInsetsMake(-5, -5, 0, 0);
+        _mailMessage.textColor = [UIColor grayColor];
+        _mailMessage.userInteractionEnabled = NO;
+        
+        _indicatorView = [[MailIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
+        _indicatorView.backgroundColor = [UIColor clearColor];
+        
+        [self.contentView addSubview:_mailFrom];
+        [self.contentView addSubview:_mailMessage];
+        [self.contentView addSubview:_mailSubject];
+        [self.contentView addSubview:_mailTime];
+        [self.contentView addSubview:_indicatorView];
+    }
+    return self;
+}
+
+-(void) layoutSubviews
+{
+    [super layoutSubviews];
+    
+    CGFloat leftPadding = 25.0;
+    CGFloat topPadding = 3.0;
+    CGFloat textWidth = self.contentView.bounds.size.width - leftPadding * 2;
+    CGFloat dateWidth = 40;
+    
+    _mailFrom.frame = CGRectMake(leftPadding, topPadding, textWidth, 20);
+    _mailSubject.frame = CGRectMake(leftPadding, _mailFrom.frame.origin.y + _mailFrom.frame.size.height + topPadding, textWidth - dateWidth, 17);
+    CGFloat messageHeight = self.contentView.bounds.size.height - (_mailSubject.frame.origin.y + _mailSubject.frame.size.height) - topPadding * 2;
+    _mailMessage.frame = CGRectMake(leftPadding, _mailSubject.frame.origin.y + _mailSubject.frame.size.height + topPadding, textWidth, messageHeight);
+    
+    CGRect frame = _mailFrom.frame;
+    frame.origin.x = self.contentView.frame.size.width - leftPadding - dateWidth;
+    frame.size.width = dateWidth;
+    _mailTime.frame = frame;
+    
+    _indicatorView.center = CGPointMake(leftPadding * 0.5, _mailFrom.frame.origin.y + _mailFrom.frame.size.height * 0.5);
+
+}
+
+@end

+ 14 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailViewController.h

@@ -0,0 +1,14 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <UIKit/UIKit.h>
+#import "MGSwipeTableCell.h"
+
+@interface MailViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, MGSwipeTableCellDelegate, UIActionSheetDelegate>
+
+@property (nonatomic, strong) UITableView * tableView;
+
+@end
+

+ 316 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/MailViewController.m

@@ -0,0 +1,316 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "MailViewController.h"
+#import "MailTableCell.h"
+#import "MGSwipeButton.h"
+
+
+@interface MailData : NSObject
+@property (nonatomic, strong) NSString * from;
+@property (nonatomic, strong) NSString * subject;
+@property (nonatomic, strong) NSString * message;
+@property (nonatomic, strong) NSString * date;
+@property (nonatomic, assign) BOOL read;
+@property (nonatomic, assign) BOOL flag;
+
+@end
+
+@implementation MailData
+@end
+
+
+typedef void(^MailActionCallback)(BOOL cancelled, BOOL deleted, NSInteger actionIndex);
+
+@implementation MailViewController
+{
+    NSMutableArray * demoData;
+    MailActionCallback actionCallback;
+    UIRefreshControl * refreshControl;
+}
+
+
+-(void) prepareDemoData
+{
+    demoData = [NSMutableArray array];
+    
+    NSArray * from = @[
+                       @"Vincent",
+                       @"Mr Glass",
+                       @"Marsellus",
+                       @"Ringo",
+                       @"Sullivan",
+                       @"Mr Wolf",
+                       @"Butch Coolidge",
+                       @"Marvin",
+                       @"Captain Koons",
+                       @"Jules",
+                       @"Jimmie Dimmick"
+                       ];
+    
+    NSArray * subjects = @[
+                           @"You think water moves fast?",
+                           @"They called me Mr Glass",
+                           @"The path of the righteous man",
+                           @"Do you see any Teletubbies in here?",
+                           @"Now that we know who you are",
+                           @"My money's in that office, right?",
+                           @"Now we took an oath",
+                           @"That show's called a pilot",
+                           @"I know who I am. I'm not a mistake",
+                           @"It all makes sense!",
+                           @"The selfish and the tyranny of evil men",
+                           ];
+    
+    NSArray * messages = @[
+                           @"You should see ice. It moves like it has a mind. Like it knows it killed the world once and got a taste for murder. After the avalanche, it took us a week to climb out.",
+                           @"And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy My brothers.",
+                           @"Look, just because I don't be givin' no man a foot massage don't make it right for Marsellus to throw Antwone into a glass motherfuckin' house",
+                           @"No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb.",
+                           @"In a comic, you know how you can tell who the arch-villain's going to be? He's the exact opposite of the hero",
+                           @"If she start giving me some bullshit about it ain't there, and we got to go someplace else and get it, I'm gonna shoot you in the head then and there.",
+                           @"that I'm breaking now. We said we'd say it was the snow that killed the other two, but it wasn't. Nature is lethal but it doesn't hold a candle to man.",
+                           @"Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows.",
+                           @"And most times they're friends, like you and me! I should've known way back when...",
+                           @"After the avalanche, it took us a week to climb out. Now, I don't know exactly when we turned on each other, but I know that seven of us survived the slide",
+                           @"Blessed is he who, in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children",
+                           ];
+    
+    
+    for (int i = 0; i < messages.count; ++i) {
+        MailData * mail = [[MailData alloc] init];
+        mail.from = [from objectAtIndex:i];
+        mail.subject = [subjects objectAtIndex:i];
+        mail.message = [messages objectAtIndex:i];
+        mail.date = [NSString stringWithFormat:@"11:%d", 43 - i];
+        [demoData addObject:mail];
+    }
+    
+}
+
+-(void) refreshCallback
+{
+    [self prepareDemoData];
+    [_tableView reloadData];
+    [refreshControl endRefreshing];
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
+    _tableView.delegate = self;
+    _tableView.dataSource = self;
+    [self.view addSubview:_tableView];
+    
+    self.title = @"MSwipeTableCell MailApp";
+    
+    refreshControl = [[UIRefreshControl alloc] init];
+    [refreshControl addTarget:self action:@selector(refreshCallback) forControlEvents:UIControlEventValueChanged];
+    [self.tableView addSubview:refreshControl];
+    
+    [self prepareDemoData];
+}
+
+-(void) viewDidAppear:(BOOL)animated
+{
+    [self.tableView reloadData];
+}
+
+-(void) viewWillLayoutSubviews
+{
+    [super viewWillLayoutSubviews];
+    _tableView.frame = self.view.bounds;
+}
+
+-(void) deleteMail:(NSIndexPath *) indexPath
+{
+    [demoData removeObjectAtIndex:indexPath.row];
+    [_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
+}
+
+-(MailData *) mailForIndexPath:(NSIndexPath*) path
+{
+    return [demoData objectAtIndex:path.row];
+}
+
+-(void) updateCellIndicactor:(MailData *) mail cell:(MailTableCell*) cell
+{
+    UIColor * color;
+    UIColor * innerColor;
+    if (!mail.read && mail.flag) {
+        color = [UIColor colorWithRed:1.0 green:149/255.0 blue:0.05 alpha:1.0];
+        innerColor = [UIColor colorWithRed:0 green:122/255.0 blue:1.0 alpha:1.0];
+    }
+    else if (mail.flag) {
+        color = [UIColor colorWithRed:1.0 green:149/255.0 blue:0.05 alpha:1.0];
+    }
+    else if (mail.read) {
+        color = [UIColor clearColor];
+    }
+    else {
+        color = [UIColor colorWithRed:0 green:122/255.0 blue:1.0 alpha:1.0];
+    }
+    
+    cell.indicatorView.indicatorColor = color;
+    cell.indicatorView.innerColor = innerColor;
+}
+
+-(void) showMailActions:(MailData *) mail callback:(MailActionCallback) callback
+{
+    actionCallback = callback;
+    UIActionSheet * sheet = [[UIActionSheet alloc] initWithTitle:@"Actions" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Trash" otherButtonTitles:mail.read ? @"Mark as unread": @"Mark as read", @"Flag", nil];
+    [sheet showInView:self.view];
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    actionCallback(buttonIndex == actionSheet.cancelButtonIndex, buttonIndex == actionSheet.destructiveButtonIndex, buttonIndex);
+    actionCallback = nil;
+}
+
+-(NSString *) readButtonText:(BOOL) read
+{
+    return read ? @"Mark as\nunread" :@"Mark as\nread";
+}
+
+
+#pragma mark Table Delegate
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    return demoData.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    static NSString * identifier = @"MailCell";
+    MailTableCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
+    if (!cell) {
+        cell = [[MailTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
+    }
+    cell.delegate = self;
+    
+    MailData * data = [demoData objectAtIndex:indexPath.row];
+    cell.mailFrom.text = data.from;
+    cell.mailSubject.text = data.subject;
+    cell.mailMessage.text = data.message;
+    cell.mailTime.text = data.date;
+    [self updateCellIndicactor:data cell:cell];
+    return cell;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    return 110;
+}
+
+#pragma mark Swipe Delegate
+
+-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell canSwipe:(MGSwipeDirection) direction;
+{
+    return YES;
+}
+
+-(NSArray*) swipeTableCell:(MGSwipeTableCell*) cell swipeButtonsForDirection:(MGSwipeDirection)direction
+             swipeSettings:(MGSwipeSettings*) swipeSettings expansionSettings:(MGSwipeExpansionSettings*) expansionSettings
+{
+    
+    swipeSettings.transition = MGSwipeTransitionBorder;
+    expansionSettings.buttonIndex = 0;
+    
+    __weak MailViewController * me = self;
+    MailData * mail = [me mailForIndexPath:[self.tableView indexPathForCell:cell]];
+    
+    if (direction == MGSwipeDirectionLeftToRight) {
+        
+        expansionSettings.fillOnTrigger = NO;
+        expansionSettings.threshold = 2;
+        return @[[MGSwipeButton buttonWithTitle:[me readButtonText:mail.read] backgroundColor:[UIColor colorWithRed:0 green:122/255.0 blue:1.0 alpha:1.0] padding:5 callback:^BOOL(MGSwipeTableCell *sender) {
+            
+            MailData * mail = [me mailForIndexPath:[me.tableView indexPathForCell:sender]];
+            mail.read = !mail.read;
+            [me updateCellIndicactor:mail cell:(MailTableCell*)sender];
+            [cell refreshContentView]; //needed to refresh cell contents while swipping
+            
+            //change button text
+            [(UIButton*)[cell.leftButtons objectAtIndex:0] setTitle:[me readButtonText:mail.read] forState:UIControlStateNormal];
+            
+            return YES;
+        }]];
+    }
+    else {
+        
+        expansionSettings.fillOnTrigger = YES;
+        expansionSettings.threshold = 1.1;
+
+        CGFloat padding = 15;
+        
+        MGSwipeButton * trash = [MGSwipeButton buttonWithTitle:@"Trash" backgroundColor:[UIColor colorWithRed:1.0 green:59/255.0 blue:50/255.0 alpha:1.0] padding:padding callback:^BOOL(MGSwipeTableCell *sender) {
+            
+            NSIndexPath * indexPath = [me.tableView indexPathForCell:sender];
+            [me deleteMail:indexPath];
+            return NO; //don't autohide to improve delete animation
+        }];
+        MGSwipeButton * flag = [MGSwipeButton buttonWithTitle:@"Flag" backgroundColor:[UIColor colorWithRed:1.0 green:149/255.0 blue:0.05 alpha:1.0] padding:padding callback:^BOOL(MGSwipeTableCell *sender) {
+            
+            MailData * mail = [me mailForIndexPath:[me.tableView indexPathForCell:sender]];
+            mail.flag = !mail.flag;
+            [me updateCellIndicactor:mail cell:(MailTableCell*)sender];
+            [cell refreshContentView]; //needed to refresh cell contents while swipping
+            return YES;
+        }];
+        MGSwipeButton * more = [MGSwipeButton buttonWithTitle:@"More" backgroundColor:[UIColor colorWithRed:200/255.0 green:200/255.0 blue:205/255.0 alpha:1.0] padding:padding callback:^BOOL(MGSwipeTableCell *sender) {
+            
+            NSIndexPath * indexPath = [me.tableView indexPathForCell:sender];
+            MailData * mail = [me mailForIndexPath:indexPath];
+            MailTableCell * cell = (MailTableCell*) sender;
+            [me showMailActions:mail callback:^(BOOL cancelled, BOOL deleted, NSInteger actionIndex) {
+                if (cancelled) {
+                    return;
+                }
+                if (deleted) {
+                    [me deleteMail:indexPath];
+                }
+                else if (actionIndex == 1) {
+                    mail.read = !mail.read;
+                    [(UIButton*)[cell.leftButtons objectAtIndex:0] setTitle:[me readButtonText:mail.read] forState:UIControlStateNormal];
+                    [me updateCellIndicactor:mail cell:cell];
+                    [cell refreshContentView]; //needed to refresh cell contents while swipping
+                }
+                else if (actionIndex == 2) {
+                    mail.flag = !mail.flag;
+                    [me updateCellIndicactor:mail cell:cell];
+                    [cell refreshContentView]; //needed to refresh cell contents while swipping
+                }
+                
+                [cell hideSwipeAnimated:YES];
+                
+            }];
+            
+            return NO; //avoid autohide swipe
+        }];
+        
+        return @[trash, flag, more];
+    }
+    
+    return nil;
+    
+}
+
+-(void) swipeTableCell:(MGSwipeTableCell*) cell didChangeSwipeState:(MGSwipeState)state gestureIsActive:(BOOL)gestureIsActive
+{
+    NSString * str;
+    switch (state) {
+        case MGSwipeStateNone: str = @"None"; break;
+        case MGSwipeStateSwippingLeftToRight: str = @"SwippingLeftToRight"; break;
+        case MGSwipeStateSwippingRightToLeft: str = @"SwippingRightToLeft"; break;
+        case MGSwipeStateExpandingLeftToRight: str = @"ExpandingLeftToRight"; break;
+        case MGSwipeStateExpandingRightToLeft: str = @"ExpandingRightToLeft"; break;
+    }
+    NSLog(@"Swipe state: %@ ::: Gesture: %@", str, gestureIsActive ? @"Active" : @"Ended");
+}
+
+@end

+ 16 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemo/MailAppDemo/main.m

@@ -0,0 +1,16 @@
+//
+//  main.m
+//  MailAppDemo
+//
+//  Created by Imanol Fernandez Gorostizaga on 26/09/14.
+//  Copyright (c) 2014 Mortimer. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+    @autoreleasepool {
+        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+    }
+}

+ 52 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/AppDelegate.swift

@@ -0,0 +1,52 @@
+//
+//  AppDelegate.swift
+//  MailAppDemoSwift
+//
+
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+    var window: UIWindow?
+
+
+    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+        
+        window = UIWindow(frame: UIScreen.main.bounds);
+        let controller = MailViewController();
+        let navigation = UINavigationController(rootViewController: controller);
+        window?.rootViewController = navigation;
+        window?.backgroundColor = UIColor.white;
+        window?.makeKeyAndVisible();
+        
+
+        // Override point for customization after application launch.
+        return true
+    }
+
+    func applicationWillResignActive(_ application: UIApplication) {
+        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+    }
+
+    func applicationDidEnterBackground(_ application: UIApplication) {
+        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+    }
+
+    func applicationWillEnterForeground(_ application: UIApplication) {
+        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+    }
+
+    func applicationDidBecomeActive(_ application: UIApplication) {
+        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+    }
+
+    func applicationWillTerminate(_ application: UIApplication) {
+        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+    }
+
+
+}
+

+ 41 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/Base.lproj/LaunchScreen.xib

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
+        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
+            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <subviews>
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2014 Imanol Fernandez. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
+                    <rect key="frame" x="20" y="439" width="441" height="21"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MailAppDemoSwift" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
+                    <rect key="frame" x="20" y="140" width="441" height="43"/>
+                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
+                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                    <nil key="highlightedColor"/>
+                </label>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+            <constraints>
+                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
+                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
+                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
+                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
+                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
+                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
+            </constraints>
+            <nil key="simulatedStatusBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="548" y="455"/>
+        </view>
+    </objects>
+</document>

+ 68 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 45 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/Info.plist

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>mortimergoro.$(PRODUCT_NAME:rfc1034identifier)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>

+ 120 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/MailTableCell.swift

@@ -0,0 +1,120 @@
+//
+//  MailTableCell.swift
+//  MailAppDemoSwift
+//
+
+import UIKit
+
+class MailIndicatorView: UIView {
+    
+    var indicatorColor : UIColor {
+        didSet {
+            self.setNeedsDisplay();
+        }
+    }
+    var innerColor : UIColor? {
+        didSet {
+            self.setNeedsDisplay();
+        }
+    }
+    
+    override init(frame:CGRect) {
+        indicatorColor = UIColor.clear;
+        super.init(frame:frame);
+    }
+
+    required init?(coder aDecoder: NSCoder) {
+        indicatorColor = UIColor.clear;
+        super.init(coder: aDecoder);
+    }
+    
+    override func draw(_ rect: CGRect) {
+        let ctx = UIGraphicsGetCurrentContext();
+        ctx?.addEllipse(in: rect);
+        ctx?.setFillColor(indicatorColor.cgColor.components!);
+        ctx?.fillPath();
+        
+        if innerColor != nil {
+            let innerSize = rect.size.width * 0.5;
+            let innerRect = CGRect(x: rect.origin.x + rect.size.width * 0.5 - innerSize * 0.5,
+                y: rect.origin.y + rect.size.height * 0.5 - innerSize * 0.5,
+                width: innerSize, height: innerSize);
+            ctx?.addEllipse(in: innerRect);
+            ctx?.setFillColor(innerColor!.cgColor.components!);
+            ctx?.fillPath();
+        }
+    }
+}
+
+class MailTableCell: MGSwipeTableCell {
+    
+    var mailFrom: UILabel!;
+    var mailSubject: UILabel!;
+    var mailMessage: UITextView!;
+    var mailTime: UILabel!;
+    var indicatorView: MailIndicatorView!;
+    
+    func initViews() {
+        mailFrom = UILabel(frame: CGRect.zero);
+        mailMessage = UITextView(frame: CGRect.zero);
+        mailSubject = UILabel(frame: CGRect.zero);
+        mailTime = UILabel(frame: CGRect.zero);
+        
+        mailFrom.font = UIFont(name:"HelveticaNeue", size:18.0);
+        mailSubject.font = UIFont(name:"HelveticaNeue-Light", size:15.0);
+        mailMessage.font = UIFont(name:"HelveticaNeue-Light", size:14.0);
+        mailTime.font = UIFont(name:"HelveticaNeue-Light", size:13.0);
+        
+        mailMessage.isScrollEnabled = false;
+        mailMessage.isEditable = false;
+        mailMessage.backgroundColor = UIColor.clear;
+        mailMessage.contentInset = UIEdgeInsetsMake(-5, -5, 0, 0);
+        mailMessage.textColor = UIColor.gray;
+        mailMessage.isUserInteractionEnabled = false;
+        
+        indicatorView = MailIndicatorView(frame: CGRect(x: 0, y: 0, width: 10, height: 10));
+        indicatorView.backgroundColor = UIColor.clear;
+        
+        contentView.addSubview(mailFrom);
+        contentView.addSubview(mailMessage);
+        contentView.addSubview(mailSubject);
+        contentView.addSubview(mailTime);
+        contentView.addSubview(indicatorView);
+        
+    }
+    
+    override init(style: UITableViewCellStyle, reuseIdentifier:String?)
+    {
+        super.init(style:style, reuseIdentifier: reuseIdentifier);
+        initViews();
+    }
+
+    required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder);
+        initViews();
+    }
+    
+    override func layoutSubviews() {
+        
+        super.layoutSubviews();
+        
+        let leftPadding:CGFloat = 25.0;
+        let topPadding:CGFloat = 3.0;
+        let textWidth = contentView.bounds.size.width - 2.0 * leftPadding;
+        let dateWidth:CGFloat = 40;
+        
+        mailFrom.frame = CGRect(x: leftPadding, y: topPadding, width: textWidth, height: 20);
+        mailSubject.frame = CGRect(x: leftPadding, y: mailFrom.frame.origin.y + mailFrom.frame.size.height + topPadding, width: textWidth - dateWidth, height: 17);
+        let messageHeight = contentView.bounds.size.height - (mailSubject.frame.origin.y + mailSubject.frame.size.height) - topPadding * 2;
+        mailMessage.frame = CGRect(x: leftPadding, y: mailSubject.frame.origin.y + mailSubject.frame.size.height + topPadding, width: textWidth, height: messageHeight);
+        
+        var frame = mailFrom.frame;
+        frame.origin.x = self.contentView.frame.size.width - leftPadding - dateWidth;
+        frame.size.width = dateWidth;
+        mailTime.frame = frame;
+        
+        indicatorView.center = CGPoint(x: leftPadding * 0.5, y: mailFrom.frame.origin.y + mailFrom.frame.size.height * 0.5);
+    }
+    
+}
+

+ 277 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/MailViewController.swift

@@ -0,0 +1,277 @@
+//
+//  ViewController.swift
+//  MailAppDemoSwift
+//
+
+import UIKit
+
+class MailData {
+    var from: String!;
+    var subject: String!;
+    var message: String!;
+    var date: String!;
+    var read = false;
+    var flag = false;
+}
+
+typealias MailActionCallback = (_ cancelled: Bool, _ deleted: Bool, _ actionIndex: Int) -> Void
+
+class MailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, MGSwipeTableCellDelegate, UIActionSheetDelegate {
+    
+    var tableView: UITableView!;
+    var demoData = [MailData]();
+    var refreshControl: UIRefreshControl!;
+    var actionCallback: MailActionCallback?;
+    
+    func prepareDemoData() {
+        var from = [
+        "Vincent",
+        "Mr Glass",
+        "Marsellus",
+        "Ringo",
+        "Sullivan",
+        "Mr Wolf",
+        "Butch Coolidge",
+        "Marvin",
+        "Captain Koons",
+        "Jules",
+        "Jimmie Dimmick"
+        ];
+        
+        var subjects = [
+       "You think water moves fast?",
+       "They called me Mr Glass",
+       "The path of the righteous man",
+       "Do you see any Teletubbies in here?",
+       "Now that we know who you are",
+       "My money's in that office, right?",
+       "Now we took an oath",
+       "That show's called a pilot",
+       "I know who I am. I'm not a mistake",
+       "It all makes sense!",
+       "The selfish and the tyranny of evil men",
+        ];
+        
+        var messages = [
+        "You should see ice. It moves like it has a mind. Like it knows it killed the world once and got a taste for murder. After the avalanche, it took us a week to climb out.",
+        "And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy My brothers.",
+        "Look, just because I don't be givin' no man a foot massage don't make it right for Marsellus to throw Antwone into a glass motherfuckin' house",
+        "No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb.",
+        "In a comic, you know how you can tell who the arch-villain's going to be? He's the exact opposite of the hero",
+        "If she start giving me some bullshit about it ain't there, and we got to go someplace else and get it, I'm gonna shoot you in the head then and there.",
+        "that I'm breaking now. We said we'd say it was the snow that killed the other two, but it wasn't. Nature is lethal but it doesn't hold a candle to man.",
+        "Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows.",
+        "And most times they're friends, like you and me! I should've known way back when...",
+        "After the avalanche, it took us a week to climb out. Now, I don't know exactly when we turned on each other, but I know that seven of us survived the slide",
+        "Blessed is he who, in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children",
+        ];
+        
+        
+        for i in 0 ..< messages.count {
+            let mail = MailData();
+            mail.from = from[i];
+            mail.subject = subjects[i];
+            mail.message = messages[i];
+            mail.date = String(format: "11:%d", arguments: [43 - i]);
+            demoData.append(mail);
+        }
+    }
+    
+    func mailForIndexPath(_ path: IndexPath) -> MailData {
+        return demoData[(path as NSIndexPath).row];
+    }
+    @objc
+    func refreshCallback() {
+        prepareDemoData();
+        tableView.reloadData();
+        refreshControl.endRefreshing();
+    }
+    
+    func deleteMail(_ path:IndexPath) {
+        demoData.remove(at: (path as NSIndexPath).row);
+        tableView.deleteRows(at: [path], with: .left);
+    }
+    
+    func updateCellIndicator(_ mail: MailData, cell: MailTableCell) {
+        var color: UIColor;
+        var innerColor : UIColor?;
+        
+        if !mail.read && mail.flag {
+            color = UIColor.init(red: 1.0, green: 149/255.0, blue: 0.05, alpha: 1.0);
+            innerColor = UIColor.init(red: 0.0, green: 122/255.0, blue: 1.0, alpha: 1.0);
+        }
+        else if mail.flag {
+            color = UIColor.init(red: 1.0, green: 149/255.0, blue: 0.05, alpha: 1.0);
+        }
+        else if mail.read {
+            color = UIColor.clear;
+        }
+        else {
+            color = UIColor.init(red: 0.0, green: 122/255.0, blue: 1.0, alpha: 1.0);
+        }
+        
+        cell.indicatorView.indicatorColor = color;
+        cell.indicatorView.innerColor = innerColor;
+    }
+    
+    func showMailActions(_ mail: MailData, callback: @escaping MailActionCallback) {
+        actionCallback = callback;
+        let sheet = UIActionSheet.init(title: "Actions", delegate: self, cancelButtonTitle: "Cancel", destructiveButtonTitle: "Trash");
+        sheet.addButton(withTitle: "Mark as unread");
+        sheet.addButton(withTitle: "Mark as read");
+        sheet.addButton(withTitle: "Flag");
+
+        sheet.show(in: self.view);
+    }
+    
+    func actionSheet(_ actionSheet: UIActionSheet, clickedButtonAt index: Int) {
+        if let action = actionCallback {
+            action(index == actionSheet.cancelButtonIndex,
+                   index == actionSheet.destructiveButtonIndex,
+                   index);
+            actionCallback = nil;
+        }
+    }
+    
+    func readButtonText(_ read:Bool) -> String {
+        return read ? "Mark as\nunread" : "Mark as\nread";
+    }
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        tableView = UITableView(frame: view.bounds, style: UITableViewStyle.plain);
+        tableView.delegate = self;
+        tableView.dataSource = self;
+        view.addSubview(tableView);
+        
+        self.title = "MSwipeTableCell MailApp";
+        
+        refreshControl = UIRefreshControl();
+        refreshControl.addTarget(self, action: #selector(refreshCallback), for: UIControlEvents.valueChanged);
+        tableView.addSubview(refreshControl);
+        prepareDemoData();
+    }
+
+    override func didReceiveMemoryWarning() {
+        super.didReceiveMemoryWarning()
+        // Dispose of any resources that can be recreated.
+    }
+    
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
+    {
+        return demoData.count;
+    }
+    
+    
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        let identifier = "MailCell";
+        
+        var cell: MailTableCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? MailTableCell;
+        if cell == nil {
+            cell = MailTableCell(style: UITableViewCellStyle.default, reuseIdentifier: identifier);
+        }
+        cell.delegate = self;
+        
+        let data: MailData = demoData[(indexPath as NSIndexPath).row];
+        cell!.mailFrom.text = data.from;
+        cell!.mailSubject.text = data.subject;
+        cell!.mailMessage.text = data.message;
+        cell!.mailTime.text = data.date;
+        updateCellIndicator(data, cell: cell);
+        return cell;
+    }
+    
+    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return 110;
+    }
+    
+    func swipeTableCell(_ cell: MGSwipeTableCell, canSwipe direction: MGSwipeDirection) -> Bool {
+        return true;
+    }
+    
+    
+    func swipeTableCell(_ cell: MGSwipeTableCell, swipeButtonsFor direction: MGSwipeDirection, swipeSettings: MGSwipeSettings, expansionSettings: MGSwipeExpansionSettings) -> [UIView]? {
+        
+        swipeSettings.transition = MGSwipeTransition.border;
+        expansionSettings.buttonIndex = 0;
+        
+        
+        let mail = mailForIndexPath(tableView.indexPath(for: cell)!);
+        
+        if direction == MGSwipeDirection.leftToRight {
+            expansionSettings.fillOnTrigger = false;
+            expansionSettings.threshold = 2;
+            let color = UIColor.init(red:0.0, green:122/255.0, blue:1.0, alpha:1.0);
+            
+            return [
+                MGSwipeButton(title: readButtonText(mail.read), backgroundColor: color, callback: { (cell) -> Bool in
+                    mail.read = !mail.read;
+                    self.updateCellIndicator(mail, cell: cell as! MailTableCell);
+                    cell.refreshContentView();
+                    (cell.leftButtons[0] as! UIButton).setTitle(self.readButtonText(mail.read), for: UIControlState());
+                    
+                    return true;
+                })
+            ]
+        }
+        else {
+            expansionSettings.fillOnTrigger = true;
+            expansionSettings.threshold = 1.1;
+            let padding = 15;
+            let color1 = UIColor.init(red:1.0, green:59/255.0, blue:50/255.0, alpha:1.0);
+            let color2 = UIColor.init(red:1.0, green:149/255.0, blue:0.05, alpha:1.0);
+            let color3 = UIColor.init(red:200/255.0, green:200/255.0, blue:205/255.0, alpha:1.0);
+            
+            let trash = MGSwipeButton(title: "Trash", backgroundColor: color1, padding: padding, callback: { (cell) -> Bool in
+                self.deleteMail(self.tableView.indexPath(for: cell)!);
+                return false; //don't autohide to improve delete animation
+            });
+    
+            let flag = MGSwipeButton(title: "Flag", backgroundColor: color2, padding: padding, callback: { (cell) -> Bool in
+                let mail = self.mailForIndexPath(self.tableView.indexPath(for: cell)!);
+                mail.flag = !mail.flag;
+                self.updateCellIndicator(mail, cell: cell as! MailTableCell);
+                cell.refreshContentView(); //needed to refresh cell contents while swipping
+                return true; //autohide
+            });
+            
+            let more = MGSwipeButton(title: "More", backgroundColor: color3, padding: padding, callback: { (cell) -> Bool in
+                let path = self.tableView.indexPath(for: cell)!;
+                let mail = self.mailForIndexPath(path);
+                
+                self.showMailActions(mail, callback: { (cancelled, deleted, index) in
+                    if cancelled {
+                        return;
+                    }
+                    else if deleted {
+                        self.deleteMail(path);
+                    }
+                    else if index == 1 {
+                        mail.read = !mail.read;
+                        self.updateCellIndicator(mail, cell: cell as! MailTableCell);
+                        cell.refreshContentView();
+                        (cell.leftButtons[0] as! UIButton).setTitle(self.readButtonText(mail.read), for: UIControlState());
+                        cell.hideSwipe(animated: true);
+                    }
+                    else if index == 2 {
+                        mail.flag = !mail.flag;
+                        self.updateCellIndicator(mail, cell: cell as! MailTableCell);
+                        cell.refreshContentView(); //needed to refresh cell contents while swipping
+                        cell.hideSwipe(animated: true);
+                    }
+                    
+                });
+                
+                return false; // Don't autohide
+            });
+            
+            return [trash, flag, more];
+        }
+        
+    }
+
+
+
+}
+

+ 2 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwift/ObjCBridgingHeader.h

@@ -0,0 +1,2 @@
+#import "MGSwipeTableCell.h"
+#import "MGSwipeButton.h"

+ 24 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwiftTests/Info.plist

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>mortimergoro.$(PRODUCT_NAME:rfc1034identifier)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>BNDL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>

+ 36 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/MailAppDemoSwift/MailAppDemoSwiftTests/MailAppDemoSwiftTests.swift

@@ -0,0 +1,36 @@
+//
+//  MailAppDemoSwiftTests.swift
+//  MailAppDemoSwiftTests
+//
+//  Created by Imanol Fernandez Gorostizag on 17/11/14.
+//  Copyright (c) 2014 Imanol Fernandez. All rights reserved.
+//
+
+import UIKit
+import XCTest
+
+class MailAppDemoSwiftTests: XCTestCase {
+    
+    override func setUp() {
+        super.setUp()
+        // Put setup code here. This method is called before the invocation of each test method in the class.
+    }
+    
+    override func tearDown() {
+        // Put teardown code here. This method is called after the invocation of each test method in the class.
+        super.tearDown()
+    }
+    
+    func testExample() {
+        // This is an example of a functional test case.
+        XCTAssert(true, "Pass")
+    }
+    
+    func testPerformanceExample() {
+        // This is an example of a performance test case.
+        self.measure() {
+            // Put the code you want to measure the time of here.
+        }
+    }
+    
+}

+ 14 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/AppDelegate.h

@@ -0,0 +1,14 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+

+ 48 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/AppDelegate.m

@@ -0,0 +1,48 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "AppDelegate.h"
+#import "SpotifyViewController.h"
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+
+    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+    
+    SpotifyViewController * vc = [[SpotifyViewController alloc] init];
+    UINavigationController * navigation = [[UINavigationController alloc] initWithRootViewController:vc];
+    navigation.navigationBar.translucent = NO;
+    self.window.rootViewController = navigation;
+    
+    self.window.backgroundColor = [UIColor whiteColor];
+    [self.window makeKeyAndVisible];
+    return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end

+ 68 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 89 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/Images.xcassets/LaunchImage.launchimage/Contents.json

@@ -0,0 +1,89 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "scale" : "1x",
+      "orientation" : "portrait"
+    },
+    {
+      "idiom" : "iphone",
+      "scale" : "2x",
+      "orientation" : "portrait"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "subtype" : "retina4",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "minimum-system-version" : "7.0",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "iphone",
+      "minimum-system-version" : "7.0",
+      "subtype" : "retina4",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "extent" : "to-status-bar",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "portrait",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "2x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "1x"
+    },
+    {
+      "orientation" : "landscape",
+      "idiom" : "ipad",
+      "minimum-system-version" : "7.0",
+      "extent" : "full-screen",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 47 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/Info.plist

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>armv7</string>
+	</array>
+	<key>UIStatusBarHidden</key>
+	<true/>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+</dict>
+</plist>

+ 14 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/SpotifyViewController.h

@@ -0,0 +1,14 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import <UIKit/UIKit.h>
+#import "MGSwipeTableCell.h"
+
+@interface SpotifyViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, MGSwipeTableCellDelegate, UIActionSheetDelegate>
+
+@property (nonatomic, strong) UITableView * tableView;
+
+@end
+

+ 223 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/SpotifyViewController.m

@@ -0,0 +1,223 @@
+/*
+ * MGSwipeTableCell is licensed under MIT license. See LICENSE.md file for more information.
+ * Copyright (c) 2014 Imanol Fernandez @MortimerGoro
+ */
+
+#import "SpotifyViewController.h"
+#import "MGSwipeButton.h"
+
+
+@interface SongData : NSObject
+@property (nonatomic, strong) NSString * title;
+@property (nonatomic, strong) NSString * album;
+@end
+
+@implementation SongData
+@end
+
+
+typedef void(^MailActionCallback)(BOOL cancelled, BOOL deleted, NSInteger actionIndex);
+
+@implementation SpotifyViewController
+{
+    NSMutableArray * demoData;
+    MailActionCallback actionCallback;
+    UIRefreshControl * refreshControl;
+}
+
+-(BOOL) prefersStatusBarHidden
+{
+    return YES;
+}
+
+
+-(void) prepareDemoData
+{
+    demoData = [NSMutableArray array];
+    
+    NSArray * titles = @[
+                       @"Vincent",
+                       @"Mr Glass",
+                       @"Marsellus",
+                       @"Ringo",
+                       @"Sullivan",
+                       @"Mr Wolf",
+                       @"Butch Coolidge",
+                       @"Marvin",
+                       @"Captain Koons",
+                       @"Jules",
+                       @"Jimmie Dimmick"
+                       ];
+    
+    NSArray * albums = @[
+                           @"You think water moves fast?",
+                           @"They called me Mr Glass",
+                           @"The path of the righteous man",
+                           @"Do you see any Teletubbies in here?",
+                           @"Now that we know who you are",
+                           @"My money's in that office, right?",
+                           @"Now we took an oath",
+                           @"That show's called a pilot",
+                           @"I know who I am. I'm not a mistake",
+                           @"It all makes sense!",
+                           @"The selfish and the tyranny of evil men",
+                           ];
+    
+    for (int i = 0; i < titles.count; ++i) {
+        SongData * song = [[SongData alloc] init];
+        song.title = [titles objectAtIndex:i];
+        song.album = [albums objectAtIndex:i];
+        [demoData addObject:song];
+    }
+}
+
+-(void) refreshCallback
+{
+    [self prepareDemoData];
+    [_tableView reloadData];
+    [refreshControl endRefreshing];
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    
+    [self.navigationController setNavigationBarHidden:YES animated:NO];
+    
+    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
+    _tableView.delegate = self;
+    _tableView.dataSource = self;
+    _tableView.separatorColor = [UIColor clearColor];
+    _tableView.backgroundColor = [UIColor colorWithRed:15/255.0 green:16/255.0 blue:16/255.0 alpha:1.0];
+    [self.view addSubview:_tableView];
+    
+    self.title = @"Spotify App Demo";
+    
+    refreshControl = [[UIRefreshControl alloc] init];
+    [refreshControl addTarget:self action:@selector(refreshCallback) forControlEvents:UIControlEventValueChanged];
+    [self.tableView addSubview:refreshControl];
+    
+    [self prepareDemoData];
+}
+
+-(void) viewDidAppear:(BOOL)animated
+{
+    [self.tableView reloadData];
+}
+
+-(void) viewWillLayoutSubviews
+{
+    [super viewWillLayoutSubviews];
+    _tableView.frame = self.view.bounds;
+}
+
+-(void) deleteMail:(NSIndexPath *) indexPath
+{
+    [demoData removeObjectAtIndex:indexPath.row];
+    [_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
+}
+
+-(SongData *) songForIndexPath:(NSIndexPath*) path
+{
+    return [demoData objectAtIndex:path.row];
+}
+
+#pragma mark Table Delegate
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    return demoData.count;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    static NSString * identifier = @"SongCell";
+    MGSwipeTableCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
+    if (!cell) {
+        cell = [[MGSwipeTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
+        cell.textLabel.font =  [UIFont fontWithName:@"HelveticaNeue-Light" size:21.0f];
+        cell.textLabel.textColor = [UIColor colorWithRed:152/255.0 green:152/255.0 blue:157/255.0 alpha:1.0];
+        cell.textLabel.font =  [UIFont fontWithName:@"HelveticaNeue-Light" size:17.0f];
+        cell.detailTextLabel.textColor = cell.textLabel.textColor;
+        cell.backgroundColor = [UIColor colorWithRed:15/255.0 green:16/255.0 blue:16/255.0 alpha:1.0];
+        cell.selectionStyle = UITableViewCellSelectionStyleNone;
+        
+        UIImageView * view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"more.png"]];
+        view.contentMode = UIViewContentModeScaleAspectFit;
+        view.frame = CGRectMake(0, 0, 25, 25);
+        cell.accessoryView = view;
+    }
+    cell.delegate = self;
+    
+    SongData * data = [demoData objectAtIndex:indexPath.row];
+    cell.textLabel.text = data.title;
+    cell.detailTextLabel.text = data.album;
+    return cell;
+}
+
+- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    return 50;
+}
+
+#pragma mark Swipe Delegate
+
+-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell canSwipe:(MGSwipeDirection) direction;
+{
+    return YES;
+}
+
+-(NSArray*) swipeTableCell:(MGSwipeTableCell*) cell swipeButtonsForDirection:(MGSwipeDirection)direction
+             swipeSettings:(MGSwipeSettings*) swipeSettings expansionSettings:(MGSwipeExpansionSettings*) expansionSettings
+{
+    
+    swipeSettings.transition = MGSwipeTransitionClipCenter;
+    swipeSettings.keepButtonsSwiped = NO;
+    expansionSettings.buttonIndex = 0;
+    expansionSettings.threshold = 1.0;
+    expansionSettings.expansionLayout = MGSwipeExpansionLayoutCenter;
+    expansionSettings.expansionColor = [UIColor colorWithRed:33/255.0 green:175/255.0 blue:67/255.0 alpha:1.0];
+    expansionSettings.triggerAnimation.easingFunction = MGSwipeEasingFunctionCubicOut;
+    expansionSettings.fillOnTrigger = NO;
+    
+    __weak SpotifyViewController * me = self;
+    UIColor * color = [UIColor colorWithRed:47/255.0 green:47/255.0 blue:49/255.0 alpha:1.0];
+    UIFont * font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14.0f];
+    if (direction == MGSwipeDirectionLeftToRight) {
+        MGSwipeButton * queueButton = [MGSwipeButton buttonWithTitle:@"QUEUE" backgroundColor:color padding:15 callback:^BOOL(MGSwipeTableCell *sender) {
+            SongData * song = [me songForIndexPath:[me.tableView indexPathForCell:sender]];
+            NSLog(@"Queue song: %@", song.title);
+            return YES;
+        }];
+        queueButton.titleLabel.font = font;
+        
+        return @[queueButton];
+    }
+    else {
+        
+        MGSwipeButton * saveButton = [MGSwipeButton buttonWithTitle:@"SAVE" backgroundColor:color padding:15 callback:^BOOL(MGSwipeTableCell *sender) {
+            SongData * song = [me songForIndexPath:[me.tableView indexPathForCell:sender]];
+            NSLog(@"Save song: %@", song.title);
+            return YES; //don't autohide to improve delete animation
+        }];
+        saveButton.titleLabel.font = font;
+        return @[saveButton];
+    }
+    
+    return nil;
+    
+}
+
+-(void) swipeTableCell:(MGSwipeTableCell*) cell didChangeSwipeState:(MGSwipeState)state gestureIsActive:(BOOL)gestureIsActive
+{
+    NSString * str;
+    switch (state) {
+        case MGSwipeStateNone: str = @"None"; break;
+        case MGSwipeStateSwippingLeftToRight: str = @"SwippingLeftToRight"; break;
+        case MGSwipeStateSwippingRightToLeft: str = @"SwippingRightToLeft"; break;
+        case MGSwipeStateExpandingLeftToRight: str = @"ExpandingLeftToRight"; break;
+        case MGSwipeStateExpandingRightToLeft: str = @"ExpandingRightToLeft"; break;
+    }
+    NSLog(@"Swipe state: %@ ::: Gesture: %@", str, gestureIsActive ? @"Active" : @"Ended");
+}
+
+@end

+ 16 - 0
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/main.m

@@ -0,0 +1,16 @@
+//
+//  main.m
+//  MailAppDemo
+//
+//  Created by Imanol Fernandez Gorostizaga on 26/09/14.
+//  Copyright (c) 2014 Mortimer. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+    @autoreleasepool {
+        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+    }
+}

BIN
Carthage/Checkouts/MGSwipeTableCell/demo/SpotifyDemo/SpotifyDemo/more@2x.png


BIN
Carthage/Checkouts/MGSwipeTableCell/readme-assets/3d.gif


BIN
Carthage/Checkouts/MGSwipeTableCell/readme-assets/RoundTableViewCell.png


BIN
Carthage/Checkouts/MGSwipeTableCell/readme-assets/border.gif


BIN
Carthage/Checkouts/MGSwipeTableCell/readme-assets/clip.gif


BIN
Carthage/Checkouts/MGSwipeTableCell/readme-assets/drag.gif


BIN
Carthage/Checkouts/MGSwipeTableCell/readme-assets/static.gif


+ 5 - 20
Nextcloud.xcodeproj/project.pbxproj

@@ -461,6 +461,7 @@
 		F7BE6E2F1D2D5C3B00106933 /* CCQuickActions.m in Sources */ = {isa = PBXBuildFile; fileRef = F7BE6E2C1D2D5C3B00106933 /* CCQuickActions.m */; };
 		F7BF1B431D51E893000854F6 /* CCLogin.m in Sources */ = {isa = PBXBuildFile; fileRef = F7BF1B401D51E893000854F6 /* CCLogin.m */; };
 		F7C40BE321998C060004137E /* PDFGenerator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C40BE221998C050004137E /* PDFGenerator.framework */; };
+		F7C40BE521998D5B0004137E /* MGSwipeTableCell.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C40BE421998D5A0004137E /* MGSwipeTableCell.framework */; };
 		F7C525A01E3B48B700FFE02C /* CCNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C5259F1E3B48B700FFE02C /* CCNotification.swift */; };
 		F7C525A21E3B6DA800FFE02C /* CCNotification.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7C525A11E3B6DA800FFE02C /* CCNotification.storyboard */; };
 		F7CA1ED020E7E3FE002CC65E /* UIImage+PKDownloadButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7CA1EBC20E7E3FE002CC65E /* UIImage+PKDownloadButton.m */; };
@@ -522,8 +523,6 @@
 		F7D4238B1F0596C6009C9782 /* ThumbsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F7D423761F0596C6009C9782 /* ThumbsViewController.m */; };
 		F7D4238C1F0596C6009C9782 /* UIXToolbarView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7D423781F0596C6009C9782 /* UIXToolbarView.m */; };
 		F7D6650720FF341600BFBA9E /* NCMainCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D6650620FF341600BFBA9E /* NCMainCommon.swift */; };
-		F7DC5FEC1F011EB700A903C7 /* MGSwipeButton.m in Sources */ = {isa = PBXBuildFile; fileRef = F7DC5FE91F011EB700A903C7 /* MGSwipeButton.m */; };
-		F7DC5FED1F011EB700A903C7 /* MGSwipeTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F7DC5FEB1F011EB700A903C7 /* MGSwipeTableCell.m */; };
 		F7DFE2521EBDC3A400CF5202 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7DFE24F1EBDC3A400CF5202 /* Realm.framework */; };
 		F7DFE2541EBDC3A400CF5202 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7DFE2501EBDC3A400CF5202 /* RealmSwift.framework */; };
 		F7DFE2551EBDC3A400CF5202 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7DFE2501EBDC3A400CF5202 /* RealmSwift.framework */; };
@@ -1251,6 +1250,7 @@
 		F7C0F46E1C8880540059EC54 /* ShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ShareViewController.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
 		F7C0F46F1C8880540059EC54 /* ShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ShareViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
 		F7C40BE221998C050004137E /* PDFGenerator.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PDFGenerator.framework; path = Carthage/Build/iOS/PDFGenerator.framework; sourceTree = "<group>"; };
+		F7C40BE421998D5A0004137E /* MGSwipeTableCell.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MGSwipeTableCell.framework; path = Carthage/Build/iOS/MGSwipeTableCell.framework; sourceTree = "<group>"; };
 		F7C5259F1E3B48B700FFE02C /* CCNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CCNotification.swift; path = Notification/CCNotification.swift; sourceTree = "<group>"; };
 		F7C525A11E3B6DA800FFE02C /* CCNotification.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = CCNotification.storyboard; path = Notification/CCNotification.storyboard; sourceTree = "<group>"; };
 		F7C742C01E7BD01F00D9C973 /* iOSClient.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = iOSClient.entitlements; sourceTree = "<group>"; };
@@ -1361,10 +1361,6 @@
 		F7D5328F1F5D443B006568B1 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F7D532A41F5D4461006568B1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F7D6650620FF341600BFBA9E /* NCMainCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMainCommon.swift; sourceTree = "<group>"; };
-		F7DC5FE81F011EB700A903C7 /* MGSwipeButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGSwipeButton.h; sourceTree = "<group>"; };
-		F7DC5FE91F011EB700A903C7 /* MGSwipeButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGSwipeButton.m; sourceTree = "<group>"; };
-		F7DC5FEA1F011EB700A903C7 /* MGSwipeTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGSwipeTableCell.h; sourceTree = "<group>"; };
-		F7DC5FEB1F011EB700A903C7 /* MGSwipeTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGSwipeTableCell.m; sourceTree = "<group>"; };
 		F7DE9AB01F482FA5008DFE10 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F7DFE24F1EBDC3A400CF5202 /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Realm.framework; sourceTree = "<group>"; };
 		F7DFE2501EBDC3A400CF5202 /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RealmSwift.framework; sourceTree = "<group>"; };
@@ -1493,6 +1489,7 @@
 				F7A377161EB2364A002856D3 /* Crashlytics.framework in Frameworks */,
 				F733B65221997CC2001C1FFA /* TLPhotoPicker.framework in Frameworks */,
 				F7FC7D561DC1F93800BB2C6A /* libz.tbd in Frameworks */,
+				F7C40BE521998D5B0004137E /* MGSwipeTableCell.framework in Frameworks */,
 				F7A3771A1EB2364A002856D3 /* Fabric.framework in Frameworks */,
 				F72D0FFE210B6638009C96B7 /* nanopb.framework in Frameworks */,
 				F72D0FFD210B6638009C96B7 /* GoogleToolboxForMac.framework in Frameworks */,
@@ -1666,7 +1663,6 @@
 				F784FA24210F672E00256C26 /* KTVHTTPCache */,
 				F7659A2F1DC0B737004860C4 /* iRate */,
 				F70F04821C889183008DAB36 /* MBProgressHUD */,
-				F7DC5FD31F00F98B00A903C7 /* MGSwipeTableCell */,
 				F7B2DEEB1F976785007CF4D2 /* NYMnemonic */,
 				F7540EE11D5B238600C3FFA8 /* openssl */,
 				F7CA1EBB20E7E3FE002CC65E /* PKDownloadButton */,
@@ -2885,17 +2881,6 @@
 			path = Sources;
 			sourceTree = "<group>";
 		};
-		F7DC5FD31F00F98B00A903C7 /* MGSwipeTableCell */ = {
-			isa = PBXGroup;
-			children = (
-				F7DC5FE81F011EB700A903C7 /* MGSwipeButton.h */,
-				F7DC5FE91F011EB700A903C7 /* MGSwipeButton.m */,
-				F7DC5FEA1F011EB700A903C7 /* MGSwipeTableCell.h */,
-				F7DC5FEB1F011EB700A903C7 /* MGSwipeTableCell.m */,
-			);
-			path = MGSwipeTableCell;
-			sourceTree = "<group>";
-		};
 		F7DFE24E1EBDC3A400CF5202 /* Realm */ = {
 			isa = PBXGroup;
 			children = (
@@ -3097,6 +3082,7 @@
 		F7FC7D541DC1F93700BB2C6A /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				F7C40BE421998D5A0004137E /* MGSwipeTableCell.framework */,
 				F7C40BE221998C050004137E /* PDFGenerator.framework */,
 				F79918A72199840500C2E308 /* Sheeeeeeeeet.framework */,
 				F79918A021997F9000C2E308 /* UICKeyChainStore.framework */,
@@ -3530,6 +3516,7 @@
 				"$(SRCROOT)/Carthage/Build/iOS/TLPhotoPicker.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/UICKeyChainStore.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/PDFGenerator.framework",
+				"$(SRCROOT)/Carthage/Build/iOS/MGSwipeTableCell.framework",
 			);
 			outputPaths = (
 			);
@@ -3744,7 +3731,6 @@
 				F732BA061D76CE1500E9878B /* CCNetworking.m in Sources */,
 				F70022B01EC4C9100080073F /* AFURLSessionManager.m in Sources */,
 				F7B1FBC71E72E3D1001781FE /* SwiftWebVC.swift in Sources */,
-				F7DC5FEC1F011EB700A903C7 /* MGSwipeButton.m in Sources */,
 				F7D423801F0596C6009C9782 /* ReaderMainPagebar.m in Sources */,
 				F762CB061EACB66200B38484 /* XLFormTextViewCell.m in Sources */,
 				F78ACD4221903CE00088454D /* NCListCell.swift in Sources */,
@@ -3951,7 +3937,6 @@
 				F762CB0B1EACB66200B38484 /* XLFormRowDescriptor.m in Sources */,
 				F7169A1C1EE590930086BD69 /* NCShares.m in Sources */,
 				F77B0EC61D118A16002130FE /* CCCellMain.m in Sources */,
-				F7DC5FED1F011EB700A903C7 /* MGSwipeTableCell.m in Sources */,
 				F7D4238B1F0596C6009C9782 /* ThumbsViewController.m in Sources */,
 				F70022B61EC4C9100080073F /* OCCapabilities.m in Sources */,
 				F7D423811F0596C6009C9782 /* ReaderMainToolbar.m in Sources */,

+ 0 - 1
iOSClient/Favorites/CCFavorites.h

@@ -27,7 +27,6 @@
 #import "UIScrollView+EmptyDataSet.h"
 #import "TWMessageBarManager.h"
 #import "AHKActionSheet.h"
-#import "MGSwipeTableCell.h"
 #import "CCCellMain.h"
 #import "CCCellMainTransfer.h"
 #import "CCUtility.h"

+ 1 - 1
iOSClient/Main/CCMain.h

@@ -27,7 +27,6 @@
 #import <AudioToolbox/AudioToolbox.h>
 
 #import "TWMessageBarManager.h"
-#import "MGSwipeTableCell.h"
 #import "AHKActionSheet.h"
 #import "BKPasscodeViewController.h"
 #import "NSString+TruncateToWidth.h"
@@ -44,6 +43,7 @@
 #import "CCHud.h"
 #import "CCMenuAccount.h"
 #import "CCPeekPop.h"
+#import <MGSwipeTableCell/MGSwipeTableCell.h>
 
 @class tableMetadata;
 

+ 1 - 1
iOSClient/Main/Cell/CCCellMain.h

@@ -22,7 +22,7 @@
 //
 
 #import <UIKit/UIKit.h>
-#import "MGSwipeTableCell.h"
+#import <MGSwipeTableCell/MGSwipeTableCell.h>
 
 @interface CCCellMain : MGSwipeTableCell