2013-10-03 4 views
58

Как сделать пользовательское редактирование в iOS7 UITableView с Objective C, как приложение Evernote или Apple Reminders, когда проведите пальцем влево. Я попытался установить пользовательское editAccessoryView, но это не сработало.Пользовательский режим редактирования в UITableViewCell во время прокрутки влево. Objective-C или Swift

Evernote вид редактирования:

enter image description here Напоминания редактировать вид:

enter image description here

Мой текущий код

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 
    return YES; 
} 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     NSLog(@"delete"); 
    } 
} 

Я попытался решить эту проблему с: (UITableViewController. h)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    //make cell 

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    [view setBackgroundColor:[UIColor greenColor]]; 
    //add Buttons to view 

    cell.editingAccessoryView = view; 

    return cell; 
} 

И то же самое с: (UITableViewCell)

- (void)willTransitionToState:(UITableViewCellStateMask)state; 
- (void)setEditing:(BOOL)editing animated:(BOOL)animated; 
- (UIView*)editingAccessoryView; 

ответ

11

См ссылке: https://github.com/TeehanLax/UITableViewCell-Swipe-for-Options

и настроить UITableViewCell с несколькими кнопки.

UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))]; 
scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.bounds) + kCatchWidth, CGRectGetHeight(self.bounds)); 
scrollView.delegate = self; 
scrollView.showsHorizontalScrollIndicator = NO; 

[self.contentView addSubview:scrollView]; 
self.scrollView = scrollView; 

UIView *scrollViewButtonView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds) - kCatchWidth, 0, kCatchWidth, CGRectGetHeight(self.bounds))]; 
self.scrollViewButtonView = scrollViewButtonView; 
[self.scrollView addSubview:scrollViewButtonView]; 

// Set up our two buttons 
UIButton *moreButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
moreButton.backgroundColor = [UIColor colorWithRed:0.78f green:0.78f blue:0.8f alpha:1.0f]; 
moreButton.frame = CGRectMake(0, 0, kCatchWidth/3.0f, CGRectGetHeight(self.bounds)); 
[moreButton setTitle:@"More" forState:UIControlStateNormal]; 
[moreButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 
[moreButton addTarget:self action:@selector(userPressedMoreButton:) forControlEvents:UIControlEventTouchUpInside]; 

[self.scrollViewButtonView addSubview:moreButton]; 

UIButton *shareButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
shareButton.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f]; 
shareButton.frame = CGRectMake(kCatchWidth/3.0f, 0, kCatchWidth/3.0f, CGRectGetHeight(self.bounds)); 
[shareButton setTitle:@"Share" forState:UIControlStateNormal]; 
[shareButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 
[shareButton addTarget:self action:@selector(userPressedMoreButton:) forControlEvents:UIControlEventTouchUpInside]; 
[self.scrollViewButtonView addSubview:shareButton]; 

UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
deleteButton.backgroundColor = [UIColor colorWithRed:1.0f green:0.231f blue:0.188f alpha:1.0f]; 
deleteButton.frame = CGRectMake(kCatchWidth/3.0f+kCatchWidth/3.0f, 0, kCatchWidth/3.0f, CGRectGetHeight(self.bounds)); 
[deleteButton setTitle:@"Delete" forState:UIControlStateNormal]; 
[deleteButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 
[deleteButton addTarget:self action:@selector(userPressedDeleteButton:) forControlEvents:UIControlEventTouchUpInside]; 
[self.scrollViewButtonView addSubview:deleteButton]; 

UIView *scrollViewContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))]; 
scrollViewContentView.backgroundColor = [UIColor whiteColor]; 
[self.scrollView addSubview:scrollViewContentView]; 
self.scrollViewContentView = scrollViewContentView; 

UILabel *scrollViewLabel = [[UILabel alloc] initWithFrame:CGRectInset(self.scrollViewContentView.bounds, 10, 0)]; 
self.scrollViewLabel = scrollViewLabel; 
[self.scrollViewContentView addSubview:scrollViewLabel]; 
  • Я реализовал этот код с моим приложением получил такой результат. Вы можете добавить количество кнопок в ячейку салфетки.

    Здесь реализуются снимки экрана

    enter image description here После взмаха клетка 3 кнопки появляется "больше", "Share", "Удалить".

+0

**** Это также работает для ios7. –

0

Как я думаю, это не лучший способ использовать ячейки на основе UIGestureRecognizer.

Во-первых, у вас не будет возможности использовать CoreGraphics.

Идеальное решение, будет UIResponder или один UIGestureRecognizer для просмотра всего стола. Не для каждого UITableViewCell. Это заставит вас приложение застрять.

0

создать представление в пользовательской ячейке в виде таблицы и применить PanGestureRecognizer к представлению на ячейке. Добавить кнопки в пользовательскую ячейку, когда вы проведите по экрану в пользовательской ячейке, тогда кнопки на пользовательской ячейке будут быть видимым.

