UITableview с более чем одной пользовательской ячейкой с Swift

111

Я хочу использовать UITableview с разными настраиваемыми tableViewCells. Мои 3 клетки таковы:

  • Ячейка1: должна иметь изображение и метку.
  • Ячейка2: должна иметь две метки.
  • Cell3: должен иметь dayPicker.

Я не хочу кодировать теги для ячеек. Как мне это сделать в Swift. Должен ли я кодировать свой собственный класс для каждой ячейки? Могу ли я использовать один tableviewController? Как я могу заполнить данные в разных ячейках?

Я хотел бы создать tableView, например контактное приложение устройства iOS.

Easyglider
источник

Ответы:

270

Позвольте мне сначала ответить на ваши вопросы.

Должен ли я кодировать собственный класс для каждой ячейки? => Да, я так считаю. По крайней мере, я бы так поступил.

Могу ли я использовать один tableviewController? => Да, можно. Однако вы также можете иметь табличное представление внутри вашего View Controller.

Как я могу заполнить данные в разных ячейках? => В зависимости от условий вы можете заполнять данные в разных ячейках. Например, предположим, что вы хотите, чтобы первые две строки были похожи на ячейки первого типа. Итак, вы просто создаете / повторно используете первый тип ячеек и устанавливаете его данные. Думаю, будет более понятно, когда я покажу вам скриншоты.

Позвольте мне привести пример с TableView внутри ViewController. Как только вы поймете основную концепцию, вы можете попробовать изменить ее как хотите.

Шаг 1. Создайте 3 пользовательских ячейки TableViewCell. Я назвал его FirstCustomTableViewCell, SecondCustomTableViewCell, ThirdCustomTableViewCell. Вам следует использовать более значимые имена.

введите описание изображения здесь

Шаг 2: перейдите на Main.storyboard и перетащите TableView внутри вашего View Controller. Теперь выберите представление таблицы и перейдите к инспектору удостоверений. Установите «Ячейки прототипа» на 3. Здесь вы только что сказали своему TableView, что у вас может быть 3 разных типа ячеек.

введите описание изображения здесь

Шаг 3. Теперь выберите 1-ю ячейку в TableView и в инспекторе удостоверений, поместите «FirstCustomTableViewCell» в поле «Пользовательский класс», а затем установите идентификатор как «firstCustomCell» в инспекторе атрибутов.

введите описание изображения здесь

введите описание изображения здесь

Сделайте то же самое для всех остальных - установите их настраиваемые классы как «SecondCustomTableViewCell» и «ThirdCustomTableViewCell» соответственно. Также последовательно установите идентификаторы secondCustomCell и thirdCustomCell.

Шаг 4: Отредактируйте пользовательские классы ячеек и добавьте розетки в соответствии с вашими потребностями. Я отредактировал его на основании вашего вопроса.

PS: Нужно поставить розетки под определение класса.

Итак, в FirstCustomTableViewCell.swift под

class FirstCustomTableViewCell: UITableViewCell {

вы бы поставили ярлык и выходы для просмотра изображений.

 @IBOutlet weak var myImageView: UIImageView!
 @IBOutlet weak var myLabel: UILabel!

и в SecondCustomTableViewCell.swift добавьте две метки, например:

import UIKit

class SecondCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var myLabel_1: UILabel!
    @IBOutlet weak var myLabel_2: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

и ThirdCustomTableViewCell.swift должен выглядеть так:

import UIKit

class ThirdCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var dayPicker: UIDatePicker!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

Шаг 5: В ViewController создайте Outlet для TableView и установите соединение из раскадровки. Кроме того, вам необходимо добавить UITableViewDelegate и UITableViewDataSource в определение класса в качестве списка протоколов. Итак, определение вашего класса должно выглядеть так:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

После этого прикрепите UITableViewDelegate и UITableViewDatasource вашего табличного представления к вашему контроллеру. На этом этапе ваш viewController.swift должен выглядеть так:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

PS: Если бы вы использовали TableViewController, а не TableView внутри ViewController, вы могли бы пропустить этот шаг.

Шаг 6: Перетащите изображения и метки в ячейку в соответствии с классом Cell. а затем обеспечить подключение к их розеткам из раскадровки.

Шаг 7. Теперь напишите необходимые методы UITableViewDatasource в контроллере представления.

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "firstCustomCell")
            //set the data here
            return cell
        }
        else if indexPath.row == 1 {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "secondCustomCell")
            //set the data here
            return cell
        }
        else {
            let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "thirdCustomCell")
            //set the data here
            return cell
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
Наташа
источник
1
Я получаю сообщение: «Не удалось преобразовать значение типа 'UITableViewCell' (0x1dfbfdc) в 'Projekt.TitelTableViewCell' (0x89568)» в func cellForRowAtIndexPath. Я использую UITableViewController, и у меня есть класс «TitelTableViewCell» для моей пользовательской ячейки «TitelZelle», которую я установил в инспекторе идентичности ячейки «TitelZelle». Что мне нужно сделать?
Easyglider
Я использовал свой сотовый как! TitelTableViewCell для заполнения моих пользовательских UI-элементов в этой ячейке.
Easyglider
7
попробуйте это => let cell = tableView.dequeueReusableCellWithIdentifier ("TitelZelle", forIndexPath: indexPath) as TitelTableViewCell
Наташа
2
@PradipKumar, в чем проблема? В чем твоя ошибка? Кстати, вы должны задать вопрос, если у вас есть какие-либо вопросы. Комментарий, который должен помочь понять или прояснить это в отношении конкретной проблемы, опубликовал автор. Если у вас возникла проблема, вы должны задать вопрос и начать свой собственный пост.
Наташа
1
numberOfRowsInSection помогает tableview определить, сколько строк нам нужно. Таким образом, вы должны предоставить только предложение, которое поможет методу определить количество строк. indexpath.row == 0 означает, что у вас уже есть строка, но в это время ваша таблица не знает, есть ли у нее строка или нет. Итак, вы должны это сделать.
Наташа
32

