Not work UITableView in cellForRowAt But numberOfRowsInsection Work in Swift - ios

I wrote a function to add a Cell in a UITableView.
numberOfRowsInSection works but cellForRowAt does not work.
class ShopMenuViewCell: UITableViewCell {
#IBOutlet weak var menuTableView: UITableView!
var menuPrice: MenuPrice!
override func awakeFromNib()
{
super.awakeFromNib()
}
}
extension ShopMenuViewCell
{
func setView()
{
self.menuTableView.delegate = self
self.menuTableView.dataSource = self
self.menuTableView.regCells(cells: ["ShopMenuInformationCell"])
DispatchQueue.main.async
{
self.menuTableView.reloadData()
}
}
}
extension ShopMenuViewCell : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "ShopMenuInformationCell", for: indexPath) as? ShopMenuInformationCell,
let menu = self.menuPrice,
let name = menu.name,
let price = menu.amt else { return ShopMenuInformationCell() }
return cell
}
}
In ShpMenuInformationCell.swift
class ShopMenuInformationCell: UITableViewCell
{
#IBOutlet weak var containerView: UIView!
#IBOutlet weak var shopNameLabel: UILabel!
#IBOutlet weak var menuNameLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
override func awakeFromNib()
{
super.awakeFromNib()
}
}
I saw the answer to add a ViewController, but I do not know what to do because it is not a storyboard. (.xib)
I think it is because I add UITableViewCell in the UITableViewCell class.
Do you know why?

I had a problem for about 5 days and found a solution!
First Reference Site: Joel's Answer cellForRowAtIndexPath: not called
Second reference site: Paolo's answer
Swift: UITableViewCell rowheight
When I add another kind of TableCell, the vertical size of the cell in question is small.
So I increased the size of the Cell's RowHeight (frame.height) before reloading the data and it's fixed!
Currently, cellforrowat runs safely. Your answers were helpful to the results.

Please try below code:
class ShopMenuViewCell: UITableViewCell
{
#IBOutlet weak var menuTableView: UITableView!
var menuPrice: MenuPrice!
override func awakeFromNib()
{
super.awakeFromNib()
}
fun setUpTable() {
self.menuTableView.regCells(cells: ["ShopMenuInformationCell"])
self.menuTableView.delegate = self
self.menuTableView.dataSource = self
self.menuTableView.reloadData()
}
}
and call the function setUpTable() from ShopMenuViewCell as an cell.setUpTable()

Try below code:
Solution 1
class ShopMenuViewCell: UITableViewCell {
#IBOutlet weak var menuTableView: UITableView! {
didSet {
self.menuTableView.regCells(cells: ["ShopMenuInformationCell"])
self.menuTableView.delegate = self
self.menuTableView.dataSource = self
}
}
}
Solution 2: Please check Anand Verma Answer

Related

ios swift tableview not showing custom cells