UIGestureRecognizer* recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    recognizer.delegate = self; 
    [YourView addGestureRecognizer:recognizer]; 

И справиться с панорамированием на представлении в методе

if (recognizer.state == UIGestureRecognizerStateBegan) { 
    // if the gesture has just started, record the current centre location 
    _originalCenter = vwCell.center; 
} 

// 2 
if (recognizer.state == UIGestureRecognizerStateChanged) { 
    // translate the center 
    CGPoint translation = [recognizer translationInView:self]; 
    vwCell.center = CGPointMake(_originalCenter.x + translation.x, _originalCenter.y); 
    // determine whether the item has been dragged far enough to initiate/complete 
    _OnDragRelease = vwCell.frame.origin.x < -vwCell.frame.size.width/2; 

} 

// 3 
if (recognizer.state == UIGestureRecognizerStateEnded) { 
    // the frame this cell would have had before being dragged 
    CGPoint translation = [recognizer translationInView:self]; 

    if (_originalCenter.x+translation.x<22) { 
      vwCell.center = CGPointMake(22, _originalCenter.y); 
     IsvwRelease=YES; 

    } 
    CGRect originalFrame = CGRectMake(0, vwCell.frame.origin.y, 
             vwCell.bounds.size.width, vwCell.bounds.size.height); 
    if (!_deleteOnDragRelease) { 
     // if the item is not being dragged far enough , snap back to the original location 
     [UIView animateWithDuration:0.2 
         animations:^{ 
          vwCell.frame = originalFrame; 
         } 
     ]; 
    } 
} 
76

Просто скопируйте вставьте код ниже!

-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { 

     UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Clona" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ 
      //insert your editAction here 
     }]; 
     editAction.backgroundColor = [UIColor blueColor]; 

     UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){ 
      //insert your deleteAction here 
     }]; 
     deleteAction.backgroundColor = [UIColor redColor]; 
return @[deleteAction,editAction]; 
} 
+14

Просто предупреждение для других читателей, это только iOS-8. – Cyrille

+8

Чтобы отобразить их в моем случае, мне также понадобилось реализовать метод dataSource табличного представления - (void) tableView: (UITableView *) tableView commitEditingStyle: (UITableViewCellEditingStyle) editStyle forRowAtIndexPath: (NSIndexPath *) indexPath; Даже пустую реализацию этого метода было достаточно, чтобы отобразить кнопки. – u2Fan

+0

@Cyrille благодарит кирилла за упоминание об этом! –

1
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { 
    let delete = UITableViewRowAction(style: .Destructive, title: "Delete") { (action, indexPath) in 
     // delete item at indexPath 
    } 

    let share = UITableViewRowAction(style: .Normal, title: "Disable") { (action, indexPath) in 
    // share item at indexPath 
    } 

    share.backgroundColor = UIColor.blueColor() 

    return [delete, share] 
} 

Приведенный выше код показывает, как создать для пользовательских кнопок, когда ваш салфетки на строке.

+0

, но салфетка не имеет никакого эффекта! in swift3 Какие-либо другие методы необходимы? – mythicalcoder

+0

'tableView (_, commit :, forRowAt :) {}' как упомянуто выше – nyxee

29

Swift 3

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { 

    let editAction = UITableViewRowAction(style: .normal, title: "Edit") { (rowAction, indexPath) in 
     //TODO: edit the row at indexPath here 
    } 
    editAction.backgroundColor = .blue 

    let deleteAction = UITableViewRowAction(style: .normal, title: "Delete") { (rowAction, indexPath) in 
     //TODO: Delete the row at indexPath here 
    } 
    deleteAction.backgroundColor = .red 

    return [editAction,deleteAction] 
} 

Swift 2,1

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { 
    let editAction = UITableViewRowAction(style: .Normal, title: "Edit") { (rowAction:UITableViewRowAction, indexPath:NSIndexPath) -> Void in 
     //TODO: edit the row at indexPath here 
    } 
    editAction.backgroundColor = UIColor.blueColor() 

    let deleteAction = UITableViewRowAction(style: .Normal, title: "Delete") { (rowAction:UITableViewRowAction, indexPath:NSIndexPath) -> Void in 
     //TODO: Delete the row at indexPath here 
    } 
    deleteAction.backgroundColor = UIColor.redColor() 

    return [editAction,deleteAction] 
} 

Примечание: для прошивки 8 года

+0

swift 3 - Swipe не работает! Нет параметров! – mythicalcoder

+0

@Maven, вы внедрили canEditRowAtIndexPath, чтобы вернуть true? – MattyG

+1

Я заметил, что вы также должны, по крайней мере написать 'функ Tableview (_ Tableview: UITableView, совершают editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { }' или 'editActionsForRowAtIndexPath' не будет называться – reojased

1

