GithubHelp home page GithubHelp logo

mortimergoro / mgswipetablecell Goto Github PK

View Code? Open in Web Editor NEW
7.0K 213.0 1.1K 2.12 MB

An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions.

License: MIT License

Objective-C 98.60% Ruby 0.70% Swift 0.70%

mgswipetablecell's Introduction

MGSwipeTableCell

Carthage compatible

MGSwipeTableCell is an easy to use UITableViewCell subclass that allows to display swipeable buttons with a variety of transitions.

This library is compatible with all the different ways to create a UITableViewCell: system predefined styles, programmatically created cells, cells loaded from a xib and prototype cells within a storyboard. You can use autolayout if you want.

Works on iOS >= 5.0. Tested on all iOS versions on iPhone and iPad: iOS 7, iOS 8, iOS 9, iOS 10, iOS 11, iOS 12, iOS 13, iOS 14.

Transitions demo

Border transition

Clip transition

3D transition

Static transition

Drag transition

API Reference

See MGSwipeTableCell.h header file for a complete overview of the capabilities of the class.

See MailAppDemo for a complete project which mimics Apple's Mail App (written in Objective-C)

See MailAppDemoSwift for a complete project which mimics Apple's Mail App (Written in Swift)

See SpotifyDemo for a complete project which mimics Spotify App swipe style

See MGSwipeDemo for a complete project where you can test the variety of transitions on a real device/simulator.

Setup your project

You can use CocoaPods to include MGSwipeTableCell into you project:

pod 'MGSwipeTableCell'

You can use Carthage to include MGSwipeTableCell into your project. Just add this dependency to your Cartfile:

github "MortimerGoro/MGSwipeTableCell"

You can use Swift Package Manager to include MGSwipeTableCell into you project:

.package(url: "https://github.com/MortimerGoro/MGSwipeTableCell.git", from: "1.6.0")

Usage

Basic

Integrating MGSwipeTableCell in your project is very easy. Basically, you only have to inherit from MGSwipeTableCell instead of UITableViewCell, or directly instantiate MGSwipeTableCell instances with iOS predefined cell styles. You can layout your cell content as you are used to do, MGSwipeTableCell doesn't force you to change layouts.

Here is a example of a MGSwipeTableCell using iOS predefined styles. You can set an array of buttons to cell.leftButtons and/or cell.rightButtons properties. MGSwipeButton is a convenience class, you are not forced to use it. You can use your own UIButtons or UIViews. You can configure transitions (and swipe thresholds) with the leftSwipeSettings and/or rightSwipeSettings properties

Objective-C
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString * reuseIdentifier = @"programmaticCell";
    MGSwipeTableCell * cell = [self.tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[MGSwipeTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
    }

    cell.textLabel.text = @"Title";
    cell.detailTextLabel.text = @"Detail text";
    cell.delegate = self; //optional


    //configure left buttons
    cell.leftButtons = @[[MGSwipeButton buttonWithTitle:@"" icon:[UIImage imageNamed:@"check.png"] backgroundColor:[UIColor greenColor]],
                          [MGSwipeButton buttonWithTitle:@"" icon:[UIImage imageNamed:@"fav.png"] backgroundColor:[UIColor blueColor]]];
    cell.leftSwipeSettings.transition = MGSwipeTransition3D;

    //configure right buttons
    cell.rightButtons = @[[MGSwipeButton buttonWithTitle:@"Delete" backgroundColor:[UIColor redColor]],
                           [MGSwipeButton buttonWithTitle:@"More" backgroundColor:[UIColor lightGrayColor]]];
    cell.rightSwipeSettings.transition = MGSwipeTransition3D;
    return cell;
}
Swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let reuseIdentifier = "programmaticCell"
    var cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! MGSwipeTableCell

    cell.textLabel!.text = "Title"
    cell.detailTextLabel!.text = "Detail text"
    cell.delegate = self //optional

    //configure left buttons
    cell.leftButtons = [MGSwipeButton(title: "", icon: UIImage(named:"check.png"), backgroundColor: .green),
                        MGSwipeButton(title: "", icon: UIImage(named:"fav.png"), backgroundColor: .blue)]
    cell.leftSwipeSettings.transition = .rotate3D

    //configure right buttons
    cell.rightButtons = [MGSwipeButton(title: "Delete", backgroundColor: .red),
                         MGSwipeButton(title: "More",backgroundColor: .lightGray)]
    cell.rightSwipeSettings.transition = .rotate3D

    return cell
}

