如何在 UITableView Cell 中实现类似于 iOS 邮件的从左向右滑动
Posted
技术标签:
【中文标题】如何在 UITableView Cell 中实现类似于 iOS 邮件的从左向右滑动【英文标题】:How to Implement Swipe Left to Right in UITableView Cell similar to iOS Mail 【发布时间】:2014-11-16 08:46:48 【问题描述】:我正在尝试复制 Apple 在其邮件应用程序中使用的相同技术,当您在邮箱内从左向右滑动时,将邮件标记为未读或“标记为未读”。
我找到了similarsolutions,但仅用于从右向左滑动的手势。我希望同样的解决方案可以作为 Apple SDK 的一部分用于相反的方向。
如何实现与 iOS 邮件应用相同的从左到右手势效果?
【问题讨论】:
我在我的应用程序中使用了这个库,效果很好:github.com/Dromaguirre/PDGestureTableView 有一个很棒的库MGSwipeTableCell。需要像ios Mail app那样实现滑动效果的大家,推荐使用。 【参考方案1】:我找到了类似的解决方案,但只是从滑动手势 从右到左。
SWTableViewCell 拥有您可能需要的所有选项。
在对单元进行出队时,只需根据需要设置左/右按钮集。
cell.leftUtilityButtons = [self leftButtons];
cell.rightUtilityButtons = [self rightButtons];
cell.delegate = self;
通过将视图控制器设置为其委托,您可以监听按钮的点击。 有关如何实施的完整详细信息在该链接中
例 1:
例 2:
如果您正在寻找垂直堆叠的按钮,请查看this。
【讨论】:
@gh0st 如何在android中实现类似的效果?他们有图书馆吗? @gh0st 如何在Android中实现类似的效果?它看起来很酷。有图书馆什么的吗? 我不确定@NiteshKhatri,我还没有在 Android 上实现它。控制它的库是为 iOS 设备编写的。 有没有人尝试这个版本只是为了触摸单元格,然后单元格滑动? @Florjon 只需添加点击手势而不是滑动手势。【参考方案2】:我通常在表级别实现它。
- (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];
然后您可以控制方向并可以随意自定义
- (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];
归功于Jade Mind
【讨论】:
这个正确答案应该是没有在项目中实现第三方库的答案。由于苹果对接受应用程序非常严格,因此限制这种可能性是可以选择的。这一篇解释了开发者如何获取 leftToRight 滑动的gestureRecognizer。【参考方案3】:从 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
这些方法返回一个包含UIContextualAction
数组的UISwipeActionsConfiguration
对于UIContextualAction
,您可以指定其标题、样式、背景颜色、动作颜色,甚至是UIImage
并处理其回调(显然:-))
这是一个示例实现:
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])
我知道这是一个老问题,但我发布这个只是为了以防它帮助随机路过的人......
【讨论】:
您可以在 func 之前添加“覆盖”,但这很好,谢谢 :) @Moitah 覆盖UITableViewDataSource
时需要覆盖,但如果你不这样做,则不需要override
。
这很奇怪,我继承 UITableViewController 和 Xcode 仍然是我需要 override 关键字。对我来说这似乎是合乎逻辑的,因为该方法来自 UITableViewDelegate ?谢谢【参考方案4】:
你可以在 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])
【讨论】:
【参考方案5】:您提供的链接中接受的答案适用于两个滑动方向。
请注意,gestureRecognizer.direction
为 UISwipeGestureRecognizerDirectionLeft
和 UISwipeGestureRecognizerDirectionRight
返回 YES
。
您只需要修改几处: 更改在滑动时调用的选择器,因此它将调用您的方法,而不是帖子示例中的方法, 并将滑动方向更改为仅从左到右,而不是当前的两个方向,因为据我了解,您正在尝试设置单向滑动。
所以你的代码应该是这样的:
// 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;
请注意,您也可以使用已接受答案下方的答案,只需将手势识别器direction
属性修改为UISwipeGestureRecognizerDirectionRight
,而不是示例中的当前方向,即UISwipeGestureRecognizerDirectionLeft
。
如果您选择实现这一点,您的 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? ...
注意——如果我没记错的话,你需要自己创建单元格滑动动画,因为我相信 Xcode 的默认单元格动画只有在向左滑动时才会出现。
信用来自您提供的链接的MadhavanRP
和Julian
。我刚刚修改了他们的答案以更好地满足您的需求。
不过,我自己还没有尝试并实现过。
【讨论】:
我真的希望得到一个更简单的答案,比如[buttonAction setAlignment:left]
或类似的东西。我想这并不容易。你认为这是 Apple 实现相同功能的方式吗?
我真的不知道。但是这段代码非常简单。虽然我自己没有测试过,但实现起来似乎并不复杂。试试吧,伙计,如果你需要帮助,尽管问。【参考方案6】:
将您的自定义 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]];
【讨论】:
以上是关于如何在 UITableView Cell 中实现类似于 iOS 邮件的从左向右滑动的主要内容,如果未能解决你的问题,请参考以下文章
在 Scala Slick 中实现类实例成员修改的最佳方法?