UITable View Cell not Appearing in Swift - ios

So I added a table view to a normal view controller and inside that table view I made a prototype cell. Ive done some work to make the cell appear but it won't. How do I fix this? Here is my code:
import UIKit
class NewsScreenViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var trendingButton: UITabBarItem!
#IBOutlet weak var newestButton: UITabBarItem!
#IBOutlet weak var topJournalists: UITabBarItem!
#IBOutlet weak var tabBar: UITabBar!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return UITableViewCell()
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
}

You need to return cell after you get the cell and give it something to display. Try something more like this
let fillTableViewArray = [String]()
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReuseableCellWithIdentifier("cell")
//now that you have that cell you have to put something into it. For example an Array of strings, can be used to fill the table view
cell!.textLabel?.text = fillTableViewArray[indexPath.row]
return cell!
}
If you want to do this in the storyboard, you can instead add a label to the prototype cell in the storyboard, set an integer value for the label's tag, and then find the label by adding these two lines after you do let cell = ...
let label = cell.viewWithTag(100) as UILabel!
label.text = fillTableViewArray[indexPath.row]
I hope this helps fix your issue

Related

The outlet from the VC to the UILabel is invalid. Outlets cannot be connected to repeating content

I am working on a todo list app that works with a table view in Swift. The table view has a UILabel called titleLabelOutlet. When I was building the app I got an error that says The titleLabelOutlet outlet from the FirstViewController to the UILabel is invalid. Outlets cannot be connected to repeating content.I have never received this error before. How do I fix it? This is my code:
import UIKit
var phoneNumberList = [String]()
var titleFieldList = [String]()
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var titleLabelOutlet: UILabel!
#IBOutlet weak var phoneNumberLabelOutlet: UILabel!
#IBOutlet weak var myTableView: UITableView!
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return (phoneNumberList.count)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
phoneNumberLabelOutlet.text = phoneNumberList[indexPath.row]
titleLabelOutlet.text = titleFieldList[indexPath.row]
return(cell)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
if editingStyle == UITableViewCellEditingStyle.delete
{
phoneNumberList.remove(at: indexPath.row)
titleFieldList.remove(at: indexPath.row)
myTableView.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
myTableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
// 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.
}
}
Your outlets should be in cell class instead of viewcontroller because labels are inside cell
And in crllfor row at delegate you have to get your outlets like that
`let cell = tableView.dequeueReusableCell(withReuseIdentifier: cellIdentifier", for: indexPath) as! TableViewCellClass
            cell.lbloutlet.text = "any text"
return cell
`
Create CustomTableCell subclassing UITableViewCell.
Have Labels in cell and connect to phoneNumberLabelOutlet & titleLabelOutlet in CustomTableCell class.
use CustomTableCell in place UITableViewCell for cellForRowAtIndex function.
now you can set values for labels as
cell.phoneNumberLabelOutlet.text = phoneNumberList[indexPath.row]
cell.titleLabelOutlet.text = titleFieldList[indexPath.row]

Custom UITableViewCell not working

I want to make a custom UITableViewCell that can have many columns. One will be a UILabel and one will be a UIButton. I want to start this off by saying I only create my IBOutlets by holding the control key and dragging the UI items to my code. So this means all of my IBOutlets are connected properly. My problem is that the UILabel and the UIButton are not visible in any of my cells. The cells are there, but nothing else.
class CustomTableViewCell: UITableViewCell{
#IBOutlet weak var label: UILabel!
#IBOutlet weak var button: UIButton!
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
var items: [Strings] = ["one", "two", "three"]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad(){
super.viewDidLoad()
self.tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:CustomTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell")! as! CustomTableViewCell
cell.label?.text = self.items[indexPath.row]
return cell
}
}
I have the UITableView's data source and delegate set to the ViewController, I have the cell reuse id set up properly and both the UILabel and UIButton have constraints set up. I feel like I am missing something.
You must not register the cell – when using prototype cells – but you must reload the table view.
Replace
override func viewDidLoad(){
super.viewDidLoad()
self.tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")
}
with
override func viewDidLoad(){
super.viewDidLoad()
self.tableView.reloadData()
}
Those are missing:
self.tableView.delegate = self
self.tableview.datasource = self
Hope this helps!

Trigger an action when cell in static UITableView is tapped [Swift]

I have eight, different static cells in a tableview. I am trying to perform different actions with six of the cells. Two of them open an alert view, two open safari, one clears a cache, and the last one opens a share popover. Previously, they all worked with UIButtons and IBActions. But since setting up a static tableview, I am running into issues.
I'm trying to link up the individual cells to their own actions and I can't seem to do that with outlets. How might I do this?
Thank you.
Swift 3
Table View code:
import UIKit
class AltSettingsTableViewController: UITableViewController {
#IBOutlet weak var copyrightInfo: UITableViewCell!
#IBOutlet weak var shareApp: UITableViewCell!
#IBOutlet weak var rateApp: UITableViewCell!
#IBOutlet weak var clearCache: UITableViewCell!
#IBOutlet weak var purchasePhotos: UITableViewCell!
#IBOutlet weak var helpFeedback: UITableViewCell!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.backgroundColor = UIColor.clear
self.tableView.backgroundView = nil;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.minimum(35, 35)
}
override var prefersStatusBarHidden: Bool {
get {
return true
}
}
Have you overridden func tableView(UITableView, didSelectRowAt: IndexPath)? It should let you know when a cell is tapped and then you can use indexPath to determine which cell it was.
Edit: documentation for UITableViewDelegate and NSIndexPath.
Example:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
// do stuff
}
//...
}