In order to listen for button click events you can implement the optional MGSwipeTableCellDelegate, or if you are too lazy to do that, the MGSwipeButton class comes with a convenience block callback ;)

Objective-c
[MGSwipeButton buttonWithTitle:@"More" backgroundColor:[UIColor lightGrayColor] callback:^BOOL(MGSwipeTableCell *sender) {
      NSLog(@"Convenience callback for swipe buttons!");
}]
Swift
MGSwipeButton(title: "Delete", backgroundColor: .red) {
      (sender: MGSwipeTableCell!) -> Bool in
      print("Convenience callback for swipe buttons!")
      return true
    }

Delegate

MGSwipeTableCellDelegate is an optional delegate to configure swipe buttons or to receive triggered actions or another events. Buttons can be configured inline when the cell is created instead of using this delegate, but using the delegate improves memory usage since buttons are only created on demand.

@protocol MGSwipeTableCellDelegate <NSObject>

@optional
/**
 * Delegate method to enable/disable swipe gestures
 * @return YES if swipe is allowed
 **/
-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell canSwipe:(MGSwipeDirection) direction;
/**
 * Delegate method invoked when the current swipe state changes
 @param state the current Swipe State
 @param gestureIsActive YES if the user swipe gesture is active. No if the uses has already ended the gesture
 **/
-(void) swipeTableCell:(MGSwipeTableCell*) cell didChangeSwipeState:(MGSwipeState) state gestureIsActive:(BOOL) gestureIsActive;
/**
 * Called when the user clicks a swipe button or when a expandable button is automatically triggered
 * @return YES to autohide the current swipe buttons
 **/
-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion;
/**
 * Delegate method to setup the swipe buttons and swipe/expansion settings
 * Buttons can be any kind of UIView but it's recommended to use the convenience MGSwipeButton class
 * Setting up buttons with this delegate instead of using cell properties improves memory usage because buttons are only created in demand
 * @param swipeTableCell the UITableViewCell to configure. You can get the indexPath using [tableView indexPathForCell:cell]
 * @param direction The swipe direction (left to right or right to left)
 * @param swipeSettings instance to configure the swipe transition and setting (optional)
 * @param expansionSettings instance to configure button expansions (optional)
 * @return Buttons array
 **/
-(NSArray*) swipeTableCell:(MGSwipeTableCell*) cell swipeButtonsForDirection:(MGSwipeDirection)direction
             swipeSettings:(MGSwipeSettings*) swipeSettings expansionSettings:(MGSwipeExpansionSettings*) expansionSettings;

@end

Expandable buttons

Buttons are not expandable by default. You can set up expandable buttons using cell.leftExpansion and cell.rightExpansion properties

Expandable button events are triggered automatically when the user ends the swipe gesture and the expansion is active (configurable via threshold value). Triggered expandable buttons can bounce back to their initial position or fill the entire UITableViewCell, you can select the desired animation using fillOnTrigger property.

@interface MGSwipeExpansionSettings: NSObject
/** index of the expandable button (in the left or right buttons arrays) */
@property (nonatomic, assign) NSInteger buttonIndex;
/** if true the button fills the cell on trigger, else it bounces back to its initial position */
@property (nonatomic, assign) BOOL fillOnTrigger;
/** Size proportional threshold to trigger the expansion button. Default value 1.5 */
@property (nonatomic, assign) CGFloat threshold;
@end

Rounded corners and swipe buttons

MGSwipeTableCell supports rounded corners. Example:

cell.layer.cornerRadius = 50
cell.backgroundColor = UIColor.gray
cell.clipsToBounds = true
cell.swipeBackgroundColor = UIColor.gray

License

The MIT License (MIT)

Copyright (c) 2014 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.

mgswipetablecell's People

Contributors

apocolipse avatar basthomas avatar brsoyan avatar chrisfsampaio avatar clarisli avatar codybaydin avatar digal avatar doodzik avatar fahadm avatar frankfle avatar jasontrask avatar jcw0913 avatar jstart avatar karthironald avatar lapfelix avatar lfarah avatar longlongjump avatar mergesort avatar mortimergoro avatar robsteinde avatar roiaddi avatar sammy-sc avatar senfi avatar shayanbo avatar taejoongyoon avatar tarbayev avatar vox-humana avatar woxtu avatar yambaypaul avatar zhukn1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mgswipetablecell's Issues