I am trying to create a table view with custom cells from Storyboard layout in an iOS app.
But for some reason the table cells are not being shown. When I tried to set debug breakpoints I found that the debugger is reaching this function
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
but it never reaches this function -
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
Here is my viewcontroller code -
extension NavigationViewController: UITableViewDataSource, UITableViewDelegate, SideMenuControllerDelegate {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTableItem", for: indexPath as IndexPath) as! SideMenuTableItem
cell.setItemData(items[indexPath.row])
return cell
}
public func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func setupTableViews() {
menuTable.register(SideMenuTableItem.self, forCellReuseIdentifier: "SideMenuTableItem")
}
}
class SideMenuTableItem: UITableViewCell {
#IBOutlet weak var menuImage: UIImageView!
#IBOutlet weak var menuLabel: UILabel!
var data: MenuItem?
override func awakeFromNib() {
super.awakeFromNib()
}
func setItemData(_ item: MenuItem) {
data = item
menuLabel.text = data?.title
if data?.icon_res != nil {
menuImage.image = UIImage(named: (data?.icon_res)!)
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
I have checked in the storyboard that I have set the reusable identifier to the table prototype cell and also connected the datasource and the delegate properties to the tableview
and I am calling the setupTableViews() method inside my viewDidLoad() function after creating the items array
But still I am not able to get the cells to appear in my view at all.
Can anyone suggest what am I missing here or what's wrong with my code, or how can I further debug this issue
import UIKit
import SideMenuSwift
class NavigationViewController: UIViewController {
#IBOutlet weak var navigationContainer: UIView!
#IBOutlet weak var emailButton: UIButton!
#IBOutlet weak var phoneButton: UIButton!
#IBOutlet weak var userAvatar: UIImageView!
#IBOutlet weak var userProfile: UIButton!
#IBOutlet weak var userName: UILabel!
#IBOutlet weak var menuTable: UITableView!
var service: AuthenticationService!
var cdc: CoreDataController!
var items: [MenuItem] = []
var currentUser: User?
override func viewDidLoad() {
super.viewDidLoad()
setupSidebar()
initSidebarData()
setupUserHeader()
setupTableViews()
}
func setupUserHeader() {
if currentUser != nil {
if currentUser?.name != nil {
userName.text = currentUser?.name
} else if currentUser?.role != nil {
userName.text = "urTutors " + (currentUser?.role ?? "")
}
if currentUser?.avatarUrl != nil {
userAvatar.downloaded(from: (currentUser?.avatarUrl)!)
}
}
}
func initSidebarData() {
service = AuthenticationServiceProvider()
cdc = CoreDataController()
items = cdc.getNavigationData()
currentUser = cdc.getUserData()
}
func setupSidebar() {
self.view.backgroundColor = UIColor.hexColor("#fff")
navigationContainer.backgroundColor = UIColor.hexColor("#2a2a2a")
SideMenuController.preferences.basic.statusBarBehavior = .hideOnMenu
SideMenuController.preferences.basic.position = .above
SideMenuController.preferences.basic.direction = .left
SideMenuController.preferences.basic.enablePanGesture = true
SideMenuController.preferences.basic.menuWidth = 275
sideMenuController?.delegate = self
}
static func createViewController() -> NavigationViewController {
let sb = UIStoryboard(name: "StudentHomeModuleStoryboard", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "NavigationViewController")
return vc as! NavigationViewController
}
}
--UPDATE--
updated setupTableLayout function -
func setupTableViews() {
let bundle = Bundle(for: type(of: self))
let cellNib = UINib(nibName: "SideMenuTableItem", bundle: bundle)
menuTable.register(cellNib, forCellReuseIdentifier: "SideMenuTableItem")
menuTable.register(SideMenuTableItem.self, forCellReuseIdentifier: "SideMenuTableItem")
menuTable.reloadData()
}
After breaking into chat on this, we found that there were two issues.
The first issue was the missing reloadData call mentioned above. That was causing cellForRow to not be called. Adding reloadData corrected that issue, but then the custom cell class's outlets were nil, causing a crash in setItemData.
The second issue was that register(_:forCellReuseIdentifier:) was being called in code, but the custom cell was already setup as part of the Interface Builder UITableView declaration. Calling register again on the custom class re-registered the reuseIdentifier, disconnecting the outlets set up in the storyboard.
Removing the register call and adding reloadData solved all issues.
You are never calling setupTableViews(). You'r code should look like this:
class NavigationViewController: UIViewController, SideMenuControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setupTableViews()
}
func setupTableViews() {
menuTable.reloadData()
}
}
extension NavigationViewController: UITableViewDataSource, UITableViewDelegate {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTableItem", for: indexPath as IndexPath) as! SideMenuTableItem
cell.setItemData(items[indexPath.row])
return cell
}
public func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
You are never calling the function, nor calling viewDidLoad. This should help. Also, where is the rest of your view controller code (is this all of it? It should not be!).
You don't need to register your cell because you requested it and make sure you reloadData().
Hope this helps!

Deleting a UITableView cell in a specific section

There is a task. Each cell contains a button by clicking which you want to delete this cell. The problem is that sections are used to delineate the entire list by category. The data I take from Realm DB. removal must occur under two conditions because the name is repeated, so you need to consider the name from the label and the name of the section. I will be very grateful for the sample code with comments.
import UIKit
import RealmSwift
class PurchesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var purchesTableView: UITableView!
let manage = ManagerData()
override func viewDidLoad() {
super.viewDidLoad()
purchesTableView.delegate = self
purchesTableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
purchesTableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return manage.loadPurchases().0.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return manage.loadPurchases().0[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return manage.loadPurchases().1[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "purchesCell", for: indexPath) as! CustomPurchesTableViewCell
cell.productLabel.text = manage.loadPurchases().1[indexPath.section][indexPath.row]
cell.weightProductLabel.text = manage.loadPurchases().2[indexPath.section][indexPath.row]
cell.weightNameLabel.text = manage.loadPurchases().3[indexPath.section][indexPath.row]
// cell.boughtButton.addTarget(self, action: #selector(removeProduct), for: .touchUpInside)
return cell
}
}
class CustomPurchesTableViewCell: UITableViewCell {
#IBOutlet weak var boughtButton: UIButton!
#IBOutlet weak var productLabel: UILabel!
#IBOutlet weak var weightProductLabel: UILabel!
#IBOutlet weak var weightNameLabel: UILabel!
#IBAction func removePurches(_ sender: Any) {
print("remove")
}
}
method for get data
func loadPurchases() -> ([String], Array<Array<String>>, Array<Array<String>>, Array<Array<String>>) {
var sections: [String] = []
var product = Array<Array<String>>()
var weight = Array<Array<String>>()
var nameWeight = Array<Array<String>>()
let realm = try! Realm()
let data = realm.objects(Purches.self)
for item in data {
if sections.contains(item.nameDish) == false {
sections.append(item.nameDish)
}
}
for a in sections {
var productArr = Array<String>()
var weightArr = Array<String>()
var nameWeightArr = Array<String>()
for prod in data {
if a == prod.nameDish {
productArr.append(prod.product)
weightArr.append(prod.weight)
nameWeightArr.append(prod.nameWeigh)
}
}
product.append(productArr)
weight.append(weightArr)
nameWeight.append(nameWeightArr)
}
return (sections, product, weight, nameWeight)
}
Index path you will get in cell class
Index path have two property section and row for table view
Now you can create on more method in Controller class and assign to a variable to every cell or you can use editAction provided by table view for delete
in order to get number section and row you need create IBOutlet in custom cell and on ViewController class is created addTarget for your button.
Example code at the bottom.
import UIKit
import RealmSwift
class PurchesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var purchesTableView: UITableView!
let manage = ManagerData()
//... more code ...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "purchesCell", for: indexPath) as! CustomPurchesTableViewCell
cell.productLabel.text = manage.loadPurchases().1[indexPath.section][indexPath.row]
cell.weightProductLabel.text = manage.loadPurchases().2[indexPath.section][indexPath.row]
cell.weightNameLabel.text = manage.loadPurchases().3[indexPath.section][indexPath.row]
cell.boughtButton.addTarget(self, action: #selector(removePurches(_:)), for: .touchUpInside)
return cell
}
#objc func removePurches(_ sender: UIButton) {
let position: CGPoint = sender.convert(CGPoint.zero, to: purchesTableView)
let indexPath: IndexPath! = self.purchesTableView.indexPathForRow(at: position)
print("indexPath.row is = \(indexPath.row) && indexPath.section is = \(indexPath.section)")
purchesTableView.deleteRows(at: [indexPath], with: .fade)
}
}
and custom class CustomPurchesTableViewCell for cell
class CustomPurchesTableViewCell: UITableViewCell {
#IBOutlet weak var boughtButton: UIButton! // you button for press
#IBOutlet weak var productLabel: UILabel!
#IBOutlet weak var weightProductLabel: UILabel!
#IBOutlet weak var weightNameLabel: UILabel!
}

