简体   繁体   English

如何在类似于 iOS 邮件的 UITableView Cell 中实现从左到右滑动

[英]How to Implement Swipe Left to Right in UITableView Cell similar to iOS Mail

I'm trying to replicate the same technique that Apple uses in their mail app for marking mail as unread or "Mark as Unread" when you swipe from left to right inside a mailbox.我正在尝试复制 Apple 在其邮件应用程序中使用的相同技术,用于在邮箱内从左向右滑动时将邮件标记为未读或“标记为未读”。

iOS 8.1 邮件应用程序中邮件的屏幕截图

I've found similar solutions but only for a gesture of swiping from right to left.我找到了类似的解决方案,但仅适用于从右向左滑动的手势。 I was hoping that this same solution was available as part of the Apple SDK for the opposite direction.我希望这个相同的解决方案可以作为 Apple SDK 的一部分用于相反的方向。

How can I acheive the same left-to-right gesture effect as iOS' Mail app does?如何获得与 iOS 的邮件应用程序相同的从左到右的手势效果?

I've found similar solutions but only for a gesture of swiping from right to left.我找到了类似的解决方案,但仅适用于从右向左滑动的手势

SWTableViewCell has all the options you might want. SWTableViewCell拥有您可能需要的所有选项。

While dequeing a cell just set up left/right set of buttons as needed.出列单元格时,只需根据需要设置左/右按钮组。

cell.leftUtilityButtons = [self leftButtons];
cell.rightUtilityButtons = [self rightButtons];
cell.delegate = self;

And by setting the view controller as its delegate, you can listen to the button clicks.通过将视图控制器设置为其委托,您可以收听按钮点击。 Full details on how to implement are in that link有关如何实施的完整详细信息在该链接中

Ex 1:例 1:

在此处输入图片说明

Ex 2:例 2:在此处输入图片说明

In case you are looking for buttons stacked vertically check out this .如果您正在寻找垂直堆叠的按钮,请查看

I usually implement it at the table level.我通常在表级别实现它。

- (void)viewDidLoad
{
    [super viewDidLoad];

    UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                                                  action:@selector(leftSwipe:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    [self.tableView addGestureRecognizer:recognizer];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                        action:@selector(rightSwipe:)];
    recognizer.delegate = self;
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
    [self.tableView addGestureRecognizer:recognizer];
}

You then have control of the direction and can customize at will然后您就可以控制方向并可以随意自定义

- (void)leftSwipe:(UISwipeGestureRecognizer *)gestureRecognizer
{
    //do you left swipe stuff here. 
}

- (void)rightSwipe:(UISwipeGestureRecognizer *)gestureRecognizer
{
    //do you right swipe stuff here. Something usually using theindexPath that you get that way
    CGPoint location = [gestureRecognizer locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
}

Credit goes to Jade Mind归功于Jade Mind

Since iOS 11, there are native provisions(delegate methods through UITableViewDelegate ) to enable 'swipe actions' on a UITableView 's cell on both sides:从 iOS 11 开始,有本机规定(通过UITableViewDelegate委托方法)在两侧的UITableView的单元格上启用“滑动操作”:

func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? //For actions at the left

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? //For actions at the right

These methods return a UISwipeActionsConfiguration that contains an array of UIContextualAction这些方法返回一个UISwipeActionsConfiguration包含数组UIContextualAction

For a UIContextualAction , you can specify its title, style, background colour, action colour, or even an UIImage and handle its callback ( obviously :-) )对于UIContextualAction ,您可以指定其标题、样式、背景颜色、动作颜色,甚至是UIImage并处理其回调(显然 :-) )

Here's a sample implementation:这是一个示例实现:

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

    let filterAction = UIContextualAction(style: .normal, title: "FILTER") { (action, view, bool) in
        print("Swiped to filter")
    }
    filterAction.backgroundColor = UIColor.blue

    return UISwipeActionsConfiguration(actions: [filterAction])
}

I know this is an old question, but I'm posting this just in case it helps someone randomly passing by...我知道这是一个老问题,但我发布这个只是为了帮助有人随机经过......