cell doesn't display selection state when swipe is closed

Can be reproduced in the enclosed email app demo:

  1. select a cell
  2. use swipe (doesn't matter if left or right)
  3. close swipe
    Result: cell isn't displayed as selected anymore. If you scroll the cell out of the visible table area and back in, it is selected again

btw: great library. many thanks to the author!

Swipe button can respond even if it is hidden

This issue is easy to reproduce in demo app.

  1. Swipe a cell to show the swipe buttons
  2. Select multi-select test button, then the table view is in edit mode
  3. Cancel this edit mode
  4. Click button position in that swiped cell

You can see the button can respond in Xcode console even if it is hidden.

I am trying to fix this issue with add _swipeOverlay to self.contentView in showSwipeOverlayIfNeeded method and remove it from super view in hideSwipeOverlayIfNeeded.

Render issue

Hi,

I'm trying your library but I have the issue that the copy of content that this library is doing seems to be behind the original content.

screenshot_9_11_14__12_14_am

I'm not sure what I'm doing incorrectly.

Also I have a question, is it possible to swipe back - automatically - the cell once a button is clicked?

When swipeTableCell is called in a searchview cant identify tableview

Hi,

here is my source:

-(BOOL) swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion
{

    static NSString *CellIdentifier = @"cell";
    NSIndexPath * indexpath = [self.tableView indexPathForCell:cell];

    Kids *aKid = nil;

    if (self.tableView == self.searchDisplayController.searchResultsTableView) {
        aKid = [searchResults objectAtIndex:indexpath.row];
    } else {
        aKid = [kids objectAtIndex:indexpath.row];
    }

}

self.tableView == self.searchDisplayController.searchResultsTableView
is always false...

thanks in advance,

Eric

PS: Your control is very nice, continue!

How can I swipe the only needed cell?

Hey!
I need to implement such feature - to swipe only needed cell in my table view. (not every cell)
Please point me - how can I disable and enable swipe for needed cell?
I suggest - it will be possible by set the right or left buttons to nil.
But maybe there is a more clear way to do it?
Best wishes!

Animation Timers after delegate deallocated

I encountered a crash yesterday which I suspect to be the cell's animation timer firing after the cell's delegate has been deallocated.

The interesting part of the crash log indicates that the cell was trying to see if his delegate responds to
@selector(swipeTableCell:didChangeSwipeState:gestureIsActive:)
-[MGSwipeTableCell updateState:] (MGSwipeTableCell.m:674)

Is there a well-known pattern for invalidating all cell timers when the VC will/did disappear?
Should I be clearing every cell's delegate when the view will disappear, or is there some other preferred solution?

Thank you for any suggestions.
I am using version 1.2.0 (pod update isn't catching 1.3.0 yet)


Thread : Crashed: com.apple.main-thread
0 libsystem_platform.dylib 0x0000000195e1d2c0 platform_memmove + 112
1 libobjc.A.dylib 0x0000000195603258 memdup_internal + 52
2 libobjc.A.dylib 0x0000000195603258 memdup_internal + 52
3 libobjc.A.dylib 0x0000000195610778 fixupMethodList(method_list_t
, bool, bool) + 64
4 libobjc.A.dylib 0x0000000195610600 attachMethodLists(objc_class
, method_list_t*
, int, bool, bool, bool) + 316
5 libobjc.A.dylib 0x0000000195608664 realizeClass(objc_class_) + 1448
6 libobjc.A.dylib 0x000000019560c930 lookUpImpOrForward + 224
7 libobjc.A.dylib 0x0000000195617db8 _objc_msgSend_uncached_impcache + 56
8 TestApp 0x00000001001d618c -MGSwipeTableCell updateState:
9 TestApp 0x00000001001d62d8 -MGSwipeTableCell setSwipeOffset:
10 TestApp 0x00000001001d6958 -MGSwipeTableCell animationTick:
11 QuartzCore 0x0000000189065280 CA::Display::DisplayLinkItem::dispatch() + 32
12 QuartzCore 0x0000000189065118 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 324
13 IOKit 0x000000018605d8d0 IODispatchCalloutFromCFMessage + 376
14 CoreFoundation 0x0000000184eb4ce0 __CFMachPortPerform + 180
15 CoreFoundation 0x0000000184ec98fc CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 56
16 CoreFoundation 0x0000000184ec985c __CFRunLoopDoSource1 + 436
17 CoreFoundation 0x0000000184ec77dc __CFRunLoopRun + 1640
18 CoreFoundation 0x0000000184df51f4 CFRunLoopRunSpecific + 396
19 GraphicsServices 0x000000018df8b5a4 GSEventRunModal + 168
20 UIKit 0x0000000189726784 UIApplicationMain + 1488
21 TestApp 0x000000010010e688 main (main.m:16)
22 libdyld.dylib 0x0000000195c72a08 start + 4

Incorrect cell displayed while swiping when using dequeueReusableCellWithIdentifier

I have a cell that subclasses MGSwipeTableCell. Here is my code to initialize a cell:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell" forIndexPath:indexPath];
    cell.data = [self getData:indexPath];
    cell.rightButtons = @[[MGSwipeButton buttonWithTitle:@"Archive" backgroundColor:[UIColor redColor]]];
    cell.rightSwipeSettings.transition = MGSwipeTransitionDrag;

    [cell layout];
    return cell;
}

This works fine at first, but after scrolling around a bit, the wrong cell content starts appearing while swiping cells to the left. I can fix it by not reusing cells, like this, but that isn't ideal:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCell *cell = [MyCell new];
    cell.data = [self getData:indexPath];
    cell.rightButtons = @[[MGSwipeButton buttonWithTitle:@"Archive" backgroundColor:[UIColor redColor]]];
    cell.rightSwipeSettings.transition = MGSwipeTransitionDrag;

    [cell layout];
    return cell;
}