UITableView with CustomCell not show data Swift4 on Xcode9

I read the other topics, but not solves my problem, I create a tableview and your cells with same value to make tests, but when I execute my project nothing data is showed. I put 5 size of rows to only to test. I don't know why my code not works.
My storyboard:
TableViewCellVenda.swift
class TableViewCellVenda: UITableViewCell {
#IBOutlet weak var cellView: UIView!
#IBOutlet weak var imageCloud: UIImageView!
#IBOutlet weak var labelValorTotal: UILabel!
#IBOutlet weak var labelQtdItens: UILabel!
#IBOutlet weak var labelCliente: UILabel!
#IBOutlet weak var labelDataVenda: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
ViewControllerVendas.swift
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// UI View
#IBOutlet weak var tableViewVendas: UITableView!
#IBOutlet weak var waitView: UIActivityIndicatorView!
// DB
var db: OpaquePointer?
var count : Int = 0
// Data
var saleOrders : [SaleOrder] = []
override func viewDidLoad() {
super.viewDidLoad()
self.waitView.startAnimating()
self.waitView.hidesWhenStopped = true
tableViewVendas.delegate = self
tableViewVendas.dataSource = self
}
// TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellVenda") as! TableViewCellVenda
print("Cell for row")
cell.labelCliente.text = "Nome do Cliente"
cell.labelDataVenda.text = "14/02/1991"
cell.labelQtdItens.text = "20"
cell.labelValorTotal.text = "R$ 542,22"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 75
}
}
Emulator:
Try adding a new swift UIKit file with a class of type UITableView and do all the tableview setup in there. And of coarse set the tables’s class as this UITableView class.

