Why am i getting a stacked text label in table view swift - ios

Why am I getting a text that stacked like this?
I know i can just delete the 'lbl' text from the inspector, but I don't believe I should get something like this.
what did i miss?
thankyou in advance
here's my code:
class ViewController: UITableViewController {
let name = [
"a", "b", "c", "d", "e", "f"
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
// Do any additional setup after loading the view.
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return name.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "bodyCell", for: indexPath)
cell.textLabel?.text = name[indexPath.row]
return cell
}
}

Try to do it programmatically:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
let name = [
"a", "b", "c", "d", "e", "f"
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "bodyCell")
// add your tableView and add constraint
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return name.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "bodyCell", for: indexPath)
cell.textLabel?.text = name[indexPath.row]
return cell
}
}

So I just figured out my self,
I need to cast it after dequeueReusableCell
so it looks like this:
let cell = tableView.dequeueReusableCell(withIdentifier: "bodyCell", for: indexPath) as! OutletClass
so the OutletClass is the class where I connected the label.
well at least that's my case.

Related

Swift UITableView: crash when moving a cell near the footer

I've implemented a drag-and-drop feature on a sample project, which is a TableView with multiple sections. The interaction works fine, however, when I try to move a single row section cell near its section footer, the app crashes.
example of the interaction that causes the crash
Here is the exception the debugger throws:
Swift/Array.swift:405: Fatal error: Array index is out of range
This is the code I've written so far:
class ViewController: UIViewController {
var data = [["1"],["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q"]]
let tableView: UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = .red
tableView.rowHeight = 55
tableView.sectionFooterHeight = 50
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
tableView.delegate = self
tableView.dataSource = self
tableView.dragDelegate = self
tableView.dragInteractionEnabled = true
tableView.register(ShippedProductCell.self, forCellReuseIdentifier: ShippedProductCell.cellID)
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource, UITableViewDragDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ShippedProductCell.cellID) as! ShippedProductCell
let shippedProductData = data[indexPath.section][indexPath.row]
cell.label.text = shippedProductData
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section \(section)"
}
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "Footer"
}
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
guard indexPath.row != data[indexPath.section].count - 1 else { return [] }
let dragItem = UIDragItem(itemProvider: NSItemProvider())
dragItem.localObject = data[indexPath.section][indexPath.row]
return [ dragItem ]
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let mover = data[sourceIndexPath.section].remove(at: sourceIndexPath.row)
data[destinationIndexPath.section].insert(mover, at: destinationIndexPath.row)
print(data)
}
}
When doing some debugging I found that the destinationIndexPath.row was 1, but the section only has 1 row, which is out of bounds. I would really appreciate your help, thanks.

Custom cell above other cells in UITableView

I have a UITableView that gets its data from a sorted array. [A-Z].
How can I place a default cell to select at the top like this.
If a user doesn't want to click any of the other cells?
Here is my UITableViewCode below.
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.allowsSelection = true
tableView.allowsMultipleSelection = false
let groupedDictionary = Dictionary(grouping: nameArray, by: {String($0.prefix(1))})
// get the keys and sort them
let keys = groupedDictionary.keys.sorted()
// map the sorted keys to a struct
sections = keys.map{ Section(letter: $0, name: groupedDictionary[$0]!.sorted()) }
self.tableView.reloadData()
}
// MARK: - Table view data source
var selectedIndexPath = IndexPath()
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].names.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "HomeNames")
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeNames", for: indexPath)
let section = sections[indexPath.section]
if indexPath == selectedIndexPath {
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
} else {
cell.accessoryType = UITableViewCell.AccessoryType.none
}
cell.textLabel?.text = section.names[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let section = sections[indexPath.section]
selectedIndexPath = indexPath
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
tableView.register(UINib(nibName: "BBcell", bundle: nil), forCellReuseIdentifier: "Cell")
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
selectedHomeName = section.name[indexPath.row]
navigationItem.title = (selectedHomeName)
self.dismiss(animated: true, completion: nil)
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sections.map{$0.letter}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].letter
}
}
The simplest solution, in my opinion, would be to insert a new Section at the beginning of your sections variable after this line.
sections = keys.map{ Section(letter: $0, name: groupedDictionary[$0]!.sorted()) }
Something like:
sections.insert(Section(letter: "Default", ["All makes"]), at: 0)
I could have messed up the syntax a bit as I don't know your Section