I think the problem has to do with the body of addInputOverlayIfNeeded which sets tableInputOverlay .currentCell, but is only executed once per reused cell.

Reorder control is not shown if tableview is in editing mode

Hi MortimerGoro, the reorder control of tableview is not shown in editing mode. I try to set the value of cell.showsReorderControl to YES, but it's still not working.
-(void) setEditing:(BOOL)editing
{
[super setEditing:YES];
if (editing) { //disable swipe buttons when the user sets table editing mode
self.swipeOffset = 0;
self.showsReorderControl = YES;
}
}

Problem with swipe gesture after I call showSwipe:

I am using iOS 8 and Swift.

I am doing a simple test with cell.showSwipe(MGSwipeDirection.LeftToRight, animated: true) and it works fine, but the problem is when I try to swipe it back to the left side the cell is not attached to the finger, it jumps straight to offset 0.

I have 2 buttons on my leftButtons view.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
   let cell = tableView.cellForRowAtIndexPath(indexPath) as MGSwipeTableCell
   cell.showSwipe(MGSwipeDirection.LeftToRight, animated: true)
}

Thanks a lot.

Pressing a UITableViewCell when a cell is currently swiped open

Hi, I am using MGSwipeTableCell in my app. When a cell is swiped open to reveal buttons if I tap on another cell it dismisses the swipe cell (hides the buttons again). I want the previously swiped cell to dismiss the buttons and then select the new cell in one tap instead of two (i.e. tap off and then tap new cell). Is there any way to to do this?

thanks

manually added cell subviews aren't animated correctly

First of all: awesome Framework!

The only small bug if one would call i that is an animation glitch with subviews, which were adden programatically and have no representation in the storyboard.

All these views slide correctly but in addition a duplicate of the view remains at the original position in the background. I only noticed it, because i'm working with a transparent cell background.
(for which i had to change line 594 in MDSwipeTableViewCell.m to [UiColor clearColor])

To overcome this, i had to create a rather useless view in the storyboard and change its properties programatically insted of generating it and add it as subview.

Table input overlay isn't removed when cell is deleted

There's an assumption that the following method will be called when a cell is deleted and therefore will hide the overlay.

-(void) willMoveToSuperview:(UIView *)newSuperview;
{
    if (newSuperview == nil) { //remove the table overlay when a cell is removed from the table
        [self hideSwipeOverlayIfNeeded];
    }
}

However, this doesn't necessarily seem to be the case. I delete a cell by calling
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];

yet the table overlay stays and it takes an extra tap to initiate the next action. Perhaps method hideSwipeOverlayIfNeeded could be exposed as public and called when needed?

