スワイプ時に削除ボタンを表示するにはどうすればよいUITableViewCell
ですか?イベントは発生せず、削除ボタンは表示されません。
スワイプ時に削除ボタンを表示するにはどうすればよいUITableViewCell
ですか?イベントは発生せず、削除ボタンは表示されません。
回答:
起動時(-viewDidLoad or in storyboard)
:
self.tableView.allowsMultipleSelectionDuringEditing = NO;
オーバーライドして、テーブルビューの条件付き編集をサポートします。これはNO
、一部のアイテムを返品する場合にのみ実装する必要があります。デフォルトでは、すべてのアイテムが編集可能です。
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
}
}
self.tableView.allowsMultipleSelectionDuringEditing = NO;
左スワイプが機能するように設定する必要もありました。テーブルが編集状態ではないため、これはバグのように思えます。このオプションは「DuringEditing」にのみ適用されます。ただし、現在は機能しており、テーブルが編集状態になるたびにYESに設定します。
この回答はSwift 3に更新されました
新しいタスクを学習するときに何も想定されないように、非常に単純な自己完結型の例があるといいといつも思っています。この答えは、UITableView
行を削除するためのものです。プロジェクトは次のように実行されます。
このプロジェクトは、SwiftのUITableViewサンプルに基づいています。
新しいプロジェクトを作成し、ViewController.swiftコードを次のコードに置き換えます。
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// These strings will be the data for the table view cells
var animals: [String] = ["Horse", "Cow", "Camel", "Pig", "Sheep", "Goat"]
let cellReuseIdentifier = "cell"
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// It is possible to do the following three things in the Interface Builder
// rather than in code if you prefer.
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
tableView.delegate = self
tableView.dataSource = self
}
// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.animals.count
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
cell.textLabel?.text = self.animals[indexPath.row]
return cell
}
// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You tapped cell number \(indexPath.row).")
}
// this method handles row deletion
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// remove the item from the data model
animals.remove(at: indexPath.row)
// delete the table view row
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Not used in our example, but if you were adding a new row, this is where you would do it.
}
}
}
行の削除を可能にする上記のコードの単一キーメソッドは、最後のメソッドです。ここでも強調のためです:
// this method handles row deletion
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// remove the item from the data model
animals.remove(at: indexPath.row)
// delete the table view row
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Not used in our example, but if you were adding a new row, this is where you would do it.
}
}
UITableView
ストーリーボードのビューコントローラーにを追加します。自動レイアウトを使用して、テーブルビューの4つの側面をビューコントローラーの端に固定します。ストーリーボードのテーブルビューから@IBOutlet var tableView: UITableView!
コードの行。
それで全部です。今すぐアプリを実行し、左にスワイプして[削除]をタップして行を削除できます。
「削除」ボタンのテキストを変更する
次のメソッドを追加します。
func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
return "Erase"
}
カスタムボタンアクション
次のメソッドを追加します。
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
// action one
let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
print("Edit tapped")
})
editAction.backgroundColor = UIColor.blue
// action two
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
print("Delete tapped")
})
deleteAction.backgroundColor = UIColor.red
return [editAction, deleteAction]
}
これはiOS 8からのみ利用できることに注意してください。詳細については、この回答を参照してください。
iOS 11向けに更新
アクションは、iOS 11のUITableViewDelegate APIに追加されたメソッドを使用して、セルの先頭または末尾に配置できます。
func tableView(_ tableView: UITableView,
leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let editAction = UIContextualAction(style: .normal, title: "Edit", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
success(true)
})
editAction.backgroundColor = .blue
return UISwipeActionsConfiguration(actions: [editAction])
}
func tableView(_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let deleteAction = UIContextualAction(style: .normal, title: "Delete", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
success(true)
})
deleteAction.backgroundColor = .red
return UISwipeActionsConfiguration(actions: [deleteAction])
}
UITableView
1、これは完全にスタンドアロンのプロジェクトであり、あなたがここで説明されていない何もする必要はありません。私がコードでそれを設定し始めた理由はそれが私の答えであまり説明を必要としないからです。コードに戻るには、基本的な例に戻って編集する必要があります。
このコードは、削除を実装する方法を示しています。
#pragma mark - UITableViewDataSource
// Swipe to delete.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_chats removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
必要に応じて、初期化オーバーライドで、以下の行を追加して、[編集]ボタン項目を表示します。
self.navigationItem.leftBarButtonItem = self.editButtonItem;
解決できたばかりの問題がありました。誰かの役に立つかもしれないので、共有しています。
UITableViewがあり、スワイプで削除できるように、以下のメソッドを追加しました。
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
}
}
テーブルを編集モードにして複数選択を有効にする更新に取り組んでいます。そのために、AppleのTableMultiSelectサンプルのコードを追加しました。いったん機能するようになったら、スワイプで削除機能が機能しなくなったことがわかりました。
次の行をviewDidLoadに追加することが問題であることがわかりました。
self.tableView.allowsMultipleSelectionDuringEditing = YES;
この行を入力すると、複数選択は機能しますが、削除するためのスワイプは機能しません。ラインがなければそれは逆でした。
修正:
次のメソッドをviewControllerに追加します。
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
self.tableView.allowsMultipleSelectionDuringEditing = editing;
[super setEditing:editing animated:animated];
}
次に、テーブルを編集モードにする(たとえば、ボタンを押すなどの)メソッドで、次を使用する必要があります。
[self setEditing:YES animated:YES];
の代わりに:
[self.tableView setEditing:YES animated:YES];
つまり、テーブルが編集モードのときにのみ複数選択が有効になります。
UITableViewDataSourceの下はスワイプ削除に役立ちます
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[arrYears removeObjectAtIndex:indexPath.row];
[tableView reloadData];
}
}
arrYears はNSMutableArrayであり、次にtableViewを再ロードします
迅速
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyleDelete {
arrYears.removeObjectAtIndex(indexPath.row)
tableView.reloadData()
}
}
iOS 8とSwift 2.0では、これを試してください。
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// let the controller to know that able to edit tableView's row
return true
}
override func tableView(tableView: UITableView, commitEdittingStyle editingStyle UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
// if you want to apply with iOS 8 or earlier version you must add this function too. (just left in blank code)
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
// add the action button you want to show when swiping on tableView's cell , in this case add the delete button.
let deleteAction = UITableViewRowAction(style: .Default, title: "Delete", handler: { (action , indexPath) -> Void in
// Your delete code here.....
.........
.........
})
// You can set its properties like normal button
deleteAction.backgroundColor = UIColor.redColor()
return [deleteAction]
}
@クルブズの答えは素晴らしいですが、私はこのメモを残して、この答えが人々の時間を節約できることを願っています。
コントローラーにこれらのラインが時々あり、スワイプ機能が動作しなくなりました。
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
UITableViewCellEditingStyleInsert
またはUITableViewCellEditingStyleNone
編集スタイルとして使用する場合、スワイプ機能は機能しません。UITableViewCellEditingStyleDelete
デフォルトのスタイルであるのみを使用できます。
スウィフト4
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "delete") { (action, indexPath) in
// delete item at indexPath
tableView.deleteRows(at: [indexPath], with: .fade)
}
return [delete]
}
また、これは次の方法を使用してSWIFTで実現できます。
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete){
testArray.removeAtIndex(indexPath.row)
goalsTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
あなたがしなければならないすべてはこれらの2つの機能を有効にすることです:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete {
tableView.reloadData()
}
}
私は古い質問を知っていますが、@ Kurbzの回答はXcode 6.3.2とSDK 8.3でこれが必要です
私は追加する必要が[tableView beginUpdates]
と[tableView endUpdates]
(@のbay.phillipsのおかげでここを)
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// Open "Transaction"
[tableView beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// your code goes here
//add code here for when you hit delete
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
// Close "Transaction"
[tableView endUpdates];
}
テーブルビューのセルを削除するときは、インデックスxの配列オブジェクトも削除する必要があります。
スワイプジェスチャーで削除できると思います。テーブルビューはデリゲートを呼び出します。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
[dataSourceArray removeObjectAtIndex:indexPath.row];
}
}
オブジェクトを削除した後。テーブルビューの使用をリロードする必要があります。コードに次の行を追加します。
[tableView reloadData];
その後、行は正常に削除されました。また、ビューをリロードしたり、DataSourceにデータを追加したりすると、オブジェクトは存在しなくなります。
それ以外の場合は、Kurbzからの正解です。
DataSource配列からオブジェクトを削除する場合、デリゲート関数では十分ではないことを思い出させたいだけです。
お役に立てば幸いです。
[tableView reloadData]
call を呼び出す代わりに[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]
。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//add code here for when you hit delete
[dataSourceArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
Swift 2.2:
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView,
editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "DELETE"){(UITableViewRowAction,NSIndexPath) -> Void in
print("Your action when user pressed delete")
}
let edit = UITableViewRowAction(style: UITableViewRowActionStyle.Normal, title: "EDIT"){(UITableViewRowAction,NSIndexPath) -> Void in
print("Your action when user pressed edit")
}
return [delete, block]
}
Swiftの場合、このコードを書くだけです
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
print("Delete Hit")
}
}
Objective Cの場合は、次のコードを記述してください
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(@"index: %@",indexPath.row);
}
}
swift4コードの場合、最初に編集を有効にします。
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
次に、編集デリゲートに削除アクションを追加します。
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action = UITableViewRowAction(style: .destructive, title: "Delete") { (_, index) in
// delete model object at the index
self.models[index.row]
// then delete the cell
tableView.beginUpdates()
tableView.deleteRows(at: [index], with: .automatic)
tableView.endUpdates()
}
return [action]
}
スウィフト4,5
スワイプでセルを削除するには、UITableViewの2つの組み込みメソッドがあります。このメソッドをTableView dataSource拡張に書き込みます。
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = deleteProperty(at: indexPath)
return UISwipeActionsConfiguration(actions: [delete])
}
//Declare this method in Viewcontroller Main and modify according to your need
func deleteProperty(at indexpath: IndexPath) -> UIContextualAction {
let action = UIContextualAction(style: .destructive, title: "Delete") { (action, view, completon) in
self.yourArray.remove(at: indexpath) //Removing from array at selected index
completon(true)
action.backgroundColor = .red //cell background color
}
return action
}
差分データソースを採用している場合は、デリゲートコールバックをUITableViewDiffableDataSource
サブクラスに移動する必要があります。例えば:
class DataSource: UITableViewDiffableDataSource<SectionType, ItemType> {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
if let identifierToDelete = itemIdentifier(for: indexPath) {
var snapshot = self.snapshot()
snapshot.deleteItems([identifierToDelete])
apply(snapshot)
}
}
}
}