UITableView swipe to delete и другие возможности

Задача

Создать проект, в котором отображается таблица. По жесту swipe нужно открывать список кнопок с различными действиями. Например удалить строку в таблице.

Решение

Создайте проект в Xcode, используюя в качестве шаблона Single View Application. На имеющийся ViewController добавьте из библиотеки объектов TableView. Задайте констрейнты. Также из библиотеки объектов добавьте Table View Cell поверх Table View. Задайте Reuse Identifier для ячейки таблицы и высоту строки таблицы для удобства.

Создайте outlet для таблицы в классе контроллера.

Для начала нам нужны тестовые данные для вывода в таблицу. Давайте добавим массив строк в свойство контроллера ViewController

//
//  proSwift.ru
//
//  Swift 3

    var dataSource = ["iPhone", "iPad", "MacMini", "MacBookPro", "iPod", "Apple Watch", "Apple TV", "iPad Pro", "Magic Mouse 2", "Mac Air"]

Теперь следует сделать класс  ViewController соответствующим двум протоколам UITableViewDataSource и UITableViewDelegate. Для этого следует изменить строку с объявлением класса и добавить нужные методы.

//
//  proSwift.ru
//
//  Swift 3

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

И методы:

//
//  proSwift.ru
//
//  Swift 3

    
    //MARK: - Table View
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CellInd", for: indexPath)
        cell.textLabel?.text = dataSource[indexPath.row]
        return cell
    }

Запустите проект… и вы ничего не увидите. Вернее увидите пустую таблицу. Это потому, что мы забыли указать конструктору интерфейсов, что наш контроллер будет делегатом таблицы. Для этого нужно сделать следующее:

 ctrl-перетягивание с таблицы на иконку контроллера и выбрать нужный пункт.

 

Запустите проект теперь и вы увидите нашу таблицу.




Теперь для реализации поведения swipe-to-delete или других методов работы со строками таблицы нужно добавить эти самые методы. По сути, мы будем создавать action для строк и просить таблицу вывести эти action в строке по жесту swipe.

//
//  proSwift.ru
//
//  Swift 3

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

        let shareAction = UITableViewRowAction(style: .default, title: "Поделиться") {
            _, indexPath in
            
        }

        shareAction.backgroundColor = UIColor.blue
        
        let deleteAction = UITableViewRowAction(style: .destructive, title: "Удалить") {
            _, indexPath in
            self.dataSource.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            
        }
        
        return [deleteAction, shareAction]
    }

Этот метод возвращает массив action, которые будут отображаться в строках. Нужно учесть, что порядок добавления action в массив обратный порядку их отображения в строке. То есть я добавил сначала метод удаления, а потом метод «Поделиться». Отображаться они будут так — «Поделиться», а затем «Удалить».

Также в методе удаления реализовано удаление двух типов — данных из массива и строки из таблицы. Не забывайте удаление строк делать именно так.

Метод «Поделиться» у нас пустой. Давайте по нажатию на эту кнопку выведем стандартное меню с заголовком как в строке таблицы. Измените код метода для shareAction:

//
//  proSwift.ru
//
//  Swift 3

        let shareAction = UITableViewRowAction(style: .default, title: "Поделиться") {
            _, indexPath in
            let alert = UIAlertController(title: self.dataSource[indexPath.row], message: "Строка таблицы", preferredStyle: .alert)
        
            alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { (sender: UIAlertAction) -> Void in
            })
            
            self.present(alert, animated: true, completion: nil)
        }

Проект готов. Запустите и протестируйте методы, которые вызываются по кнопкам, скрытым в строках.

Полный код контролера:

//
//  proSwift.ru
//
//  Swift 3
//
//  ViewController.swift
//  SwipeToDelete
//
//  Created by Andrew Belozerov on 18.03.17.
//  Copyright © 2017 Andrew Belozerov. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    
    @IBOutlet weak var tableView: UITableView!
    
    var dataSource = ["iPhone", "iPad", "MacMini", "MacBookPro", "iPod", "Apple Watch", "Apple TV", "iPad Pro", "Magic Mouse 2", "Mac Air"]
    

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    //MARK: - Table View
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CellInd", for: indexPath)
        cell.textLabel?.text = dataSource[indexPath.row]
        return cell
    }
    
    
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

        let shareAction = UITableViewRowAction(style: .default, title: "Поделиться") {
            _, indexPath in
            let alert = UIAlertController(title: self.dataSource[indexPath.row], message: "Строка таблицы", preferredStyle: .alert)
        
            alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { (sender: UIAlertAction) -> Void in
            })
            
            self.present(alert, animated: true, completion: nil)
        }

        shareAction.backgroundColor = UIColor.blue
        
        let deleteAction = UITableViewRowAction(style: .destructive, title: "Удалить") {
            _, indexPath in
            self.dataSource.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            
        }
        
        return [deleteAction, shareAction]
        
    }
}




Метки: ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.