Conflict with iOS standard "swipe to go back"

Info received by mail:

Basically, it seems as though the MGSTC panGesture and the iOS standard "swipe to go back" gesture are stealing one anthers touches. Strangely, it seems like whichever is engaged first disables the other. i.e. Swipe a cell and the swipe-back gesture will never get called, it will only swipe other cells. But, if you engage the swipe-back gesture first, only part-ways and return into the view cell will no longer swipe!

At first I thought the solution would be to modify the _swipeView bounds so that the MGSTC panGesture isn't called if it initiate within the first x points (sy, 5) of the left screen edge. For some reason I can't get this to work properly and it adds strange behaviour (cells will only swipe once and then never again? weird).

Anyway, it's an unlikely situation for any of my users to find them in, but something I thought I'd bring to your attention. Any ideas?

Swiping stops working after reloading table

Hi, sometimes (eg. when after swiping cell occurs reload on containing table or when I swipe a lot ;) ) swiping functionality crashes.

XCode console shows this message:
unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UIWindow: 0x7d1559e0; frame = (0 0; 768 1024); userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x7d1561e0>; layer = <UIWindowLayer: 0x7d155bd0>>

Do you know possible issue/solution? I was running code in simulator with iOS 8.1

While in multi-select edit mode, leftView steals input from the native circle selection button

I have a UITableView that allows for multiple selections while editing (self.tableView.allowsMultipleSelectionDuringEditing = YES;). When I go to edit mode I cannot select the native blue circle/checkbox because the MGSwipeButton is getting my touch events. This is due to the hitTest: override in MGSwipeTableCell. Here is how I resolved it but am not sure if it is the right solution.

