Guy*_*lon 246 user-interface cocoa-touch uitableview ios swipe-gesture
用户在表格视图中滑动单元格时如何创建"更多"按钮(如ios 7中的邮件应用程序)
我一直在这里和Cocoa Touch论坛上寻找这些信息,但我似乎无法找到答案,我希望比我更聪明的人能给我一个解决方案.
我希望当用户滑动表格视图单元格时,显示多个编辑按钮(默认为删除按钮).在iOS 7的Mail应用程序中,您可以滑动删除,但会显示一个"更多"按钮.

Joh*_*nny 126
看起来iOS 8打开了这个API.Beta 2中提供了此类功能的提示.
要使某些工作正常,请在UITableView的委托上实现以下两种方法以获得所需的效果(请参阅gist以获取示例).
- tableView:editActionsForRowAtIndexPath:
- tableView:commitEditingStyle:forRowAtIndexPath:
Run Code Online (Sandbox Code Playgroud)
文档说tableView:commitEditingStyle:forRowAtIndexPath是:
"不使用UITableViewRowAction调用编辑操作 - 将调用操作的处理程序."
但是,如果没有它,滑动就无法工作.即使方法存根是空白的,它现在仍然需要它.这显然是beta 2中的一个错误.
https://twitter.com/marksands/status/481642991745265664 https://gist.github.com/marksands/76558707f583dbb8f870
原答案:https://stackoverflow.com/a/24540538/870028
这个工作的示例代码(在Swift中):http://dropbox.com/s/0fvxosft2mq2v5m/DeleteRowExampleSwift.zip
示例代码在MasterViewController.swift中包含这个易于理解的方法,只需使用此方法,您就可以获得OP屏幕截图中显示的行为:
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "More", handler:{action, indexpath in
println("MORE•ACTION");
});
moreRowAction.backgroundColor = UIColor(red: 0.298, green: 0.851, blue: 0.3922, alpha: 1.0);
var deleteRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete", handler:{action, indexpath in
println("DELETE•ACTION");
});
return [deleteRowAction, moreRowAction];
}
Run Code Online (Sandbox Code Playgroud)
Mor*_*oro 121
我创建了一个新的库来实现可交换按钮,它支持各种转换和可扩展按钮,如iOS 8邮件应用程序.
https://github.com/MortimerGoro/MGSwipeTableCell
该库兼容所有不同的创建UITableViewCell的方法,并在iOS 5,iOS 6,iOS 7和iOS 8上进行测试.
这里有一些过渡的样本:
边境过渡:

剪辑转换

3D过渡:

