Как установить UITableViewCellStyleSubtitle и dequeueReusableCell в Swift?
Я хотел бы использовать UITableView
с subtitle
-стилами, использующими dequeueReusableCellWithIdentifier
.
Мой оригинальный Objective-C код:
static NSString* reuseIdentifier = @"Cell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
}
После поиска нескольких вопросов UITableView
здесь уже на SO, я подумал записать его в Swift следующим образом:
tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
Но это не позволяет мне сказать, что мне нужен стиль subtitle
. Поэтому я попробовал это:
var cell :UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
Что дает мне ячейку subtitle
, но она не позволяет мне dequeueReusableCellWithIdentifier
.
Я изучил еще несколько и посмотрел этот видеоурок, но он создает отдельный subclass
of UITableViewCell
, который, как я полагаю, не нужен, поскольку я сделал этот же эффект ранее в Obj-C.
Любые идеи? Спасибо.
Ответы
Ответ 1
Имейте в виду, что UITableView
определяется как необязательный в функции, что означает, что ваша первоначальная декларация ячейки должна проверять наличие необязательного свойства. Кроме того, возвращенная ячейка в очереди также является необязательной, поэтому убедитесь, что вы добавили опцию в UITableViewCell
. Впоследствии мы можем заставить разворот, потому что мы знаем, что у нас есть ячейка.
var cell:UITableViewCell? =
tableView?.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell
if (cell == nil)
{
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle,
reuseIdentifier: reuseIdentifier)
}
// At this point, we definitely have a cell -- either dequeued or newly created,
// so let force unwrap the optional into a UITableViewCell
cell!.detailTextLabel.text = "some text"
return cell
Ответ 2
Если вы предпочитаете избегать дополнительных возможностей, вы можете создать подкласс UITableViewCell, который будет выглядеть примерно так:
class SubtitleTableViewCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Затем зарегистрируйте его, используя:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
}
Это позволяет вашему коду настройки ячейки быть действительно хорошим:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
cell.textLabel?.text = "foo"
cell.detailTextLabel?.text = "bar"
return cell
}
Ответ 3
В основном то же самое, что и другие ответы, но я общаюсь с неприятными опциями (вы не можете вернуть nil
из -tableView:cellForRow:atIndexPath:
в Swift) с помощью вычисленной переменной:
Swift 3
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell") else {
// Never fails:
return UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: "UITableViewCell")
}
return cell
}()
// (cell is non-optional; no need to use ?. or !)
// Configure your cell:
cell.textLabel?.text = "Key"
cell.detailTextLabel?.text = "Value"
return cell
}
Edit:
На самом деле было бы лучше удалить ячейку с помощью: tableView.dequeueReusableCell(withIdentifier:for:)
.
Этот более поздний вариант функции автоматически создает новую ячейку, если никто не доступен для повторного использования (именно то, что делает мой код явно выше) и поэтому никогда не возвращает nil
.
Ответ 4
Просто основываясь на ответе меммонов, очистив его стиль Swift 2...
let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) ?? UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
cell.detailTextLabel?.text = "some text"
return cell
Swift 3:
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) ?? UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
cell.detailTextLabel?.text = ""
return cell
Ответ 5
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "cell"
var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as UITableViewCell?
if (cell == nil) {
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
}
cell!.textLabel?.text = self.items[indexPath.row]
cell!.detailTextLabel?.text = self.items[indexPath.row]
return cell!
}
Ответ 6
Так как tableView.dequeueReusableCell(withIdentifier:, for:)
возвращает ячейку non-nil, проверка if cell == nil
всегда будет ложной.
Но я нашел решение, чтобы ячейка стиля по умолчанию стала тем стилем (value1, value2 или subtitle), который вы хотите, потому что ячейка стиля стиля detailTextLabel
равна нулю, поэтому проверьте detailTextLabel
, если она равна нулю, затем создайте новую ячейку стиля, и дать ему деактивировать ячейку, например:
Swift 3:
var cell = tableView.dequeueReusableCell(withIdentifier: yourCellReuseIdentifier, for: indexPath)
if cell.detailTextLabel == nil {
cell = UITableViewCell(style: .value1, reuseIdentifier: repeatCellReuseIdentifier)
}
cell.textLabel?.text = "Title"
cell.detailTextLabel?.text = "Detail"
return cell
Это работает для меня.
Надеюсь, что это поможет.
Ответ 7
Для предотвращения принудительной разворачивания вы можете использовать несколько иной синтаксис, отличный от memmons:
let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as? UITableViewCell ?? UITableViewCell(style: .Subtitle,
reuseIdentifier: reuseIdentifier)
cell.detailTextLabel?.text = "some text"
return cell
Это использует XCode 6.1 7, Swift 1.2 2.0, где UITableView
больше не является необязательным.
Ответ 8
Если вы не используете свою собственную пользовательскую ячейку. Просто зарегистрируйте UITableViewCell через код. Тогда вы можете выбрать код.
Просто выберите раскадровку, выберите свой TableViewCell → Goto Attribute Inspector и выберите нужный стиль, как показано ниже.
![введите описание изображения здесь]()
Ответ 9
Идеально, как предложил Майкл Дж. Эммонс, но в Xcode 6.1, используя
if !cell { .....
Я получаю эту ошибку:
Необязательный тип '@| значение UITableViewCell?' не может использоваться как логическое; тест вместо '!= nil'
Принятый синтаксис:
if cell == nil { ...
Ответ 10
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath:
NSIndexPath) -> UITableViewCell {
var CellIdentifier:String = "Cell"
var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style:UITableViewCellStyle(rawValue:3)!,reuseIdentifier:CellIdentifier)
}
return cell!
}
Ответ 11
Это немного странно. Я ожидал бы, что tableView потребует от нас вернуть ячейку, которая была зарегистрирована на ней с помощью идентификатора ячейки. Но это, похоже, не так, и следующее отобразит ячейку для textLabel и detailTextLabel:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: cellId)
let user = users[indexPath.row]
cell.textLabel?.text = user.name
cell.detailTextLabel?.text = user.email
return cell
}
Ответ 12
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell:UITableViewCell? =
tableView.dequeueReusableCell(withIdentifier: "cell")
if (cell != nil)
{
cell = UITableViewCell(style: UITableViewCellStyle.subtitle,
reuseIdentifier: "cell")
}
cell!.textLabel?.text = "ABC"
cell!.detailTextLabel?.text = "XYZ"
return cell!
}
Ответ 13
Убедитесь, что вы не регистрируете ни одну ячейку в табличном представлении.
Если вы это сделали, dequeueReusableCellWithIdentifier всегда будет давать необязательную ячейку, поэтому UITableViewCellStyle.Subtitle никогда не будет инициироваться.
Ответ 14
Я приглашаю вас посмотреть этот маленький пример UITableView на Github: https://github.com/YANGReal/UITableView-Swift
Они делают следующее:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let cell = tableView .dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel.text = String(format: "%i", indexPath.row+1)
// set any other property of your cell here
return cell
}
Ответ 15
Просто используйте это для Swift 3:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "My Reuse Identifier", for: indexPath)
cell.textLabel?.text = "Key"
cell.detailTextLabel?.text = "Value"
return cell
}
Ответ 16
swift4:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = settingsTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "String"
cell.detailTextLabel?.text = " string"
return cell
}