// Line 610
-(UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event
{

    if (!self.isEditing) {
    //override hitTest to give swipe buttons a higher priority (diclosure buttons can steal input)
    UIView * targets[] = {_leftView, _rightView};
    for (int i = 0; i< 2; ++i) {
        UIView * target = targets[i];
        if (!target) continue;

        CGPoint p = [self convertPoint:point toView:target];
        if (CGRectContainsPoint(target.bounds, p)) {
            return [target hitTest:p withEvent:event];
        }
    }
    }
    return [super hitTest:point withEvent:event];
}

Button padding

One more small issue, I created my swipe buttons like below, but noticed that there was very little space around the text when displayed on screen.
[MGSwipeButton buttonWithTitle:@"Trash" backgroundColor:[UIColor redColor]];
[MGSwipeButton buttonWithTitle:@"More" backgroundColor:[UIColor lightGrayColor]];

To get around this I added spaces to one of the titles like so which caused both the Trash and More button widths to expand:
[MGSwipeButton buttonWithTitle:@" Trash " backgroundColor:[UIColor redColor]];

Is there a way you could implement a default padding similar to how Apple and components like MSCMoreOptionTableView display so I can avoid doing this myself?

Looking forward to adding this to my app so I can add right swipe as well. Thanks!

Cannot split space between multiple buttons in Release build

For some reason when I configure the build for Debug my buttons work fine (they're distributed evenly across the full width of the cell), but as soon as I configure the build for Release I see my buttons fly across and then the last button takes up the full width. Any ideas what's up here? I didn't find anything in the code that could cause this issue.

Is MGSwipeTableCell safe on arm64 platform ?

you know, apple will reject any app that doesn't support arm64 after next Feb. That means all third-party frameworks in my project need support arm64. MGSwipeTableCell is a good framework, so is it safe on arm64 platform ?

Application crash on tap

Hi, I am using MGSwipeTableCell I my application. Since I am using iOS 8 I am having issues. Sometimes it crashes my app. When I press on one of the button my app randomly crashes. I tried to set a breakpoint at
"-(BOOL)swipeTableCell:(MGSwipeTableCell*) cell tappedButtonAtIndex:(NSInteger) index direction:(MGSwipeDirection)direction fromExpansion:(BOOL) fromExpansion;" but when I set a breakpoint nothing crashes. Then I added an "NSLog();" and I saw, that it crashes before calling that delegate methode.

Sometimes there is no exception in the console, but sometimes there is the following message in the console.

2014-11-15 15:20:39.792 MyApp[2566:133071] -[**NSCFType buttonClicked:]: unrecognized selector sent to instance 0x7fa19db67f00
2014-11-15 15:20:39.798 MyApp[2566:133071] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType buttonClicked:]: unrecognized selector sent to instance 0x7fa19db67f00'
* First throw call stack:
(
0 CoreFoundation 0x000000010f3a0f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010f77cbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010f3a804d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010f30027c __forwarding
+ 988
4 CoreFoundation 0x000000010f2ffe18 _CF_forwarding_prep_0 + 120
5 UIKit 0x000000010cde18be -[UIApplication sendAction:to:from:forEvent:] + 75
6 UIKit 0x000000010cee8410 -[UIControl _sendActionsForEvents:withEvent:] + 467
7 UIKit 0x000000010cee77df -[UIControl touchesEnded:withEvent:] + 522
8 UIKit 0x000000010ce27308 -[UIWindow _sendTouchesForEvent:] + 735
9 UIKit 0x000000010ce27c33 -[UIWindow sendEvent:] + 683
10 UIKit 0x000000010cdf49b1 -[UIApplication sendEvent:] + 246
11 UIKit 0x000000010ce01a7d _UIApplicationHandleEventFromQueueEvent + 17370
12 UIKit 0x000000010cddd103 _UIApplicationHandleEventQueue + 1961
13 CoreFoundation 0x000000010f2d6551 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
14 CoreFoundation 0x000000010f2cc41d __CFRunLoopDoSources0 + 269
15 CoreFoundation 0x000000010f2cba54 __CFRunLoopRun + 868
16 CoreFoundation 0x000000010f2cb486 CFRunLoopRunSpecific + 470
17 GraphicsServices 0x0000000111a459f0 GSEventRunModal + 161
18 UIKit 0x000000010cde0420 UIApplicationMain + 1282
19 MyApp 0x000000010b6ce8af MyApp + 2123951
20 libdyld.dylib 0x0000000111f8a145 start + 1
21 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

fillOnTrigger and "flash" before removal of cell

On the demos and when implemented, there is a flash of the cell in its default state before the cell is handled when fillOnTrigger is set.

Is there anyway to keep the cell filled until it is updated or removed?

Bug when there are multiple right buttons and fillOnTrigger is YES

I have multiple right buttons as follows -

cell.rightButtons = @[[MGSwipeButton buttonWithTitle:@"Call" backgroundColor:[UIColor redColor]],
[MGSwipeButton buttonWithTitle:@"Email" backgroundColor:[UIColor blueColor]]];
cell.rightExpansion.fillOnTrigger = YES;
cell.rightExpansion.buttonIndex = 0;

Neither of these buttons delete the cell. If you swipe the cell all the way to left and then try swiping again, you will see only 1 button instead of 2.

showSwipe:animated does not work if the user has not yet swiped

Calling

[self createSwipeViewIfNeeded];

prior to

UIView * buttonsView = direction == MGSwipeDirectionLeftToRight ? leftView : rightView;

fixes the issue. So the new showSwipe implementation looks like this:

-(void) showSwipe: (MGSwipeDirection) direction animated: (BOOL) animated
{
    [self createSwipeViewIfNeeded];
    UIView * buttonsView = direction == MGSwipeDirectionLeftToRight ? leftView : rightView;

    if (buttonsView) {
        CGFloat s = direction == MGSwipeDirectionLeftToRight ? 1.0 : -1.0;
        [self setSwipeOffset:buttonsView.bounds.size.width * s animated:animated completion:nil];
    }
}

Cannot update cell while buttons are open.

Great library, appreciate the work that went in to it.

Swiping cells are taking a snapshot of the cell and overlaying it on the cell in order to allow the buttons to appear. This causes a couple bugs.

  1. The cell cannot be edited while the buttons are out. We wanted to have a number in the cell that incremented each time the button was pushed. The overlay can't change.
  2. The overlay isn't updated even when the buttons are hidden again. This causes weird behavior if the text in the cell changes while the tableview is open, since the overlay doesn't change even when the cell contents do.

We hacked our way around this by exposing the prepareForReuse method and resetting the overlay and swiping back out with no animation whenever a button was pushed.
prepareForReuse()
showSwipe(MGSwipeDirectionRightToLeft, animated: false)

It would be nice if there was a way to update the cells when the buttons were open. Issue 1 may be hard to fix properly, but 2 could be fixed pretty easily by setting the overlay to null whenever the buttons are dismissed.

add a subview in SwipeTableCell

Hi there,

i add a subview in cell, and setup the left and right button like your demo code in md file.
everything is worked, but the view I just added on cell can't move while button area open.
they will stay at same place.

here is my code in tableView cellForRowAtIndexPath:
static NSString * reuseIdentifier = @"programmaticCell";
MGSwipeTableCell * cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
cell = [[MGSwipeTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
}

cell.textLabel.text = @"Title";
cell.detailTextLabel.text = @"Detail text";

UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 150, 50)];
testLabel.text = @"!$#@%$@#$@#%$@#$@#$#@";
[cell addSubview:testLabel];

//configure left buttons
cell.leftButtons = @[[MGSwipeButton buttonWithTitle:@"" icon:[UIImage imageNamed:@"check.png"] backgroundColor:[UIColor greenColor]],
                     [MGSwipeButton buttonWithTitle:@"" icon:[UIImage imageNamed:@"fav.png"] backgroundColor:[UIColor blueColor]]];
cell.leftSwipeSettings.transition = MGSwipeTransition3D;

//configure right buttons
cell.rightButtons = @[[MGSwipeButton buttonWithTitle:@"Delete" backgroundColor:[UIColor redColor]],
                      [MGSwipeButton buttonWithTitle:@"More" backgroundColor:[UIColor lightGrayColor]]];
cell.rightSwipeSettings.transition = MGSwipeTransition3D;

return cell;

Performance

to increase the overall performance of the table cells:

1.add pod WCFastCell
2. in MGSwipeTableCell.h change class to:

@interface MGSwipeTableCell : WCFastCell

happy?

Changelog and breaking changes

Hey,

just wanted to ask if you can introduce a changelog where you list release changes and breaking changes. This way developers can get a better overview what has change in the project. ๐Ÿ‘

Right expansion animation not working properly

I'm using iOS 8 and objective-c. I'm also seeing the same issue on iOS 7.1 in the simulator.... I took your MailViewController from the MailAppDemo and updated the method below. No other mods were made. What happens is when you swipe to the right, and the swipe reaches the expansion threshold, the left button animates nicely into place. However, when you swipe to the left and reach the threshold, the right button pops into place as if not animated.

-(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) {
            return YES;
        }]];
    }
    else {

        expansionSettings.fillOnTrigger = NO;
        expansionSettings.threshold = 2;

        MGSwipeButton * trash = [MGSwipeButton buttonWithTitle:@"Trash" backgroundColor:[UIColor colorWithRed:1.0 green:59/255.0 blue:50/255.0 alpha:1.0] padding:25 callback:^BOOL(MGSwipeTableCell *sender) {
            return YES;
        }];
        return @[trash];
    }
    return nil;   
}