Cannot convert return expression of type 'ForumViewController' to return type 'UITableViewCell'

My code:
//
// ForumViewController.swift
// Kode4Kids
//
// Created by Caleb Clegg on 17/06/2020.
// Copyright © 2020 Group9. All rights reserved.
//
import UIKit
class ForumViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView = UITableView(frame: view.bounds, style: .plain)
tableView.backgroundColor = UIColor.white
let cellNib = UINib(nibName: "ForumViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "ForumCell")
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *){
layoutGuide = view.safeAreaLayoutGuide
} else {
//fallback on previous versions
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
}
#IBAction func backTapped(_ sender: Any) {
let homeViewController = self.storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
self.view.window?.rootViewController = homeViewController
self.view.window?.makeKeyAndVisible()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 12
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ForumCell", for: indexPath) as! ForumViewController
return cell
}
}
[I keep getting: "Cannot convert return expression of type 'ForumViewController' to return type 'UITableViewCell', I've been at this for two days and my project is due for college next week. I'd really appreciate some help. "][1]
Any ideas on what might need to change?
[1]: https://i.stack.imgur.com/Dgxfn.png
You need to return UITableViewCell not UIViewController in cellForRow function so replace the as ForumViewController to “as ForumCell” or whatever the name of your custom UITableViewCell is.
You can't cast UITableViewCell as UIViewController.
Replace this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ForumCell", for: indexPath) as! ForumViewController
return cell
}
With this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.dequeueReusableCell(withIdentifier: "ForumCell", for: indexPath) // since you're not doing any additional stuff here this would do
}
Note: If you've made a xib file for defining the layout of your UITableViewCell use it's class for downcasting. In your case as! ForumViewCell.

Create UITableView programmatically in Swift