Datepicker won't display in custom UITableViewCell class

I try to keep a separate custom cell class, but somehow the datepicker I dragged into it from storyboard refuses to show up after I ran it.
import UIKit
class eventViewController: UIViewController,UITextViewDelegate,UIScrollViewDelegate,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var timeTableView: UITableView!
#IBOutlet weak var eventText: UITextView!
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.eventText.delegate = self
self.scrollView.delegate = self
self.timeTableView.delegate = self
self.timeTableView.dataSource = self
self.timeTableView.register(startDateCell.self, forCellReuseIdentifier: "startDateCell")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "startDateCell", for: indexPath) as! startDateCell
//cell.startDatePicker.date = Date()
//cell.text = "anything"
return cell
}
}
class startDateCell: UITableViewCell {
#IBOutlet weak var startDatePicker: UIDatePicker!
}
I have the outlet connected to my datePicker in the custom cell and I also defined my custom cell class to be startDateCell in inspector, and I registered my custom cell in my view controller. It will throw a runtime error saying the datepicker is nil.
Can somebody explain why it isn't showing up?
Can you remove the following code from viewDidLoad() and ensure you have set reuse identifier of custom tableviewcell as "startDateCell" in storyboard and try again?
self.timeTableView.register(startDateCell.self,
forCellReuseIdentifier: "startDateCell")

Swift -> my prototype cell (UITableViewCell) doesn't show in my UIViewController with a UITableView

My storyboard looks like this
and my code is the following
UIViewController
class DownLoadSoundsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: View Controller Properties
let viewName = "DownLoadSoundsViewController"
#IBOutlet weak var visualEffectView: UIVisualEffectView!
#IBOutlet weak var dismissButton: UIButton!
#IBOutlet weak var downloadTableView: UITableView!
// MARK: Properties
var soundPacks = [SoundPack?]() // structure for downloadable sounds
override func viewDidLoad() {
super.viewDidLoad()
downloadTableView.dataSource = self
downloadTableView.delegate = self
downloadTableView.register(DownLoadTableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfSoundPacks
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let method = "tableView.cellForRowAt"
//if (indexPath as NSIndexPath).section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "downloadTableViewCell", for: indexPath) as! DownLoadTableViewCell
cell.backgroundColor = UIColor.green
if soundPacks[(indexPath as NSIndexPath).row]?.price == 0 {
cell.soundPackPriceUILabel.text = "FREE"
} else {
cell.soundPackPriceUILabel.text = String(format: "%.2", (soundPacks[(indexPath as NSIndexPath).row]?.price)!)
}
//cell.textLabel?.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackTitleUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.soundPackTitle
cell.soundPackAuthorUILabel.text = soundPacks[(indexPath as NSIndexPath).row]?.author
cell.soundPackShortDescription.text = soundPacks[(indexPath as NSIndexPath).row]?.shortDescription
cell.soundPackImage.image = UIImage(named: "Placeholder Icon")
DDLogDebug("\(viewName).\(method): table section \((indexPath as NSIndexPath).section) row \((indexPath as NSIndexPath).row))")
return cell
//}
}
UItableViewCell
class DownLoadTableViewCell: UITableViewCell {
#IBOutlet weak var soundPackImage: UIImageView!
#IBOutlet weak var soundPackTitleUILabel: UILabel!
#IBOutlet weak var soundPackAuthorUILabel: UILabel!
#IBOutlet weak var soundPackShortDescription: UILabel!
#IBOutlet weak var soundPackPriceUILabel: UILabel!
let gradientLayer = CAGradientLayer()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
But I get the following;
I am sure I am doing something small incorrectly, but as of yet can't figure it out. Looked through many examples included my own code where I have gotten this working before.
Not a single one of my settings for the tableview are getting invoked except the number of cells. But everything in;
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{...}
is not working.
Help is appreciated.
I think you need to reload the tableView after getting data from Firebase
self.saveMixesTableView.reloadData()

Resources