Add delegate method "swipeTableCellBack"

Using

func swipeTableCell(cell: MGSwipeTableCell!, canSwipe direction: MGSwipeDirection) -> Bool

the delegate is informed when I swipe right or left. However I would like to perform an action when the table cell has reached its default position.

Take the "note app" from apple as an example. When you swipe a note the "new" button changes to "cancel" button. When you swipe back or just tap anywhere, the button changes again to "new".

Update cell contents while swiping

First off, let me just say that this library is awesome! Thank you for making it open-source.

I'm thinking of using this in a table view where some cells might be continuously updated with an NSTimer (they contain timing information) and I've just noticed that if one of those cells that is being updated every 1/50th of a second is swiped, the contents freeze.

I glanced at your implementation of MGSwipeTableCell and sure enough the cell contents are being snapshotted when the swiping begins.

I was wondering if it would be possible to modify MGSwipeTableCell's implementation, such that the updated cell's contents can still be seen even when the user is swiping it...

Thank you.

Swipe twice and base "Delete" button displayed

I had everything working correctly with two right buttons (More & Trash) but I noticed that every so often the "Delete" button would display, which is the default for my UITableView. It was hard to recreate until I swiped left when the "More" and "Trash" buttons were visible. When I swiped left the "More" and "Trash" buttons would be replaced by the "Delete" button.

Not able to swipe to reveal right after scrolling collection view children of cell content view

Hi,

I have attached a project to reproduce the issue.

When a collection view is added to the cell content view, the first swipe is working fine when we are not touching the collection view.