You can do that in Swift 5 with this:你可以在 Swift 5 中这样做:

func tableView(_ tableView: UITableView,
                leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
    let closeAction = UIContextualAction(style: .normal, title:  "Close", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
        print("OK, marked as Closed")
        success(true)
    })
    closeAction.image = UIImage(named: "tick")
    closeAction.backgroundColor = .purple
 
    return UISwipeActionsConfiguration(actions: [closeAction])
}
 
func tableView(_ tableView: UITableView,
                trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
    let modifyAction = UIContextualAction(style: .normal, title:  "Update", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
        print("Update action ...")
        success(true)
    })
    modifyAction.image = UIImage(named: "hammer")
    modifyAction.backgroundColor = .blue
 
    return UISwipeActionsConfiguration(actions: [modifyAction])
}

The accepted answer in the link you've provided is for both swipes directions.您提供的链接中接受的答案适用于两个滑动方向。
Notice that gestureRecognizer.direction returns YES both for UISwipeGestureRecognizerDirectionLeft and UISwipeGestureRecognizerDirectionRight .请注意,对于UISwipeGestureRecognizerDirectionLeftUISwipeGestureRecognizerDirectionRightgestureRecognizer.direction返回YES

You'll just need to modify a couple of things:你只需要修改几件事情:
Change the selector that get's called upon swiping, so it'll call your method, instead of the one in the post's example,更改在滑动时调用的选择器,因此它会调用您的方法,而不是帖子示例中的方法,
And change the direction of the swipe to be from left to right only, and not for both directions as it currently is, since, as I understand, you are trying to set a one-direction swipe.并将滑动方向更改为仅从左到右,而不是像目前这样的两个方向,因为据我了解,您正在尝试设置单向滑动。

So your code should look like this:所以你的代码应该是这样的:

// In cellForRowAtIndexPath:, where you create your custom cell  
cell.tableView=tableView;  
cell.indexPath=indexPath;
UISwipeGestureRecognizer *swipeGestureRecognizer=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(YOUR_METHOD_GOES_HERE)];
[cell addGestureRecognizer:swipeGestureRecognizer];  

. .

-(BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {  
    if([[gestureRecognizer view] isKindOfClass:[UITableViewCell class]] && ((UISwipeGestureRecognizer*)gestureRecognizer.direction==UISwipeGestureRecognizerDirectionRight)  
        return YES;  
}

Note that you could also use the answer below the accepted answer, and just modify the gesture recogniser direction property to be UISwipeGestureRecognizerDirectionRight , instead of the current direction in the example, which is UISwipeGestureRecognizerDirectionLeft .请注意,您还可以使用已接受答案下方的答案,只需将手势识别器direction属性修改为UISwipeGestureRecognizerDirectionRight ,而不是示例中的当前方向UISwipeGestureRecognizerDirectionLeft

If you choose to implement this, your viewController must implement the gesture recogniser delegate, and your code should look like this:如果您选择实现这一点,您的 viewController 必须实现手势识别器委托,您的代码应如下所示:

// Call this method in viewDidLoad  
- (void)setUpLeftSwipe {  
    UISwipeGestureRecognizer *recognizer;  
    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                   action:@selector(swipeRightt:)];  
    [recognizer setDirection:UISwipeGestureRecognizerDirectionRight];  
    [self.tableView addGestureRecognizer:recognizer];  
    recognizer.delegate = self;  
}  


- (void)swipeRight:(UISwipeGestureRecognizer *)gestureRecognizer {  
    CGPoint location = [gestureRecognizer locationInView:self.tableView];  
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];  
    ... do something with cell now that i have the indexpath, maybe save the world? ...  
}  

Note- if I'm not mistaken, you'll need to create the cell swiping animation yourself, as, I believe, Xcode's default cell animation is only when swiping left.注意 - 如果我没有记错的话,您需要自己创建单元格滑动动画,因为我相信 Xcode 的默认单元格动画仅在向左滑动时才出现。

