Как создать кнопку "еще", когда пользователь пролистывает ячейку в виде таблицы (как в приложении mail в ios 7)
Я искал эту информацию и здесь, и на форуме Cocoa Touch, но, похоже, не могу найти ответ и надеюсь, что кто-то умнее меня сможет подсказать мне решение.
Я бы хотел, чтобы когда пользователь проводит пальцем по ячейке таблицы, отображалось более одной кнопки редактирования (по умолчанию это кнопка удаления). В приложении Mail для iOS 7 можно провести пальцем, чтобы удалить, но там отображается кнопка "MORE".
Похоже, что в iOS 8 открывает этот API. Намеки на такую функциональность присутствуют в бета-2.
Чтобы получить что-то рабочее, реализовать следующие два метода на ваш UITableView'ы делегата, чтобы получить желаемый эффект (см. Суть для примера).
- tableView:editActionsForRowAtIndexPath:
- tableView:commitEditingStyle:forRowAtIndexPath:
В документации сказано, что метод TableView:commitEditingStyle:forRowAtIndexPath является:
"и не называется Для редактирования действий, используя UITableViewRowAction - действие'ы обработчик будет вызван.&и"
Однако, проводя не'т работать без него. Даже если заглушку метода является пустым, он все еще нуждается в его, сейчас. Это наиболее очевидно ошибка в бета-версии 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.Свифт, и только с помощью этого метода вы получите поведением в ОП скриншот:
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];
}
Я создал новую библиотеку для реализации кнопок swippable, который поддерживает различные переходы и расширяемыми кнопками, как iOS 8 приложение "Почта".
https://github.com/MortimerGoro/MGSwipeTableCell
Данная библиотека совместима со всеми различными способами, чтобы создать инструменту UITableViewCell и протестировано на iOS 5, с iOS 6, iOS 7 и iOS 8.
Вот примеры некоторых переходах:
Границы перехода:
Переход клип
3D перехода:
Джонни'ы ответ является правильным на сайте. Я'м, просто добавив Это ниже в 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...
}
Это (скорее смешно) частный API.
Следующие два метода являются частными и отправили в UITableView'ы делегат:
-(NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
-(void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath;
Они довольно понятны.
Чтобы улучшить Джонни'ы ответьте, это может теперь быть сделано с помощью публичного 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];
}
Надеюсь, вы не можете ждать, пока Apple даст вам то, что вам нужно? Так что вот мой вариант.
Создайте пользовательскую ячейку. Иметь в ней два uiview
1. upper
2. lower
В нижнем представлении добавьте любые кнопки, которые вам нужны. Разберитесь с ее действиями так же как и с любыми другими IBActions. Вы можете выбрать время анимации, стиль и все что угодно.
Теперь добавьте uiswipegesture в верхний вид и откройте нижний вид по жесту пролистывания. Я уже делал это раньше, и это самый простой вариант, насколько я понимаю.
Надеюсь, это поможет.
Свифт 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]
}
}
Это невозможно с помощью стандартного SDK. Однако существуют различные сторонние решения, которые более или менее имитируют поведение в Mail.app. Некоторые из них (например, MCSwipeTableViewCell, DAContextMenuTableViewController, RMSwipeTableViewCell) определяют пролистывание с помощью распознавателей жестов, некоторые (например. SWTableViewCell) помещают второй UISScrollView ниже стандартного UITableViewCellScrollView
(частное вложенное представление UITableViewCell
), а некоторые из них изменяют поведение UITableViewCellScrollView
.
Мне больше всего нравится последний подход, так как работа с прикосновениями кажется наиболее естественной. В частности, хорошо подходит MSCMoreOptionTableViewCell. Ваш выбор может варьироваться в зависимости от ваших конкретных потребностей (нужно ли вам панорамирование слева направо, нужна ли совместимость с iOS 6 и т.д.). Также имейте в виду, что большинство из этих подходов несут в себе бремя: они могут легко сломаться в будущей версии iOS, если Apple внесет изменения в иерархию подпрограмм UITableViewCell
.
Вам нужно подкласс UITableViewCell
и подкласс метода willTransitionToState:(UITableViewCellStateMask)state
, который вызывается каждый раз, когда пользователь проводит пальцем по ячейке. Флаги state
позволят вам узнать, отображается ли кнопка Delete, и показать/скрыть вашу кнопку More.
К сожалению, этот метод не дает вам ни ширины кнопки Delete, ни времени анимации. Поэтому вам нужно в коде жестко закодировать кадр и время анимации кнопки More (лично я считаю, что Apple должна что-то с этим сделать).
Для быстрого программирования
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
deleteModelAt(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
else if editingStyle == UITableViewCellEditingStyle.Insert {
println("insert editing action")
}
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
var archiveAction = UITableViewRowAction(style: .Default, title: "Archive",handler: { (action: UITableViewRowAction!, indexPath: NSIndexPath!) in
// maybe show an action sheet with more options
self.tableView.setEditing(false, animated: false)
}
)
archiveAction.backgroundColor = UIColor.lightGrayColor()
var deleteAction = UITableViewRowAction(style: .Normal, title: "Delete",
handler: { (action: UITableViewRowAction!, indexPath: NSIndexPath!) in
self.deleteModelAt(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic);
}
);
deleteAction.backgroundColor = UIColor.redColor()
return [deleteAction, archiveAction]
}
func deleteModelAt(index: Int) {
//... delete logic for model
}
ЭТО МОЖЕТ ПОМОЧЬ ВАМ.
-(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...
}
Я искал, чтобы добавить такую же функциональность в мое приложение, и пройдя через так много различных учебников (raywenderlich лучшие поделки решение), я узнал, что Apple, имеет свой собственный `UITableViewRowAction'class, что очень удобно.
Вы должны изменить метод TableView'ы boilerpoint метод для этого:
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject]? {
// 1
var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
// 2
let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .ActionSheet)
let twitterAction = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
shareMenu.addAction(twitterAction)
shareMenu.addAction(cancelAction)
self.presentViewController(shareMenu, animated: true, completion: nil)
})
// 3
var rateAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Rate" , handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in
// 4
let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .ActionSheet)
let appRateAction = UIAlertAction(title: "Rate", style: UIAlertActionStyle.Default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)
rateMenu.addAction(appRateAction)
rateMenu.addAction(cancelAction)
self.presentViewController(rateMenu, animated: true, completion: nil)
})
// 5
return [shareAction,rateAction]
}
Вы можете узнать больше об этом на этом сайте. Яблоко'ы документации - это очень полезно для изменения цвета фона:
цвет фона кнопки действия.
В декларации цель-с свойство @(неатомической, копия) UIColor *свойство backgroundColor обсуждения используйте это свойство, чтобы указать цвет фона для кнопки. Если не указать значение для это свойство, программирования с использованием UIKit присваивает цвет по умолчанию на основе значения в свойство стиля.
наличие доступен на iOS 8.0 и позже.
Если вы хотите изменить шрифт кнопки, это'ы немного сложнее. Я'видел [другая] сообщение4 о так. Ради того, чтобы предоставить код, а также ссылку, Здесь's в коде они есть. Вы'd должны изменить внешний вид кнопки. Вы'd нужно было дать конкретную ссылку на tableviewcell, в противном случае вы'd изменение кнопка's возникновение во всем приложении (я не'т, что хотите, но, возможно, я не'т знаю :) )
Цель C:
+ (void)setupDeleteRowActionStyleForUserCell {
UIFont *font = [UIFont fontWithName:@"AvenirNext-Regular" size:19];
NSDictionary *attributes = @{NSFontAttributeName: font,
NSForegroundColorAttributeName: [UIColor whiteColor]};
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString: @"DELETE"
attributes: attributes];
/*
* We include UIView in the containment hierarchy because there is another button in UserCell that is a direct descendant of UserCell that we don't want this to affect.
*/
[[UIButton appearanceWhenContainedIn:[UIView class], [UserCell class], nil] setAttributedTitle: attributedTitle
forState: UIControlStateNormal];
}
Свифт:
//create your attributes however you want to
let attributes = [NSFontAttributeName: UIFont.systemFontOfSize(UIFont.systemFontSize())] as Dictionary!
//Add more view controller types in the []
UIButton.appearanceWhenContainedInInstancesOfClasses([ViewController.self])
Это самый простой, и наиболее модернизированный вариант ИМХО. Надеюсь, что это помогает.
Обновление: здесь'ы SWIFT-версия 3.0:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
var shareAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: "Share", handler: {(action, cellIndexpath) -> Void in
let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .actionSheet)
let twitterAction = UIAlertAction(title: "Twitter", style: .default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
shareMenu.addAction(twitterAction)
shareMenu.addAction(cancelAction)
self.present(shareMenu,animated: true, completion: nil)
})
var rateAction:UITableViewRowAction = UITableViewRowAction(style: .default, title: "Rate" , handler: {(action, cellIndexpath) -> Void in
// 4
let rateMenu = UIAlertController(title: nil, message: "Rate this App", preferredStyle: .actionSheet)
let appRateAction = UIAlertAction(title: "Rate", style: .default, handler: nil)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
rateMenu.addAction(appRateAction)
rateMenu.addAction(cancelAction)
self.present(rateMenu, animated: true, completion: nil)
})
// 5
return [shareAction,rateAction]
}
Фактическое Свифт 3 Ответа
Это единственная функция вам нужна. Вам не нужно CanEdit или функции CommitEditingStyle для пользовательских действий.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action1 = UITableViewRowAction(style: .default, title: "Action1", handler: {
(action, indexPath) in
print("Action1")
})
action1.backgroundColor = UIColor.lightGray
let action2 = UITableViewRowAction(style: .default, title: "Action2", handler: {
(action, indexPath) in
print("Action2")
})
return [action1, action2]
}
Начиная с iOS 11 это публично доступен в UITableViewDelegate`. Здесь's некоторые примеры кода:
- (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;
}
Также в наличии:
- (UISwipeActionsConfiguration *)TableView для:(UITableView *)TableView для leadingSwipeActionsConfigurationforrowatindexpath:(NSIndexPath *)indexPath;
Документы: https://developer.apple.com/documentation/uikit/uitableviewdelegate/2902367-tableview?language=objc
Свифт 4 & Ио 11+
@available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .destructive, title: "Delete") { _, _, handler in
handler(true)
// handle deletion here
}
let more = UIContextualAction(style: .normal, title: "More") { _, _, handler in
handler(true)
// handle more here
}
return UISwipeActionsConfiguration(actions: [delete, more])
}
Я tableViewCell, чтобы показать несколько данных, после салфетки () справа налево по мобильному он покажет две кнопки одобрить и отклонить, существует два способа, первый-ApproveFunc, которая принимает один аргумент, и еще один RejectFunc который принимает один аргумент.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let Approve = UITableViewRowAction(style: .normal, title: "Approve") { action, index in
self.ApproveFunc(indexPath: indexPath)
}
Approve.backgroundColor = .green
let Reject = UITableViewRowAction(style: .normal, title: "Reject") { action, index in
self.rejectFunc(indexPath: indexPath)
}
Reject.backgroundColor = .red
return [Reject, Approve]
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func ApproveFunc(indexPath: IndexPath) {
print(indexPath.row)
}
func rejectFunc(indexPath: IndexPath) {
print(indexPath.row)
}
Есть удивительная библиотека SwipeCellKit
, он должен получить больше признания. На мой взгляд это круче, чем MGSwipeTableCell
. Последний не't полностью копируют поведение почтового приложения's ячеек, тогда как SwipeCellKit
делает. Посмотреть
Здесь'ы довольно хрупкий способ сделать это, что не предполагает частных API или строить свою собственную систему. Вы'вновь хеджирования свои ставки, что Apple не'т сломать это и надеюсь, что они выпустят API, который вы можете заменить эти несколько строк кода.
Это также требует, чтобы вы реализовали стандартный вид таблиц для редактирования вызовы делегатов.
static char kObserveContext = 0;
@implementation KZTableViewCell {
UIScrollView *_contentScrollView;
UIView *_confirmationView;
UIButton *_editButton;
UIButton *_deleteButton;
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_contentScrollView = (id)self.contentView.superview;
[_contentScrollView.layer addObserver:self
forKeyPath:@"sublayers"
options:0
context:&kObserveContext];
_editButton = [UIButton new];
_editButton.backgroundColor = [UIColor lightGrayColor];
[_editButton setTitle:@"Edit" forState:UIControlStateNormal];
[_editButton addTarget:self
action:@selector(_editTap)
forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
-(void)dealloc {
[_contentScrollView.layer removeObserver:self forKeyPath:@"sublayers" context:&kObserveContext];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if(context != &kObserveContext) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
if(object == _contentScrollView.layer) {
for(UIView * view in _contentScrollView.subviews) {
if([NSStringFromClass(view.class) hasSuffix:@"ConfirmationView"]) {
_confirmationView = view;
_deleteButton = [view.subviews objectAtIndex:0];
CGRect frame = _confirmationView.frame;
CGRect frame2 = frame;
frame.origin.x -= frame.size.width;
frame.size.width *= 2;
_confirmationView.frame = frame;
frame2.origin = CGPointZero;
_editButton.frame = frame2;
frame2.origin.x += frame2.size.width;
_deleteButton.frame = frame2;
[_confirmationView addSubview:_editButton];
break;
}
}
return;
}
}
-(void)_editTap {
UITableView *tv = (id)self.superview;
while(tv && ![tv isKindOfClass:[UITableView class]]) {
tv = (id)tv.superview;
}
id<UITableViewDelegate> delegate = tv.delegate;
if([delegate respondsToSelector:@selector(tableView:editTappedForRowWithIndexPath:)]) {
NSIndexPath *ip = [tv indexPathForCell:self];
// define this in your own protocol
[delegate tableView:tv editTappedForRowWithIndexPath:ip];
}
}
@end
Свифт 4
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .destructive, title: "Delete") { (action, sourceView, completionHandler) in
print("index path of delete: \(indexPath)")
completionHandler(true)
}
let rename = UIContextualAction(style: .normal, title: "Edit") { (action, sourceView, completionHandler) in
print("index path of edit: \(indexPath)")
completionHandler(true)
}
let swipeActionConfig = UISwipeActionsConfiguration(actions: [rename, delete])
swipeActionConfig.performsFirstActionWithFullSwipe = false
return swipeActionConfig
}
Здесь есть одно простое решение. Он способен отображать и скрывать пользовательские наследник UIView внутри инструменту UITableViewCell. Отображение логика содержится внутри класса продлен с инструменту UITableViewCell, BaseTableViewCell.
BaseTableViewCell.ч
#import <UIKit/UIKit.h>
@interface BaseTableViewCell : UITableViewCell
@property(nonatomic,strong)UIView* customView;
-(void)showCustomView;
-(void)hideCustomView;
@end
BaseTableViewCell.М
#import "BaseTableViewCell.h"
@interface BaseTableViewCell()
{
BOOL _isCustomViewVisible;
}
@end
@implementation BaseTableViewCell
- (void)awakeFromNib {
// Initialization code
}
-(void)prepareForReuse
{
self.customView = nil;
_isCustomViewVisible = NO;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)showCustomView
{
if(nil != self.customView)
{
if(!_isCustomViewVisible)
{
_isCustomViewVisible = YES;
if(!self.customView.superview)
{
CGRect frame = self.customView.frame;
frame.origin.x = self.contentView.frame.size.width;
self.customView.frame = frame;
[self.customView willMoveToSuperview:self.contentView];
[self.contentView addSubview:self.customView];
[self.customView didMoveToSuperview];
}
__weak BaseTableViewCell* blockSelf = self;
[UIView animateWithDuration:.5 animations:^(){
for(UIView* view in blockSelf.contentView.subviews)
{
CGRect frame = view.frame;
frame.origin.x = frame.origin.x - blockSelf.customView.frame.size.width;
view.frame = frame;
}
}];
}
}
}
-(void)hideCustomView
{
if(nil != self.customView)
{
if(_isCustomViewVisible)
{
__weak BaseTableViewCell* blockSelf = self;
_isCustomViewVisible = NO;
[UIView animateWithDuration:.5 animations:^(){
for(UIView* view in blockSelf.contentView.subviews)
{
CGRect frame = view.frame;
frame.origin.x = frame.origin.x + blockSelf.customView.frame.size.width;
view.frame = frame;
}
}];
}
}
}
@end
Чтобы получить эту функциональность, просто продлить ваш вид таблицы ячейки из BaseTableViewCell.
Далее Внутри для UIViewController, который реализовать UITableViewDelegate, создать два жест распознаватели для обработки левой и правой пойло.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.tableView registerNib:[UINib nibWithNibName:CUSTOM_CELL_NIB_NAME bundle:nil] forCellReuseIdentifier:CUSTOM_CELL_ID];
UISwipeGestureRecognizer* leftSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipe:)];
leftSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[self.tableView addGestureRecognizer:leftSwipeRecognizer];
UISwipeGestureRecognizer* rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipe:)];
rightSwipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self.tableView addGestureRecognizer:rightSwipeRecognizer];
}
Чем добавить две салфетки обработчики
- (void)handleLeftSwipe:(UISwipeGestureRecognizer*)recognizer
{
CGPoint point = [recognizer locationInView:self.tableView];
NSIndexPath* index = [self.tableView indexPathForRowAtPoint:point];
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:index];
if([cell respondsToSelector:@selector(showCustomView)])
{
[cell performSelector:@selector(showCustomView)];
}
}
- (void)handleRightSwipe:(UISwipeGestureRecognizer*)recognizer
{
CGPoint point = [recognizer locationInView:self.tableView];
NSIndexPath* index = [self.tableView indexPathForRowAtPoint:point];
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:index];
if([cell respondsToSelector:@selector(hideCustomView)])
{
[cell performSelector:@selector(hideCustomView)];
}
}
Теперь, внутри cellForRowAtIndexPath, в UITableViewDelegate, вы можете создавать пользовательские наследник UIView и прикрепить его к удалены из очереди ячейки.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCellTableViewCell* cell = (CustomCellTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"CustomCellTableViewCell" forIndexPath:indexPath];
NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"CellCustomView"
owner:nil
options:nil];
CellCustomView* customView = (CellCustomView*)[ nibViews objectAtIndex: 0];
cell.customView = customView;
return cell;
}
Конечно, этот способ загрузки пользовательских наследник UIView только для этого примера. Управлять, как вы хотите.