Once we attempt to scroll on the collection view, somehow the touches are messed up and we are not able to swipe to reveal right buttons anymore.

Please run the demo of the following repo for more details.
https://github.com/lovesharyn/MGSwipeTableCellCollectionViewTest

Thank you for your time.

Starting swiping on one cell while another one is open makes the swipe a no-op

  1. Show the MGSwipeButtons for a cell
  2. Try to show the buttons for another cell further down the table view
  3. Note that all that happens is that the first cell closes but nothing happens with the cell you swiped

Maybe there is a good reason for this but in my own testing I found that the UI felt weird when I was trying to open up different menus for different rows (e.g., I swiped the wrong row and want to swipe open the one below). Having to close the one that's open before you can open another one feels like a bit of extra work.

Is this configurable? Could it be?

Crash when using multiple MGSwipeButtons in Swift

Hello!
I am using iOS 8 and Swift.

When I create one MGSwipeButton, it works fine but I have an issue when I create two or more MGSwipeButtons. Here is my code:

let cell: CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier(kCustomCellIdentifier, forIndexPath: indexPath) as CustomTableViewCell

cell.rightButtons = [[MGSwipeButton(title: "Button 1", backgroundColor: UIColor.blackColor())],[MGSwipeButton(title: "Button 2", backgroundColor: UIColor.redColor())]]

My CustomTableViewCell is a sub class of MGSwipeTableCell. My breakpoint stops in this method:

"MGSSwipeTableCell.m"
-(instancetype) initWithButtons:(NSArray*) buttonsArray direction:(MGSwipeDirection) direction
{
CGSize maxSize = CGSizeZero;
for (UIView * button in buttonsArray) {
maxSize.width = MAX(maxSize.width, button.bounds.size.width); // breakpoint here
maxSize.height = MAX(maxSize.height, button.bounds.size.height);
}
[...]
}

And I have this message :
2014-11-18 10:41:34.828 MyProject[13183:2530873] -[Swift._NSSwiftArrayImpl bounds]: unrecognized selector sent to instance 0x7fd8faeab890
2014-11-18 10:56:09.548 MyProject[13183:2530873] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Swift._NSSwiftArrayImpl bounds]: unrecognized selector sent to instance 0x7fd8faeab890'

Thank you for your help! :)

Subclassing MGSwipeTableCell

Hi,

I am trying to use MGSwipeCell in a storyboard based app. I subclassed my table cell views for using custom IBOutlets. Now I changed the Superclass of those classes to "MGSwipeTableCell" and added two left buttons to the cell but I simple can't get the buttons to show up. Do I need to change something in my sub-classes?

Thank you for your work!

Philip

Expansion is not animated correctly

The expansion is not correctly animated when the threshold is reached.
You can reproduce this in the MailAppDemo.

  • Open MailAppDemo
  • Swipe first cell from left to right -> "Mark as read" gets visible
  • Swipe more and more until the threshold is reched

Expected: the blue button animates to the expanded button

Actual: the blue button does not animate, it is expanded immediately

The unexpansion-animation works as expected. You can check this by swiping a few pixels to the left until the threshold is reached -> the button animates correctly to the smaller size. So the "make button smaller" animation is working, the "make button bigger" animation not.

Do you accept pull requests for new features?

I wanted to add a few features to MGSwipeTableCell to match requirements that I have, and think could be useful in general.

โ€ข The ability to add an animation curve to the swipe animation.
โ€ข Being able to make buttons a consistent size, not sizeToFit, the way Apple's implementation in the Mail app is.

I'd be happy to work on these and merge them in if you're friendly to it.

Thanks a lot!

section index title view/bar overlaps right utility button(s) when swiping right-to-left

issue: section index title view/bar overlaps right utility button(s) when swiping right-to-left

options to fix: 1) hide the section index bar when displaying the right utility button(s), and 2) move the right utility buttons further left by the width of the section index bar when displaying the right utility button(s).

I would prefer option 1, since the width of the section index bar may be wider than the width of the rightmost utility button, or in many cases the section index bar could cover a significant portion of the rightmost utility button.

my (hopefully temporary) workaround is to not use section indexes in my tables, which can be quite useful for large tables.

Thanks!

p.s. I have settled on using this code in my soon-to-be-released app. I can live without the section index bar, but I cannot live without this code! Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.