tim*_*ykc 71
约翰尼的回答是正确的回答.我只是在objective-c中添加以下内容,以使初学者(以及那些拒绝学习Swift语法的人)更清楚:)
确保声明uitableviewdelegate并具有以下方法:
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *button = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Button 1" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(@"Action to perform with Button 1");
}];
button.backgroundColor = [UIColor greenColor]; //arbitrary color
UITableViewRowAction *button2 = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"Button 2" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath)
{
NSLog(@"Action to perform with Button2!");
}];
button2.backgroundColor = [UIColor blueColor]; //arbitrary color
return @[button, button2]; //array with all the buttons you want. 1,2,3, etc...
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// you need to implement this method too or nothing will work:
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES; //tableview must be editable or nothing will work...
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*an. 25
这是(相当荒谬)一个私有API.
以下两个方法是私有的并发送到UITableView的委托:
-(NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath;
Run Code Online (Sandbox Code Playgroud)
他们非常自我解释.
Aru*_*Das 24
为了改进Johnny的答案,现在可以使用公共API完成此操作,如下所示:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let moreRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "More", handler:{action, indexpath in
print("MORE•ACTION");
});
moreRowAction.backgroundColor = UIColor(red: 0.298, green: 0.851, blue: 0.3922, alpha: 1.0);
let deleteRowAction = UITableViewRowAction(style: UITableViewRowActionStyle.default, title: "Delete", handler:{action, indexpath in
print("DELETE•ACTION");
});
return [deleteRowAction, moreRowAction];
}
Run Code Online (Sandbox Code Playgroud)
Dee*_*yan 17
我希望你不能等到苹果给你什么,你需要什么?所以这是我的选择.
创建自定义单元格.有两个uiviews
1. upper
2. lower
Run Code Online (Sandbox Code Playgroud)
在下方视图中,添加您需要的按钮.像任何其他IBActions一样处理其行为.你可以决定动画的时间,风格和任何东西.
现在在上方视图中添加一个uiswipegesture,并在滑动手势上显示您的下方视图.我以前做过这个,就我而言,它是最简单的选择.
希望有所帮助.
使用标准SDK无法做到这一点.但是,有各种第三方解决方案或多或少地模仿Mail.app中的行为.其中一些(例如MCSwipeTableViewCell,DAContextMenuTableViewController,RMSwipeTableViewCell)使用手势识别器检测滑动,其中一些(例如SWTableViewCell)将第二个UISScrollView放在标准UITableViewCellScrollView(私有子视图UITableViewCell)之下,其中一些修改了它们的行为UITableViewCellScrollView.
我最喜欢最后一种方法,因为触摸处理感觉最自然.具体来说,MSCMoreOptionTableViewCell很好.您的选择可能会根据您的具体需求而有所不同(无论您是否需要从左到右的平底锅,是否需要iOS 6兼容性等).还要注意,大多数这些方法都有负担:如果Apple在UITableViewCell子视图层次结构中进行更改,它们很容易在未来的iOS版本中中断.
Swift 3版本代码,不使用任何库:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.tableFooterView = UIView(frame: CGRect.zero) //Hiding blank cells.
tableView.separatorInset = UIEdgeInsets.zero
tableView.dataSource = self
tableView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
return cell
}
//Enable cell editing methods.
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let more = UITableViewRowAction(style: .normal, title: "More") { action, index in
//self.isEditing = false
print("more button tapped")
}
more.backgroundColor = UIColor.lightGray
let favorite = UITableViewRowAction(style: .normal, title: "Favorite") { action, index in
//self.isEditing = false
print("favorite button tapped")
}
favorite.backgroundColor = UIColor.orange
let share = UITableViewRowAction(style: .normal, title: "Share") { action, index in
//self.isEditing = false
print("share button tapped")
}
share.backgroundColor = UIColor.blue
return [share, favorite, more]
}
}
Run Code Online (Sandbox Code Playgroud)
您需要子类化UITableViewCell和子类化方法willTransitionToState:(UITableViewCellStateMask)state,只要用户刷新单元格就会调用该方法.该state标志将让你知道,如果删除按钮被显示,并显示/隐藏您的更多按钮那里.
不幸的是,这种方法既不提供删除按钮的宽度也不提供动画时间.因此,您需要观察并将您的更多按钮的帧和动画时间硬编码到您的代码中(我个人认为Apple需要对此做些什么).
从 iOS 11 开始,这在UITableViewDelegate. 这是一些示例代码:
迅速
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: nil) { (_, _, _) in
print("Swipe action tapped")
}
action.image = UIImage(systemName: "plus.slash.minus")
action.backgroundColor = .green
return UISwipeActionsConfiguration(actions: [action])
}
Run Code Online (Sandbox Code Playgroud)
目标C
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive
title:@"DELETE"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
NSLog(@"index path of delete: %@", indexPath);
completionHandler(YES);
}];
UIContextualAction *rename = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal
title:@"RENAME"
handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
NSLog(@"index path of rename: %@", indexPath);
completionHandler(YES);
}];
UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[rename, delete]];
swipeActionConfig.performsFirstActionWithFullSwipe = NO;
return swipeActionConfig;
}
Run Code Online (Sandbox Code Playgroud)
也提供:
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath;
文档:https://developer.apple.com/documentation/uikit/uitableviewdelegate/2902367-tableview ?language=objc
| 归档时间: |
|
| 查看次数: |
124295 次 |
| 最近记录: |