Если вы хотите использовать только текст, делая салфетки действия, то вы можете используйте действия по удалению по умолчанию для iOS, но если вы хотите изображение и текст, тогда вы должны его настроить. Я нашел отличный учебник и образец, которые могут решить эту проблему.

Попробуйте этот репозиторий, чтобы получить пользовательскую ячейку очистки. Здесь вы можете добавить несколько вариантов.

http://iosbucket.blogspot.in/2016/04/custom-swipe-table-view-cell_16.html

https://github.com/pradeep7may/PKSwipeTableViewCell

enter image description here

8

Вы можете использовать UITableViewRowAction «s backgroundColor установить собственное изображение или представление. Трюк использует UIColor(patternImage:).

В основном ширина области UITableViewRowAction определяется ее названием, поэтому вы можете найти точную длину заголовка (или пробела) и установить точный размер изображения с помощью patternImage.

Чтобы реализовать это, я сделал метод расширения UIView.

func image() -> UIImage { 
    UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0) 
    guard let context = UIGraphicsGetCurrentContext() else { 
     return UIImage() 
    } 
    layer.render(in: context) 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image! 
} 

и сделать строку с пробелами и точной длины,

fileprivate func whitespaceString(font: UIFont = UIFont.systemFont(ofSize: 15), width: CGFloat) -> String { 
    let kPadding: CGFloat = 20 
    let mutable = NSMutableString(string: "") 
    let attribute = [NSFontAttributeName: font] 
    while mutable.size(attributes: attribute).width < width - (2 * kPadding) { 
     mutable.append(" ") 
    } 
    return mutable as String 
} 

и теперь, вы можете создать UITableViewRowAction.

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { 
    let whitespace = whitespaceString(width: kCellActionWidth) 
    let deleteAction = UITableViewRowAction(style: .`default`, title: whitespace) { (action, indexPath) in 
     // do whatever you want 
    } 

    // create a color from patter image and set the color as a background color of action 
    let kActionImageSize: CGFloat = 34 
    let view = UIView(frame: CGRect(x: 0, y: 0, width: kCellActionWidth, height: kCellHeight)) 
    view.backgroundColor = UIColor.white 
    let imageView = UIImageView(frame: CGRect(x: (kCellActionWidth - kActionImageSize)/2, 
               y: (kCellHeight - kActionImageSize)/2, 
               width: 34, 
               height: 34)) 
    imageView.image = UIImage(named: "x") 
    view.addSubview(imageView) 
    let image = view.image() 

    deleteAction.backgroundColor = UIColor(patternImage: image) 

    return [deleteAction] 
} 

Результат будет выглядеть следующим образом.

enter image description here

Другой способ сделать это, чтобы импортировать специальный шрифт, который имеет изображение, которое вы хотите использовать в качестве шрифта и использовать UIButton.appearance. Однако это повлияет на другие кнопки, если вы вручную не установите шрифт другой кнопки.

От iOS 11 оно отобразит это сообщение [TableView] Setting a pattern color as backgroundColor of UITableViewRowAction is no longer supported.. В настоящее время он все еще работает, но он не будет работать в будущем обновлении.

+0

Не могли бы вы упростить func image() -> UIImage {} У меня есть ошибки ebcause в его первой строке нет varaible bounds.size. аналогично в 5-й строке hthere нет переменной слоя ... Так как функция не принимает никаких переменных. Спасибо – Jerland2

+1

Это расширение UIView. Таким образом, границы будут границами экземпляра. – Ryan

+0

Oh !!! Duuu, извините, не реализовал в качестве расширения, им глупо .... – Jerland2

2

вы можете попробовать это,

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { 

    let backView = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 80)) 
    backView.backgroundColor = #colorLiteral(red: 0.933103919, green: 0.08461549133, blue: 0.0839477703, alpha: 1) 

    let myImage = UIImageView(frame: CGRect(x: 30, y: backView.frame.size.height/2-14, width: 16, height: 16)) 
    myImage.image = #imageLiteral(resourceName: "rubbish-bin") 
    backView.addSubview(myImage) 

    let label = UILabel(frame: CGRect(x: 0, y: myImage.frame.origin.y+14, width: 80, height: 25)) 
    label.text = "Remove" 
    label.textAlignment = .center 
    label.textColor = UIColor.white 
    label.font = UIFont(name: label.font.fontName, size: 14) 
    backView.addSubview(label) 

    let imgSize: CGSize = tableView.frame.size 
    UIGraphicsBeginImageContextWithOptions(imgSize, false, UIScreen.main.scale) 
    let context = UIGraphicsGetCurrentContext() 
    backView.layer.render(in: context!) 
    let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()! 
    UIGraphicsEndImageContext() 

    let delete = UITableViewRowAction(style: .destructive, title: "   ") { (action, indexPath) in 
     print("Delete") 
    } 

    delete.backgroundColor = UIColor(patternImage: newImage) 

    return [delete, share] 
} 
Смежные вопросы