XCode: Unable to embed a UITableview in a UIViewController

I want to create a UIViewController with an embedded UITableView. I've seen various examples but so far have been unable to get it to work. The outlets are embedded in the table cells.
class CREWStartMenuVCCell: UITableViewCell {
#IBOutlet weak var myButton: UIButton!
#IBOutlet weak var myTextView: UITextView!
}
class CREWStartMenuVC: UIViewController { // , UITableViewDelegate { // UITableViewDataSource,
#IBOutlet weak var tableView: UITableView! //<<-- TableView Outlet
override func viewDidLoad() {
super.viewDidLoad()
createAppData()
tableView.registerClass(CREWStartMenuVCCell.self, forCellReuseIdentifier: getCellName(viewName))
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> CREWStartMenuVCCell! {
let cell = tableView.dequeueReusableCellWithIdentifier(getCellName(viewName), forIndexPath: indexPath) as! CREWStartMenuVCCell
// processing cell code not relevant
I get this error if I attempt to override the following functions: Method does not override any method from its superclass. What am I missing?
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { // was override
// calculate length of text and adjust the size of cell for that
return calculateTipsHeight(viewName, text:getTipsInfo(viewName, sectionNumber: indexPath.section, tipOrder: indexPath.row).tipItemText)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {section))
return getTipsRowCount (viewName, sectionNumber: 0)
}
UPDATE
I get the following errors when I try to add UITableViewDataSource:
5:17: Protocol requires function 'tableView(_:cellForRowAtIndexPath:)' with type '(UITableView, cellForRowAtIndexPath: NSIndexPath) -> UITableViewCell'
34:10: Candidate has non-matching type '(UITableView!, cellForRowAtIndexPath: NSIndexPath!) -> CREWStartMenuVCCell!'
I don't see the error.
Since the class CREWStartMenuVC does NOT inherit from UITableViewController (or any other class which implements those methods), the methods in the protocols UITableViewDelegate and UITableViewDataSource can (or must) be implemented but they are not overridden. That means that the implementation of those methods cannot be preceded by
override
Also, in case you didn't do it in the Storyboard, don't forget to set the delegate and the dataSource of the tableView, for example, in the call to viewDidLoad() of your CREWStartMenuVC class.
tableView.delegate = self
tableView.dataSource = self
About the two errors from the UPDATE, just replace
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> CREWStartMenuVCCell!
with
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> CREWStartMenuVCCell!
(the only differences are the exclamations ! after the classes UITableView and NSIndexPath)
I got it to work without UITableViewDataSource after I removed the tableView.registerClass
Here is the working code:
class CREWStartMenuVCCell: UITableViewCell {
#IBOutlet weak var myButton: UIButton!
#IBOutlet weak var myTextView: UITextView!
}
class CREWStartMenuVC: UIViewController, UITableViewDelegate { //, UITableViewDataSource { //
#IBOutlet var tableView: UITableView! //<<-- TableView Outlet
override func viewDidLoad() {
super.viewDidLoad()
createAppData()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> CREWStartMenuVCCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier(getCellName(viewName), forIndexPath: indexPath) as! CREWStartMenuVCCell
// MARK: Common tips code

creating a custom TableViewCell in swift

I created a custom class for a cell in my program. When I try to use it in another class to create a cell I keep getting the error Cannot invoke 'init' with an argument list of type '(style: UITableViewCellStyle, reuseIdentifier: StringLiteralConvertible)'. Can anybody point me in the right direction here? I would really appreciate any help. I tried changing the class to inherit form UITableViewController so I can use this var cell: bookCell = self.tableView.dequeueReusableCellWithIdentifier("cell1") as bookCell but it crashes the program if I try to make the class inherit from tableviewcontroller.
import UIKit
class bookCell: UITableViewCell {
#IBOutlet var bookImage: UIImageView!
#IBOutlet var bookDescription: UILabel!
#IBOutlet var bookPosterUsername: UILabel!
}
import UIKit
class SubjectBooksViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var navigationBarTitle: UINavigationBar!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationBarTitle.topItem?.title = "\(selectedCourse)"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : bookCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "subjectCell")
//var cell: bookCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "subjectCell")
//var cell: bookCell = self.tableView.dequeueReusableCellWithIdentifier("cell1") as bookCell
return cell
}
}
Update code:
import UIKit
class SubjectBooksViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var navigationBarTitle: UINavigationBar!
#IBOutlet var myTableView: UITableView! //Outlet for your table View
override func viewDidLoad() {
super.viewDidLoad()
self.myTableView.dataSource = self //If you have not done in IB
self.myTableView.registerNib(yourCellNib, forCellReuseIdentifier: "subjectCell")
self.navigationBarTitle.topItem?.title = "\(selectedCourse)"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : bookCell = tableView.dequeueReusableCellWithIdentifier("subjectCell", forIndexPath: indexPath)
return cell
}
}
In viewDidLoad() in line :
self.myTableView.registerNib(yourCellNib, forCellReuseIdentifier: "subjectCell")
replace yourCellNib with loaded nib file for your custom cell.
Registering your nib file is required if you plan to reuse cell in your table view. It is always a good idea to reuse cells.
You need to override this function and get your custom cell in this manner:
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell = tableView.dequeueReusableCellWithIdentifier(
"subjectCell",
forIndexPath: indexPath) as bookCell
Your class name really should be BookCell though, with an uppercase "B". Just to keep with existing standards

Resources