UITableView does not conform to protocol - swift

Type ‘TVViewController’ does not conform to protocol ‘UITableViewDataSource’
I'm fairly new to programming and the error is very vague so I don't know where to begin troubleshooting.
class WeeksViewController: UIViewController, UITableViewDataSource {
//Categories
var categories = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"]
//Number of sections
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return categories.count
}
//Defining the headers
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return categories[section]
}
//Number of rows
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
//Cell as identifier & category as the class
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! CategoryRow
return cell
}
}

You copied and pasted Swift 2 code. These are the proper Swift 3+ methods
class WeeksViewController: UIViewController, UITableViewDataSource {
//Categories
var categories = ["One", "Two", "Three", "Four", "Five", "Six", "Seven"]
//Number of sections
func numberOfSections(in tableView: UITableView) -> Int
return categories.count
}
//Defining the headers
func func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return categories[section]
}
//Number of rows
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
//Cell as identifier & category as the class
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", for: indexPath) as! CategoryRow
return cell
}
}
It's always worth it to have a look at the documentation

I think the issue is that you have a misspelling in the name of the numberOfRows data source method and the cellForRow signature is also a bit off.
Instead of these:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return categories.count
}
...
func func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//
}
You probably want these:
func numberOfSections(in tableView: UITableView) -> Int {
return categories.count
}
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// code
}

Related

Swift tableview 'method heightForHeaderInSection' makes section text raise

When heightForHeaderInSection and/or heightForFooterInSection is called, the section text raises above it's first row. I attached a screenshot to show the issue. How can I increase the section spacing without the section header being affected?
#IBOutlet weak var tableView: UITableView!
let fruits =
["apple","pear","orange","caramel","peach","fruit","fruits"]
let numbers = ["1", "2"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
if section == 0 {
return fruits.count
} else {
return numbers.count
}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection
section: Int) -> String? {
if section == 0 {
return "Animals"
} else {
return "Numbers"
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"cell1", for: indexPath)
if indexPath.section == 0 {
cell.textLabel?.text = fruits[indexPath.row]
} else {
cell.textLabel?.text = numbers[indexPath.row]
}
return cell
}
These are the 2 methods in question:
func tableView(_ tableView: UITableView, heightForHeaderInSection
section: Int) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, heightForFooterInSection
section: Int) -> CGFloat {
return 100
}
You are setting the height of the header to 100. See here:
func tableView(_ tableView: UITableView, heightForHeaderInSection
section: Int) -> CGFloat {
return 100 // Instead try returning 30
}
func tableView(_ tableView: UITableView, heightForFooterInSection
section: Int) -> CGFloat {
return 100 // If you are not using a footer - return .zero
}
I got the answer from another post.
Just add:
tableView.sectionHeaderTopPadding = 100 // or whatever number you want.
There's also another way.
Click on of these ->
You can choose Grouped or the rounded design 'Inset Grouped'
After you can use the method 'heightForHeaderInSection' to select the specific section/s.

How to insert one Cell into the first section of UITableView Swift

I have created a UITableView with two sections. Now I am trying to populate one section. When I do action, my program populates both sections at the same time with the same text. What I am trying to do is to populate the first section, and then eventually move one of the cell from Section 1 to Section 2. So far I got here:
extension ListVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
randomCount = notes.count
return notes.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomNoteCell.reuseId) as! CustomNoteCell
cell.set(with: notes[indexPath.row])
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
sections.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section < sections.count {
return sections[section]
}
return nil
}
}
I believe it needs to happen in cellForRowAt but I have no clue how to specify section. Any help and clues appreciated. Many thanks ;)
Change the code of numberOfRowInSection to this:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 { //first section
randomCount = notes.count
return notes.count
}else{
return 0
}
}

dropdown tableview - Swift

I draw data from MSSQL and load this data into tableView. No problem with that. I want to make a drop down menu, but I don't know how to do it. Now all the menus are angled. How do I make tables open and close? How can I do this? How do I make a folding tableview?
class CollapsibleTableViewController: UITableViewController {
var sectionNames: [String] = []
var sectionDetay: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
makaleDetay()
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableView.automaticDimension
}
func makaleDetay(){
...
client.execute("SELECT soru_icerik FROM uzaktanptomg_db.omg_user.ie_soru", completion: { (_ results: ([Any]?)) in
... self.sectionDetay.append(String(result))
...
}
extension CollapsibleTableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return sectionDetay.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CollapsibleTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleTableViewCell ??
CollapsibleTableViewCell(style: .default, reuseIdentifier: "cell")
cell.nameLabel.text = "SSS"
cell.detailLabel.text = sectionDetay[indexPath.section]
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as? CollapsibleTableViewHeader ?? CollapsibleTableViewHeader(reuseIdentifier: "header")
header.titleLabel.text = sectionNames[section]
header.arrowLabel.text = ">"
header.setCollapsed(false)
header.section = section
header.delegate = self
return header
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44.0
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1.0
}
}
extension CollapsibleTableViewController: CollapsibleTableViewHeaderDelegate {
func toggleSection(_ header: CollapsibleTableViewHeader, section: Int) {
....
}
}

Delete UITableHeader title when section contains empty row

I am implementing a UITableView to populate contact name of the persons. I have implemented pretty much every thing.
I need to delete the section header title of the section whose rows have been deleted by the user and does not contain any other rows. Is there some way to do that. Simply deleting the value from title array when index.item gives me a crash. Any idea on it..
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sortedUniqueFirstLetters[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! TableViewCell
cell.account = sections[indexPath.section][indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
view.tintColor = UIColor.setColor(Red: 223, Green: 220, Blue: 224, Alpha: 1)
let header = view as! UITableViewHeaderFooterView
header.textLabel?.textColor = UIColor.white
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true;
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
***if indexPath.item == 0{ //Trying to update title array when a section is empty
sortedUniqueFirstLetters.remove(at: indexPath.section) //Index out of range error here.
}***
sections[indexPath.section].remove(at: indexPath.item)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.middle);
}
}
Here is the answer :
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
return sortedUniqueFirstLetters[section]
} else {
return nil
}
}
You should also use the heightForHeaderInSction as well along with your titleForHEaderInSction method. Let me know if below code works for you:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let numberOfRows = tableView.numberOfRows(inSection: section)
if numberOfRows == 0 {
return ""
}else{
return sortedUniqueFirstLetters[section]
}
}
func tableView (tableView:UITableView , heightForHeaderInSection section:Int) -> Float {
let title = self.tableView(tableView, titleForHeaderInSection: section)
if (title == "") {
return 0.0
}
return 80.0
}

Swift 3 UITableView sections showing after the list

I'm trying to create a list of products using swift 3 UITableViewController, but the sections is showing after the list of the products. There must be something I'm missing, couldn't find anywhere
Here is a simplified code
let data = [["0,0", "0,1", "0,2"], ["1,0", "1,1", "1,2"], ["2,0", "2,1", "2,2"], ["3,0", "3,1", "3,2"]]
override func numberOfSections(in tableView: UITableView) -> Int {
return data.count//productCategoriesSections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data[section].count//productCategories[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "defaultCategoryCell", for: indexPath) as! CategoryDefaultTableViewCell
cell.titleTextView.text = data[indexPath.section][indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "Section \(section)"
}
screenshot
It is because you are using wrong callback.
Use override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? instead of override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?.
The former will place the text as a header above the section. The latter places it at the bottom.