I try to implement UITableView programmatically without use of xib or Storyboards. This is my code:
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let table: UITableViewController = MyTableViewController()
let tableView: UITableView = UITableView()
tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
tableView.dataSource = table
tableView.delegate = table
self.view.addSubview(tableView)
}
}
MyTableViewController.swift
import UIKit
class MyTableViewController: UITableViewController {
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
NSLog("sections")
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
NSLog("rows")
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("get cell")
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
cell.textLabel!.text = "foo"
return cell
}
}
But when I run app, all I get is empty table. In log I see a few lines of sections and rows, but no get cell. How can I fix this code to get table with 6 lines of foo text?
Note: As you mentioned you just started programming in Swift. I created a tableView programmatically. Copy and paste below code into your viewController and run the project...
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let myArray: NSArray = ["First","Second","Third"]
private var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = self.view.frame.height
myTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
myTableView.dataSource = self
myTableView.delegate = self
self.view.addSubview(myTableView)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Num: \(indexPath.row)")
print("Value: \(myArray[indexPath.row])")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
cell.textLabel!.text = "\(myArray[indexPath.row])"
return cell
}
}
Output:
Updated for Swift 3
Option 1:
import UIKit
//
// MARK :- TableViewController
//
class TableViewController: UITableViewController {
private let headerId = "headerId"
private let footerId = "footerId"
private let cellId = "cellId"
//
// MARK :- HEADER
//
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! CustomTableViewHeader
return header
}
//
// MARK :- FOOTER
//
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerId) as! CustomTableViewFooter
return footer
}
//
// MARK :- CELL
//
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CustomTableCell
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
title = "TableView Demo"
view.backgroundColor = .white
setupTableView()
}
func setupTableView() {
tableView.backgroundColor = .lightGray
tableView.register(CustomTableViewHeader.self, forHeaderFooterViewReuseIdentifier: headerId)
tableView.register(CustomTableViewFooter.self, forHeaderFooterViewReuseIdentifier: footerId)
tableView.register(CustomTableCell.self, forCellReuseIdentifier: cellId)
}
}
//
// MARK :- HEADER
//
class CustomTableViewHeader: UITableViewHeaderFooterView {
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .orange
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// MARK :- FOOTER
//
class CustomTableViewFooter: UITableViewHeaderFooterView {
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .green
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// MARK :- CELL
//
class CustomTableCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .white
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Option 2: replace above Option 1 TableViewController with this class
import UIKit
//
// MARK :- ViewController
//
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private let headerId = "headerId"
private let footerId = "footerId"
private let cellId = "cellId"
lazy var tableView: UITableView = {
let tv = UITableView(frame: .zero, style: .plain)
tv.translatesAutoresizingMaskIntoConstraints = false
tv.backgroundColor = .lightGray
tv.delegate = self
tv.dataSource = self
tv.register(CustomTableViewHeader.self, forHeaderFooterViewReuseIdentifier: self.headerId)
tv.register(CustomTableViewFooter.self, forHeaderFooterViewReuseIdentifier: self.footerId)
tv.register(CustomTableCell.self, forCellReuseIdentifier: self.cellId)
return tv
}()
//
// MARK :- HEADER
//
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerId) as! CustomTableViewHeader
return header
}
//
// MARK :- FOOTER
//
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerId) as! CustomTableViewFooter
return footer
}
//
// MARK :- CELL
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CustomTableCell
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
title = "TableView Demo"
view.backgroundColor = .white
view.addSubview(tableView)
setupAutoLayout()
}
func setupAutoLayout() {
tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
}
Swift 4 compatible
Instead of adding a UITableView to your UIViewController, you should consider creating a UITableViewController and avoid setting up delegates:
class YourTVC: TableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// setup custom cells if you use them
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "yourCell")
}
// MARK: tableView
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3 // set to value needed
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! CustomTableViewCell
cell.textLabel?.text = "Cell at row \(indexPath.row)"
return cell
}
}
It makes no sense that you are using a UITableViewController as the data source and delegate for your view controller's table view. Your own view controller should be the table view's data source and delegate.
Since you seem to want a view controller with a table view that doesn't take up the entire view, move every thing to your view controller as follows:
ViewController.swift:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let tableView: UITableView = UITableView()
tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
tableView.dataSource = self
tableView.delegate = self
self.view.addSubview(tableView)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
NSLog("sections")
return 2
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
NSLog("rows")
return 3
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("get cell")
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
cell.textLabel!.text = "foo"
return cell
}
}
You don't need to make a separate class for UITableView. Just in your ViewController class implement protocols of UITableViewDelegate and UITableViewDataSource and then implement delegate methods.
I think your code should be like
class ViewController: UIViewController , UITableViewDelegate , UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
let table: UITableViewController = MyTableViewController()
let tableView: UITableView = UITableView()
tableView.frame = CGRect(x: 10, y: 10, width: 100, height: 500)
tableView.dataSource = table
tableView.delegate = table
self.view.addSubview(tableView)
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
NSLog("sections")
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
NSLog("rows")
return 3
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("get cell")
let cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "Cell")
cell.textLabel!.text = "foo"
return cell
}
}
Tell us more info or show logs if you still face issue.
I had a similar issue in that the data would not populate for my programmatic UITableView. This was because I was using a delegate/dataSource without a strong reference. Once I kept a reference to it (I had one class implementing both UITableViewDataSource and UITableViewDelegate), the data was populated.
import UIKit
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(TableCell.self, forCellReuseIdentifier: "cell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableCell
cell.nameLabel.text = "TableViewCell programtically"
cell.nameLabel.textAlignment = .center
cell.nameLabel.textColor = .white
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
Simple solution
import UIKit
class CustomTableViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
cell.textLabel!.text = "\(indexPath.row)"
return cell
}
}

Show TableView in Swift Playgrounds for iPad

Everything works fine except the last line where I try to show the tableView in live view does not work: PlaygroundPage.current.liveView = controller
I can't figure out what I'm getting wrong?
import UIKit
import PlaygroundSupport
import Foundation
class TableViewController: UITableViewController {
let tableData = ["Matthew", "Mark", "Luke", "John"]
override func viewDidLoad() {
super.viewDidLoad()
print("Hello Matt")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell.textLabel?.text = tableData[indexPath.row]
return cell
}
}
let controller = TableViewController()
PlaygroundPage.current.liveView = controller
I think you forgot to register the table view cell class in viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
In func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath), add one line to the top of the function:
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
Like this:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
var cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as UITableViewCell
cell.textLabel?.text = tableData[indexPath.row]
return cell
}

Resources