Credit goes to MadhavanRP and Julian from the link you've provided.您提供的链接MadhavanRPJulian I just modified their answers to suite better to your needs.我只是修改了他们的答案,以更好地满足您的需求。
I haven't tried and implemented this myself though.不过,我自己还没有尝试过并实施过。

Use your custom TableViewCell with scrollview as given below :将自定义 TableViewCell 与滚动视图一起使用,如下所示:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    return 80;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 120;

}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return header_view;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [array_field1 count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Schedule_cell";

    Custom_Schedule_Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = (Custom_Schedule_Cell *)[Custom_Schedule_Cell cellFromNibNamed:@"Custom_Schedule_Cell"];
    }

    x = 0;

        UILabel *lbl_title =[[UILabel alloc] initWithFrame:CGRectMake(x,0,cell.scroll_view.frame.size.width,cell.scroll_view.frame.size.height)];
        lbl_title.text=@"Title Array";
        [lbl_title setTextAlignment:NSTextAlignmentCenter];
        [lbl_title setFont:[UIFont fontWithName:@"Raleway" size:18.0f]];

        x += lbl_title.frame.size.width+10;

        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(x,0,110,cell.scroll_view.frame.size.height)];
        [button setTitle:@"Button1" forState:UIControlStateNormal];
        [button setBackgroundColor:[UIColor grayColor]];
        [button addTarget:self action:@selector(button1:) forControlEvents:UIControlEventTouchDown];
        button.tag = indexPath.row;
        [button.titleLabel setTextAlignment:NSTextAlignmentCenter];
        [button.titleLabel setFont:[UIFont fontWithName:@"Raleway" size:14.0f]];

    x += button.frame.size.width+5;

    UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(x,0,110,cell.scroll_view.frame.size.height)];
    [button2 setTitle:@"Button2" forState:UIControlStateNormal];
    [button2 setBackgroundColor:[UIColor grayColor]];
    [button2 addTarget:self action:@selector(button2:) forControlEvents:UIControlEventTouchDown];
    button2.tag = indexPath.row;
    [button2.titleLabel setTextAlignment:NSTextAlignmentCenter];
    [button2.titleLabel setFont:[UIFont fontWithName:@"Raleway" size:14.0f]];

    x += button2.frame.size.width+5;


    UIButton *button3 = [[UIButton alloc] initWithFrame:CGRectMake(x,0,110,cell.scroll_view.frame.size.height)];
    [button3 setTitle:@"Button3" forState:UIControlStateNormal];
    [button3 setBackgroundColor:[UIColor grayColor]];
    [button3 addTarget:self action:@selector(button3:) forControlEvents:UIControlEventTouchDown];
    button3.tag = indexPath.row;
    [button3.titleLabel setTextAlignment:NSTextAlignmentCenter];
    [button3.titleLabel setFont:[UIFont fontWithName:@"Raleway" size:14.0f]];

        [cell.scroll_view addSubview:lbl_title];
        [cell.scroll_view addSubview:button];
    [cell.scroll_view addSubview:button2];
    [cell.scroll_view addSubview:button3];

    x += button3.frame.size.width+5;

    cell.scroll_view.contentSize = CGSizeMake(x,cell.scroll_view.frame.size.height);
    cell.scroll_view.showsHorizontalScrollIndicator = NO;
    cell.scroll_view.showsVerticalScrollIndicator = NO;
    [cell.scroll_view setContentOffset:CGPointMake(0,0) animated:NO];
    [cell.scroll_view setPagingEnabled:true];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//    Custom_Schedule_Cell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
//    [selectedCell.scroll_view setContentOffset:CGPointMake(x2,0) animated:NO];

}
-(void)button1:(UIButton *)button
{
    NSLog(@“button1 Click ");
    [button setBackgroundColor:[UIColor redColor]];
}

-(void)button2:(UIButton *)button
{
    NSLog(@“button2 Click");
    [button setBackgroundColor:[UIColor greenColor]];
}

-(void)button3:(UIButton *)button
{
    NSLog(@“button Click");
    [button setBackgroundColor:[UIColor redColor]];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM