I have problem while creating the model.
My api is in such way.
{data:["name":"seena","option":["Yes, always","no"]]}
so according to this i need to display the data in tableviewsection using mvvm way.
Here i need two create two model
1.for question list
2.options list
mymodel:-
class QuestionListModel: NSObject {
var home:[OPTIONS] = []
var id:Int!
var question:String!
var options:[String]?
var v:String?
init(dictionary :JSONDictionary) {
guard let question = dictionary["question"] as? String,
let id = dictionary["id"] as? Int
else {
return
}
if let options = dictionary["options"] as? [String]{
print(options)
print(options)
}
self.question = question
self.id = id
}
}
in viewmodel:-
func numberOfSections(tableView: UITableView) -> Int{
print((datasourceModel.dataListArray?.count)!)
return (datasourceModel.dataListArray?.count)!
}
func titleForHeaderInSection(atsection section: Int) -> QuestionListModel {
return datasourceModel.dataListArray![section]
}
func numberOfRowsInSection(section:Int) -> Int {
print(self.tableArray[section].count)
return self.tableArray[section].count
}
and in the viewcontroller as:-
func numberOfSections(in tableView: UITableView) -> Int {
return reviewViewModel.numberOfSections(tableView: tableView)
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// let headercell = Bundle.main.loadNibNamed("HeaderCell", owner: self, options: nil)?.first as! questionheader
let identifier = "HeaderCell"
var headercell: questionheader! = tableView.dequeueReusableCell(withIdentifier: identifier) as? questionheader
if headercell == nil {
tableView.register(UINib(nibName: "questionheader", bundle: nil), forCellReuseIdentifier: identifier)
headercell = tableView.dequeueReusableCell(withIdentifier: identifier) as? questionheader
}
headercell.setReviewData(reviews:reviewViewModel.titleForHeaderInSection(atsection:section))
return headercell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 63
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 2
//return 1
return reviewViewModel.numberOfRowsInSection(section: section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "Cell"
var cell: QuestionListCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_QuestionListCell
if cell == nil {
tableView.register(UINib(nibName: "NH_QuestionListCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? QuestionListCell
}
cell.contentView.backgroundColor = UIColor.clear
print(reviewViewModel.tableArray)
if (reviewViewModel.type == "1"){
cell.imagebutton.setImage(UIImage(named: "radio_uncheck.png"), for: .normal)
}
else{
cell.imagebutton.setImage(UIImage(named: "radio_uncheck.png"), for: .normal)
}
if let tempArray = reviewViewModel.tableArray[indexPath.section] as? [String] {
print(tempArray)
let values = tempArray[indexPath.row]
print(values)
cell.question.text = values
}
return cell
}
And how to display data of options in tableviewcell
Related
Now my ViewController code is here -
import UIKit
struct jsonstruct: Codable {
let name: String
let meta_data: [Categories]
enum CodingKeys: String, CodingKey {
case name
case meta_data
}
}
struct Categories: Codable {
let value: String
enum CodingKeys: String, CodingKey {
case value
}
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var arrdata : [jsonstruct] = [jsonstruct]()
var categorydata : [Categories] = [Categories]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
getdata()
}
func getdata() {
let url = URL(string: "https://mywebstaging.net/ab/garnier/wp-json/wc/v3/products?consumer_key=<key>&consumer_secret=<secret>")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
do{if error == nil{
self.arrdata = try JSONDecoder().decode([jsonstruct].self, from: data!)
print(self.arrdata)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}catch{
print("Error in get json data")
}
}.resume()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == tableView {
return arrdata.count
}else{
return categorydata.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == tableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdata = arrdata[indexPath.row]
cell.lblid.text = getdata.name
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdatadesciption = self.categorydata[indexPath.row]
cell.lblname.text = getdatadesciption.value
return cell
}
}
}
Hare only the "name" is being displayed in the tableview. But the "value" is not coming. The output I'm getting like this. Please guide me. Thanks in advance.
Replace
if tableView == tableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdata = arrdata[indexPath.row]
cell.lblid.text = getdata.name
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdatadesciption = self.categorydata[indexPath.row]
cell.lblname.text = getdatadesciption.value
return cell
}
with getdata.meta_data.first?.value contains top category name
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdata = arrdata[indexPath.row]
cell.lblid.text = getdata.name
cell.lblname.text = getdata.meta_data.first?.value
return cell
You don't have to maintain 2 arrays it's only one
Replace
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == tableView {
return arrdata.count
} else {
return categorydata.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == tableView {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdata = arrdata[indexPath.row]
cell.lblid.text = getdata.name
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let getdatadesciption = self.categorydata[indexPath.row]
cell.lblname.text = getdatadesciption.value
return cell
}
}
With
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrdata.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CellTableViewCell
let data = arrdata[indexPath.row]
let category = data.meta_data.first
cell.lblid.text = data.name
cell.lblname.text = category.value
return cell
}
What I want to do:
I have a feed (TableView( and once the user taps on a Post (TableViewCell), he should see a new Page (TableView) with the Post he tapped on first (the same TableViewCell) on top and a couple of comments below.
My Problem:
I dont get how to "clone" that TableViewCell.
Here two pictures for a better understanding:
Some complications:
I have multiple post types in the main feed, so the code would have to differentiate between them to see which cell type to use to display the content.
My code:
Main Feed
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return mixed.count
}
else if section == 1{
return phots.count
}
else{
return texttt.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell = tableView.dequeueReusableCell(withIdentifier: mixedTableViewCell.identifier, for: indexPath) as! mixedTableViewCell
cell.configure(with: self.mixed[indexPath.row])
return cell
}
else if indexPath.section == 1{
let cell = tableView.dequeueReusableCell(withIdentifier: popularTableViewCell.identifier, for: indexPath) as! popularTableViewCell
cell.configure(with: self.phots[indexPath.row])
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: self.texttt[indexPath.row])
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "commentsVC")
vc.modalPresentationStyle = .fullScreen
self.navigationController?.pushViewController(vc, animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
My second ViewController
class CommentsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var table: UITableView!
var texty = [TextComment]()
override func viewDidLoad() {
super.viewDidLoad()
table.register(popularTableViewCell.nib(), forCellReuseIdentifier: popularTableViewCell.identifier)
table.register(featuredTableViewCell.nib(), forCellReuseIdentifier: featuredTableViewCell.identifier)
table.register(textTableViewCell.nib(), forCellReuseIdentifier: textTableViewCell.identifier)
table.register(mixedTableViewCell.nib(), forCellReuseIdentifier: mixedTableViewCell.identifier)
table.register(textComTableViewCell.nib(), forCellReuseIdentifier: textComTableViewCell.identifier)
table.delegate = self
table.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return 1
}
else{
return 15
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: textComTableViewCell.identifier, for: indexPath) as! textComTableViewCell
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0{
// self.table.estimatedRowHeight = 250
// self.table.rowHeight = UITableView.automaticDimension
// return UITableView.automaticDimension
return 300
}
else{
// self.table.estimatedRowHeight = 150
// self.table.rowHeight = UITableView.automaticDimension
// return UITableView.automaticDimension
return 150
}
}
Note
Right now the it isnt working at all, how I want it. I just have these "mock" posts as space-fillers in there.
Any help or ideas would be greatly appreciated!
My structs
struct PhotoPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let postImageName: String
let postID: String
}
struct TextPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
let postID: String
}
struct MixedPhoto {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
let postImageName: String
let postID: String
}
Here my errors:
Each instance of UITableView has its own pool of cells, for this reason it would not be correct to "steal" an instance of the cell from one UITableView and put it into another. Also, as far as i can see you already have a convenient way to feed your cells with data, and dequeue corresponding types. Thus the only thing left here is to pass the required data from MainFeed under your tableView(_: didSelectRowAt:) function, something like that:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let vc = storyboard.instantiateViewController(withIdentifier: "commentsVC") as? CommentsViewController else {
return
}
switch indexPath.section {
case 0:
vc.mixedData = mixed[indexPath.row]
case 1:
vc.photoData = photos[indexPath.row]
default:
vc.textData = texttt[indexPath.row]
}
vc.modalPresentationStyle = .fullScreen
navigationController?.pushViewController(vc, animated: true)
}
And then, under the CommentsViewController's tableView(_:, cellForRowAt:) function, implement pretty much the same stuff you did in MainFeed:
var mixedData: MixedPhoto?
var photoData: PhotoPost?
var textData: TextPost?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell: UITableViewCell
switch (mixedData, photoData, textData) {
case (.some(let value), _, _):
cell = tableView.dequeueReusableCell(withIdentifier: mixedTableViewCell.identifier, for: indexPath) as! mixedTableViewCell
cell.configure(with: value)
case (_, .some(let value), _):
cell = tableView.dequeueReusableCell(withIdentifier: popularTableViewCell.identifier, for: indexPath) as! popularTableViewCell
cell.configure(with: value)
case (_, _, .some(let value)):
cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: value)
default:
fatalError("The data is not set")
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: textComTableViewCell.identifier, for: indexPath) as! textComTableViewCell
return cell
}
}
Also I should say that it's a good idea to implement a common protocol for your data types, so you actually can define a single non-optional variable in the CommentsViewController instead of three optionals.
This is the screen shot. According to this how to list the data in the tableview:
Already I have code as below.
func numberOfSections(in tableView: UITableView) -> Int {
return questionViewModel.numberOfSections()
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 100
} func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let identifier = "HeaderCell"
var headercell: questionheader! = tableView.dequeueReusableCell(withIdentifier: identifier) as? questionheader
if headercell == nil {
tableView.register(UINib(nibName: "questionheader", bundle: nil), forCellReuseIdentifier: identifier)
headercell = tableView.dequeueReusableCell(withIdentifier: identifier) as? NH_questionheader
} headercell.setReviewData(reviews:questionViewModel.titleForHeaderInSection(atsection:section))
headercell.isUserInteractionEnabled = false
return headercell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return questionViewModel.numberOfRowsIn(section: section)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let model = questionViewModel.titleForHeaderInSection(atsection: indexPath.section)
print(model.answerType)
print(model.answerType?.rawValue)
let c = model.answerType
return c!.cellType().getHeight()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = questionViewModel.titleForHeaderInSection(atsection: indexPath.section)
print(model.answerType)
print(model.answerType?.rawValue)
let c = model.answerType
let cellClass = c?.cellType().getClass()
print(cellClass)
let cell = tableView.dequeueReusableCell(withIdentifier: (cellClass?.cellReuseIdentifier())!, for: indexPath) as! BaseCell
print(cell)
cell.selectionStyle = .none
let optionModel = questionViewModel.datafordisplay(atindex: indexPath)
cell.setOptions(Options1: optionModel)
cell.delegate = self
if optionModel.isSelected!
{
print(optionModel.isSelected)
cell.setOptions1(OptionsSelected:optionModel)
}
else {
print(optionModel.isSelected)
cell.setOptions1(OptionsisSelected:optionModel)
}
cell.type = c?.cellType()
print(cell.type)
else if cell.type == .radiotype{
cell.selectionStyle = .none
}
return cell
}
This is my code. But according to this I will get the output as below screen shot.
Actually initially I need to display the section header as: - Please tell about us
After that there is subsection. The subsection questions header are as below: -1. knowledge 2. friendly or not
Then in the subsections display the options. How to do implement?
You can just display "Please tell us about" as UILabel above the table.
Below example may help you out.
let sections = [ // All sections
[ // Sports section
["Baseball", "Softball", "Cricket"], // Bat-and-Ball sub-section
["Field Hockey", "Ice Hockey", "Roller Hockey"] // Hockey subsection
], [ // Engineering section
["Software Engineer", "Electrical Engineer"] // Computer Science subsection
]
]
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionItems = sections[section]
var numberOfRows: Int = sectionItems.count // For second level section headers
for rowItems: [Any] in sectionItems as? [[Any]] ?? [] {
numberOfRows += rowItems.count // For actual table rows
}
return numberOfRows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var sectionItems = sections[indexPath.section]
var sectionHeaders = self.sectionHeaders[indexPath.section]
let itemAndSubsectionIndex: IndexPath? = computeItemAndSubsectionIndex(for: indexPath)
let subsectionIndex = Int(itemAndSubsectionIndex?.section ?? 0)
let itemIndex: Int? = itemAndSubsectionIndex?.row
if (itemIndex ?? 0) < 0 {
// Section header
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "SECTION_HEADER_CELL", for: indexPath)
cell.textLabel?.text = sectionHeaders[subsectionIndex] as? String
return cell
}
else{
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "ROW_CONTENT_CELL", for: indexPath)
cell.textLabel?.text = sectionItems[subsectionIndex][itemIndex ?? 0] as? String
return cell
}
}
func computeItemAndSubsectionIndex(for indexPath: IndexPath?) -> IndexPath? {
var sectionItems = sections[Int(indexPath?.section ?? 0)]
var itemIndex: Int? = indexPath?.row
var subsectionIndex: Int = 0
for i in 0..<sectionItems.count {
// First row for each section item is header
itemIndex = (itemIndex ?? 0) - 1
// Check if the item index is within this subsection's items
let subsectionItems = sectionItems[i] as? [Any]
if (itemIndex ?? 0) < Int(subsectionItems?.count ?? 0) {
subsectionIndex = i
break
} else {
itemIndex = itemIndex! - (subsectionItems?.count)!
}
}
return IndexPath(row: itemIndex ?? 0, section: subsectionIndex)
}
And for objective-C Help you may following URL
http://sapandiwakar.in/nested-sections-in-uitableview/
how to make model,viewModel and DataSourceModel for this type of api.
{"data":[{"id":45,"question":"Were the answers that staff provided to your questions presented in a way that you could understand?","options":["Yes, always","Yes, sometimes","No""Other"]}]}
this is my api.
According to my design i am using tableview section So in the header the questions will display and in the tableviewcell the list of options will display.
output as :-
Were the answers that staff provided to your questions presented in a way that you could understand?
Yes, always
Yes, sometimes
No
Other
this way i need to display.
My code is as below:-
model:-
classQuestionListModel: NSObject {
var home:[OPTIONS] = []
var id:String?
var question:String?
var options:[String]?
var v:String?
init?(dictionary :JSONDictionary) {
guard
let question = dictionary["question"] as? String,
let id = dictionary["id"] as? String
else {
return
}
if let options = dictionary["options"] as? [String]{
print(options)
}
self.question = question
self.id = id
}
}
viewmodel:-
func numberOfSections(tableView: UITableView) -> Int{
print((datasourceModel.dataListArray?.count)!)
return (datasourceModel.dataListArray?.count)!
}
func titleForHeaderInSection(atsection section: Int) -> QuestionListModel {
return datasourceModel.dataListArray![section]
}
func numberOfRowsInSection(section:Int) -> Int {
print(self.tableArray[section].count)
return self.tableArray[section].count
}
func datafordisplay(atindex indexPath: IndexPath) -> OPTIONS{
// print(datasourceModel.dataListArray![indexPath.section].options)
return datasourceModel.dataListArray![indexPath.row]
// return values
}
in viewcontroller:-
func numberOfSections(in tableView: UITableView) -> Int {
return reviewViewModel.numberOfSections(tableView: tableView)
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let identifier = "HeaderCell"
var headercell: questionheader! = tableView.dequeueReusableCell(withIdentifier: identifier) as? questionheader
if headercell == nil {
tableView.register(UINib(nibName: "questionheader", bundle: nil), forCellReuseIdentifier: identifier)
headercell = tableView.dequeueReusableCell(withIdentifier: identifier) as? questionheader
}
headercell.setReviewData(reviews:reviewViewModel.titleForHeaderInSection(atsection:section))
headercell.setReviewData(reviews:reviewViewModel.datafordisplay(atindex: section))
return headercell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 63
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return reviewViewModel.numberOfRowsInSection(section: section)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "Cell"
var cell: QuestionListCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? QuestionListCell
if cell == nil {
tableView.register(UINib(nibName: "QuestionListCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? QuestionListCell
}
cell.contentView.backgroundColor = UIColor.clear
cell.question.text = reviewViewModel.datafordisplay(atindex: indexPath)
print(reviewViewModel.tableArray)
return cell
}
in questionlistcell:-
class
QuestionListCell: UITableViewCell {
#IBOutlet weak var imagebutton: UIButton!
#IBOutlet weak var options: UILabel!
var i = 0
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func setReviewData(reviews:QuestionListModel)
{
print(reviews.options)
self.question.text = reviews.v
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
cell.question.text is expecting a string, & you passed QuestionListModel.
It should be
if let question = reviewViewModel.datafordisplay(atindex: indexPath).question {
cell.question.text = question
}
I'm in trouble with retrieving data from Firebase.
My JSON looks like this:
-user
-contacts
-autoID Value1
-contactName : A
-autoID Value2
-contactName : B
-autoID Value3
-contactName : C
(more contactName is coming, in same structure.)
But I have no idea how to get ALL contactName's Data(A,B,C....) then print in UITableView in Swift3.0
I want to make a result like this :
#In the TableView#
A
B
C
...
But My result is different, Maybe some problem in TableViewCell.swift... but I'm not sure
ViewController.swift :
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : MoneyTableViewCell = tableView.dequeueReusableCell(withIdentifier: "MoneyTableViewCell", for: indexPath) as! MoneyTableViewCell
cell.eachCell()
cell.layoutIfNeeded()
return cell
}
MoneyTableViewCell.swift
func eachCell() {
dbRef = Database.database().reference()
self.dbRef.child("user/contacts").observe(.value, with: {(snapshot) in
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let receiverNameDB = child.childSnapshot(forPath: "contactName").value! as! String
self.nameArray.append(receiverNameDB)
self.nameLabel.text = receiverNameDB
print(self.nameArray)
continue
}
}
})
}
Can Anybody help me please ;)
Update - I solved this problem! Here is my edited code...
Thanks to #Abdul91
The problem was.. I had to get the data from DB first, then put them in the array. After that get each data for tableView.
My edited code will tell you more.
ViewController.swift:
var nameArray:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
getNameDB{ value in
self.nameArray = value
self.tableView.reloadData()
}
tableView.register(UINib(nibName: "MoneyTableViewCell", bundle: nil), forCellReuseIdentifier: "MoneyTableViewCell")
}
//completion is for getting DB value outside of block..
func getNameDB(completion: #escaping (_ value: [String]) -> Void) {
self.dbRef.child("user/contacts").observe(.value, with: {(snapshot) in
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let receiverNameDB = child.childSnapshot(forPath: "contactName").value! as! String
self.nameArray.append(receiverNameDB)
}
completion(self.nameArray)
}
})
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.nameArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : MoneyTableViewCell = tableView.dequeueReusableCell(withIdentifier: "MoneyTableViewCell", for: indexPath) as! MoneyTableViewCell
cell.nameLabel.text = nameArray[(indexPath as NSIndexPath).row]
cell.layoutIfNeeded()
return cell
}