Swift 3.0 + обновление с минимальным кодом

Базовая концепция: создание табличного представления с динамическими прототипами ячеек. Назначьте идентификатор и создайте собственный класс ячейки представления таблицы для каждого прототипа ячейки. Инициировать и отображать настраиваемые ячейки в методе делегата табличного представления.

1. Создайте ячейки в раскадровке.

Перетащите tableView на свой контроллер представления, добавьте к нему ячейки прототипа, а затем перетащите элемент пользовательского интерфейса в ячейки представления таблицы, при необходимости добавьте ограничение.

введите описание изображения здесь

2. Создавайте собственные UITableViewCellклассы.

Добавьте в свой проект следующий код. Я помещаю его прямо над классом контроллера представления.

class FirstTableCell: UITableViewCell {
}

class SecondTableCell: UITableViewCell {
}

class ThirdTableCell: UITableViewCell {   
}

3. Назначьте пользовательский класс и идентификатор прототипам ячеек.

Для каждого прототипа ячейки в раскадровке назначьте настраиваемый класс, созданный на шаге 2, а затем введите уникальный идентификатор.

введите описание изображения здесь

4. Подключите элементы пользовательского интерфейса к быстрому коду.

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

введите описание изображения здесь

5. Добавьте код для просмотра контроллера и управления табличным представлением.

Сделайте свой контроллер представления совместимым с делегатом табличного представления

class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate

В viewDidLoadнастройте делегата табличного представления и источника данных.

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.dataSource = self
    self.tableView.delegate = self

}

Наконец, добавьте два метода делегата для управления представлением таблицы в соответствии с минимальными требованиями.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "firstTableCell") as! FirstTableCell
        // Set up cell.label
        return cell
    } else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "secondTableCell") as! SecondTableCell
        // Set up cell.button
        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: "thirdTableCell") as! ThirdTableCell
        // Set up cell.textField
        return cell
    }
}

6. Попробуйте :)

введите описание изображения здесь

Fangming
источник
Фантастика! Мне нравятся твои анимации.
iphaaw
Подскажите, пожалуйста, можно ли ставить заголовок для каждой ячейки? если да, то как?
Прутви Харихаран
@PruthviHariharan, если вы хотите иметь «заголовок» для каждой или большинства ваших ячеек, не рекомендуется реализовывать заголовки ячеек или разделов заголовков, для управления которыми требуется больше кода, и это повлияет на производительность. Я предлагаю разместить вид поверх ячейки вашего прототипа и сделать его похожим на «заголовок»
Fangming
@FangmingNing Не могли бы вы пояснить небольшой пример. Спасибо
Прутви Харихаран
Шаг 5 не нужен, если вы используете UITableViewController вместо UIViewController.
Дипак Тхакур,
0

Приведенные выше ответы - лучшие ответы, но есть ТОННА причин для возникновения этой проблемы. Вот еще одно возможное решение для тех, у кого есть эта проблема:

Моя проблема заключалась в том, что я переходил к классу ViewController, а не к раскадровке. Так что моя ссылка на ячейку раскадровки была бессмысленной, поскольку раскадровка не использовалась.

Я делал это:

let viewControllerB = SubViewController()
viewControllerB.passedData = diseases[indexPath.row].name
navigationController?.pushViewController(viewControllerB, animated: true)

И мне нужно было сделать что-то вроде этого:

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "SubViewStoryboardController") as! SubViewController
nextViewController.passedData = diseases[indexPath.row].name
self.present(nextViewController, animated:true, completion:nil)

Надеюсь, это кому-то поможет.

Колтуксумаб
источник
-22

UITableViewControllerнаследуется , UIViewControllerчто уже UITableviewDataSourceи UITableviewDelegateотображается на себя.

Вы можете UITableViewControllerсоздать подкласс или использовать TableViewвнутри вашего ViewController. После этого вы должны реализовать необходимые методы ( cellForRowAtIndexPath and numberOfRowsInSection), которые объявлены в UITableviewDataSource.

Также в раскадровке вам нужно создать прототипы ячеек с уникальным идентификатором.

Существуют базовые типы ячеек с (например, заголовком, подзаголовком) - вы также можете использовать их, если вам не нужна специальная конфигурация.

Итак, для средства выбора, да, вам нужно создать свою собственную ячейку. Создайте необходимое средство UITableViewCellвыбора даты удержания класса и убедитесь, что вы используете делегат для отправки желаемого результата обратно в ваш ViewController.

siarheibrazil
источник