I created a UIViewController containing a UITableView.
I want it to display files I created at another position.
The corresponding class looks like this:
import UIKit
class BackupViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var rows:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.table.dataSource = self
self.table.delegate = self
getFiles()
// Do any additional setup after loading the view.
}
func getFiles() {
let filemgr = FileManager.default
let path = filemgr.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last
do {
rows = try filemgr.contentsOfDirectory(atPath: (path?.path)!)
// process files
} catch {
print("Error while enumerating files")
}
table.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.table.dequeueReusableCell(withIdentifier: "cell") as! UITableViewCell
cell.textLabel?.text = rows[indexPath.row]
return cell
}
#IBOutlet weak var table: UITableView!
}
It reads the files correctly and when
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int)
is called (which happens 3 times for some reason), the array has (at the moment) 2 elements. However, the function
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
is never called and of course I get an empty table.
You need to reload your tableView after fetching files in getFile() function.
func getFiles() {
let filemgr = FileManager.default
let path = filemgr.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last
do {
rows = try filemgr.contentsOfDirectory(atPath: (path?.path)!)
self.table.reloadData()
// process files
} catch {
print("Error while enumerating files")
}
/*for file in files {
rows.append(file.absoluteString)
}*/
showFiles = true
}
You need to call reloadData() once row will have some value in it.
Related
I'm getting this error message in my table view controller class
value of uitableviewcell has no member delegate
Here is an image of the error.
Is there anything that should be changed in my code?
import UIKit
class TViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var Tviews: UITableViewCell!
let contacts:[[String]] = [
["Elon Musk", "+1-201-3141-5926"],
["Bill Gates", "+1-202-5358-9793"],
["Tim Cook", "+1-203-2384-6264"],
["Richard Branson", "+1-204-3383-2795"],
["Jeff Bezos", "+1-205-0288-4197"],
["Warren Buffet", "+1-206-1693-9937"],
["The Zuck", "+1-207-5105-8209"],
["Carlos Slim", "+1-208-7494-4592"],
]
override func viewDidLoad() {
super.viewDidLoad()
Tviews.delegate = self
Tviews.datasource = self
// Do any additional setup after loading the view.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViews", for: indexPath)
print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")
cell.textLabel?.text = contacts[indexPath.row][0]
return cell
}
You should assign your delegate and data source to your table view instance, and not your table view cell.
In order to do that, create an outlet link with your table view in the TViewController file and then edit your code like this:
import UIKit
class TViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
let contacts:[[String]] = [
["Elon Musk", "+1-201-3141-5926"],
["Bill Gates", "+1-202-5358-9793"],
["Tim Cook", "+1-203-2384-6264"],
["Richard Branson", "+1-204-3383-2795"],
["Jeff Bezos", "+1-205-0288-4197"],
["Warren Buffet", "+1-206-1693-9937"],
["The Zuck", "+1-207-5105-8209"],
["Carlos Slim", "+1-208-7494-4592"],
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "<your-table-view-cell-id>", for: indexPath) as! YourTableViewCell
cell.textLabel?.text = contacts[indexPath.row][0]
return cell
}
}
I have a tableView connected to the array. The array isn't empty but the tableView shows nothing other than lines. Can you help me, please?
var invoicesDictionary = [String:[String]]()
var invoicesSectionTitles = [String]()
var invoices: [String] = ["JV1", "R1", "JV2"]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
for invoice in invoices {
let invoiceKey = String(invoice.prefix(1))
if var invoiceValues = self.invoicesDictionary[invoiceKey] {
invoiceValues.append(invoice)
self.invoicesDictionary[invoiceKey] = invoiceValues
} else {
self.invoicesDictionary[invoiceKey] = [invoice]
}
}
invoicesSectionTitles = [String](invoicesDictionary.keys)
invoicesSectionTitles = invoicesSectionTitles.sorted(by: { $0 < $1 })
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return invoicesSectionTitles.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let invoiceKey = invoicesSectionTitles[section]
if let invoiceValues = invoicesDictionary[invoiceKey] {
return invoiceValues.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let invoiceKey = invoicesSectionTitles[indexPath.section]
if let invoiceValues = invoicesDictionary[invoiceKey] {
cell.textLabel?.text = invoiceValues[indexPath.row]
}
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return invoicesSectionTitles[section]
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return invoicesSectionTitles
}
I printed out the array which is without a doubt not empty. I tried this code on an another project and it just worked.
You have to put this in viewDidLoad :
tableView.delegate = self
tableView.dataSource = self
You have to tell the View controller that it's the delegate or assigned VC for the table View functionality by passing the following lines inside viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
I'm trying to create a tableView within a viewController. I know it is annoying, but the table looks much better that way. I am also trying to incorporate data from Firebase to put into the table. Unfortunately when I run the code, it only shows a blank table. The console was able to print the desired data, but it just won't show on the actual table. Please let me know what I'm doing wrong. Many thanks!
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var user = Auth.auth().currentUser
var users = [Users]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.reloadData()
fetchUser()
}
func fetchUser() {
Database.database().reference(fromURL: "https://yala-2018.firebaseio.com/").child("users").observe(.childAdded, with: { (DataSnapshot) in
if let dictionary = DataSnapshot.value as? [String: AnyObject] {
let user = Users()
// user.setValuesForKeys(dictionary)
user.name = dictionary["name"] as! String
user.age = dictionary["age"] as! String
user.sex = dictionary["sex"] as! String
self.users.append(user)
print(user.name, user.age)
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
})
}
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "guide", for: indexPath)
let user = users[indexPath.row]
cell.textLabel?.text = user.name
cell.detailTextLabel?.text = "Age: \(user.age) Sex: \(user.sex)"
// Configure the cell...
return cell
}
func tableView(tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
Change this to 1 as by 0 you mean no sections which will display empty tableView even if there is a data , or remove it as by default it's 1
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
I have two view controller with tableviewcell and in both of them I can add items.
What I want to implement is that when I add items in the first tableviewcell lets say I add (item one , item two) and press on (item one).
I want to sugue to the second tableviewcell and add data.
BUT I want the data in the second tableviewcell to save separately,
that means, now if I press on (item one) I should see the data that I added
but if I press on (item two) it should be empty and I can add data later.
I have saved the data for the two tableviewcell in coredata.
I don't use segues or coredata in this solution, but the solution will fix what you need to some extent at least.
class vc1: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
let options: [Int] = [1,2]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return options.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = vc2()
//Not sure where to put the setup to be honest
//option 1:
vc.setupTableView(forCell: indexPath.item)
present(vc, animated: true) {
//option 2:
vc.setupTableView(forCell: indexPath.item)
}
}
}
class vc2: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView = UITableView()
var selectedCell: Int!
//Having an nested array in an array will solve this custom "page" you are looking for
let results: [[String]] = [["test1", "test2"], ["test3", "test4"]]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func setupTableView(forCell cell: Int) {
selectedCell = cell
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results[selectedCell].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel = results[selectedCell][indexPath.item]
return UITableViewCell()
}
}
I want to make tableview cell have dynamic label or image in it. I don't want to loop add subview to content view of tableview cell because it will run slow when you scroll. So can anyone help me please? Like this image:
My code is;
Without knowing the context of your code, something like this can work:
NOTE This will work on iOS <= 8
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var TableVC: UITableView!
let elements = ["item1 item2 item3","item1 item2", "item1"]
override func viewDidLoad() {
super.viewDidLoad()
self.TableVC.delegate = self
self.TableVC.dataSource = self
self.TableVC.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return elements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.numberOfLines = 0
cell.textLabel?.attributedText = addTextToAttribute(text: elements[indexPath.item])
return cell
}
func addTextToAttribute(text : String) -> NSMutableAttributedString {
let mutString = NSMutableAttributedString()
let s = text.components(separatedBy: .whitespaces)
let attr: [String: AnyObject] = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 20)]
for text in s {
mutString.append(NSAttributedString(string: "-" + text + "\n", attributes: attr))
}
return mutString
}
}