I created a table view controller and from drop down in Xcode selected content to be static cells. I placed buttons in those cells but when I run I get an empty table. I didn't enter any code in the TableViewController class as I thought this was not needed.
How can this be fixed?
This is the way it looks in Xcode and then when it runs in simulator:
You may miss some stuff:
1) Check whether your tableView has set the class named as that on in your code. You find the input field to type the name of the class in Attributes inspector of the tableView.
2) Check whether you implemented methods, that comform to UITableViewDelegate and UITableViewDataSource Protocol.
func numberOfSections(in tableView: UITableView) -> Int {
// I see you only have 1 section now
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//you should return appropriate number
return 3
}
3) Check whether your table is properly connected from Storyboard to your UIViewController =>
if your tableView is inside UIViewController, check whether you set delegate and datasource for tableView in your controller (CTRL drag from table to FileOwner - rounded yellow icon in storyboard scene frame.)
using static cells, it's not necessary to implement numberOfSections and numberOfRowsInSection. By default, at runtime you get the static cell(s) as implemented in the designer.
However, if you do implement these methods and, by error, return 0: No cell is shown at runtime.
Following up on the answer above:
1) Make sure the tableview is hooked up as both the datasource and delegate.
2) Make sure these two lines of code are modified to your table. Default is to return 0 (an empty table) so you need to modify them accordingly. You can also choose to comment them out completely (what I did).
func numberOfSections(in tableView: UITableView) -> Int {
// I see you only have 1 section now
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//you should return appropriate number
return 3
}
Related
I've come across a very strange issue suddenly in an app I'm building - the tableViewCells in my tableView are not showing up at all, even though the tableView methods are firing (I've checked using print statements within them). The app does not crash, but everything within the table view cell is just not showing up anymore, even though all data variables have been updated.
Below are the tableView methods I've used:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let count = selectedValidInputs.count
return count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = carbonDetailsTable.dequeueReusableCell(withIdentifier: "CarbonDetailsCell") as! CarbonTableViewCell
cell.itemName.text = selectedValidInputs[indexPath.row]
cell.carbonValue.text = carbonValues[indexPath.row]
cell.tip.text = tips[indexPath.row]
cell.hashtag.text = tags[indexPath.row]
return cell
}
Covering some questions that may be asked
I have a Controller that conforms to UIViewController, UITableViewDelegate, UITableViewDataSource, so override methods are not required
I have made sure the identifier for the CarbonTableViewCell (the custom UITableViewCell class) matches the one being used in .dequeueReusableCell method
I have verified all the variable connections from the storyboard to the code
I have not set the number of sections within the tableView, but the code had been working for a month without that too, so don't think the problem is associated with that.
I'm very new to coding altogether, so any help and feedback would be much appreciated!
Note that the page is just empty. Even the 'cellBg' variable below, which is just a view and has a background color, does not show up and neither does the app crash - which is a bit weird.
Edit: Since this is being suggested by everyone, just updating here. On printing the results, I get all values: When the input value is "apple" for example, all the values are shown:
count: 1
selectedValidInputs: ["apple (1 kg)"]
carbonValues: ["550 g CO2, same as 22 plastic bags"]
tips: ["Avoid wastage that adds unnecessary methane to the air with decomposition!"]
tags: ["#very-low-carbon-impact"]
When I add carbonDetailsTable.register(CarbonTableViewCell.self, forCellReuseIdentifier: "CarbonDetailsCell") to viewDidLoad(), I get a crash with the msg shown in attached image
Number of sections is equal 0, ‘selectedValidInputs’ array is empty or you have not placed all of the code that is initialising it with values.
1) Try to implement also
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
2) Try to implement also
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 40.0
}
And comment the estimatedRowHeight and rowHeight setters, to confirm if the cell's autolayout is not broken and table view is unable to determine row height.
(estimatedRowHeight is basically used just for tableView indicator bar and estimating the content size of tableView)
Print your Arrays which you are passing in tableview in CarbonDetailsViewController, and check data is exact as you passed in previous viewcontroller.
I'm trying to create a reference to my TableView's static section. I control-drag the section from the Document Outline ("My Section", highlighted in the second screenshot) into the associated code file and Xcode offers to connect to a new UITableViewSection outlet (the "Type" field was pre-filled with "UITableViewSection"):
But then Xcode immediately complains telling me it doesn't know what UITableViewSection is:
I've imported UIKit, so that's not it. I can't find any documentation for UITableViewSection. It seems to not exist, but then why would Xcode let me drag it into the file to create an outlet?
You can not declare UITableViewSection like that, as there as no class available with that name.
You can do it simply by creating a custom prototype UITableViewCell and can use it custom section header like below-
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "SectionHeader") as! CustomHeaderUITableViewCell
return cell
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
I tried the same thing and same error occured. What i did was instead of creating an outlet on the section, i created an outlet on the Content View
#IBOutlet var editCountdownTableViewCell: UITableViewCell!
I am creating it because i want to be able to hide and show.
I'm starting to work with UITableViews and can't seem to find out how to change the position of a cell with code. Changing the position in the storyboard is straightforward enough but I need to be able to do it in swift.
TLDR;
Update your data. i.e. swap(&arr[2], &arr[3]).
Call the tableView's reloadData() method to reflect the changes to your data.
Long answer
An instance of UITableView works by checking its data source (UITableViewDataSource) for the information it needs. This includes the number of sections and rows, as well as the instance of UITableViewCell that the table view is to use. These are defined by the following UITableViewDataSource delegate methods:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int;
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int;
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell;
Usually, you would base the former two on some data you have, likely an Array or similar container. For example, if your tableView displayed data from an Array named fruitArray (which contained names of different fruit - a list of strings), then you might have something like the following:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Our array is one dimensional, so only need one section.
// If you have an array of arrays for example, you could set this using the number of elements of your child arrays
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Number of fruits in our array
return fruitArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("yourCellId") // Set this in Interface Builder
cell.textLabel?.text = fruitArray[indexPath.row]
return cell
}
Then, you can see that the answer to your question becomes simple! Since the contents of a given cell are based upon fruitArray, all you need to do is update your array. But how do you get the tableView to "recheck" its dataSource? Well, you use the reloadData method, like so:
swap(&fruitArray[2], &fruitArray[3])
tableView.reloadData()
This then triggers the tableView to "recheck" its dataSource, hence causing your data swap to appear on the screen!
If you'd like the user to be able to swap the positions of the cells, you can use the following UITableViewDelegate (not UITableViewDataSource) delegate method:
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
Have a look at this article for more info. You can also view Apple's documentation on UITableView, UITableViewDataSource, and UITableViewDelegate for further detail.
Hope this helps!
I have build UItableView with static cells, when I tried to run it nothing is appear in my simulator,
here is my interface builder looks like:
and here in simulator:
You need to provide return value for number of sections and number of rows. By default it is 0
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return 3
}
Make sure the tableview doesn't have a programatic datasource connected to your view controller, with the numberOfCells/numberOfSections/cellForRow methods overriding the static cell population
I have an UITableView with custom cells. I would like that the first row is always visible. As I have only once section, I thought of making a header but in this case I don't really know how to do it?
Is it possible to make a header from the first row with the same gesture recognizers, same dataSource behind the rows, briefly, have the header exactly like th row, just as if the row was pined to the top of the tableView?
You should use a header, or a separate view outside the table view. You can use the same gestures (generally, though not the delete) and data source.
If you want it all, you could use 2 table views- the first with one section and one row, the second with all the other data. It would be easiest if your data source was broken down in a similar way in the view controller.
In either case you can achieve what you want, but not by flicking a switch, you will need to add some logic and different views to make it happen.
If you want to make one static cell that is pinned to the top but in all other ways the same to the others, you could simply add one to your numberOfRowsInSection
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count + 1
}
Then when you display the cells, check for the row number and always set the first row to contain your static header content.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
// Create or set static cell content.
}
}
The other way is to create a custom section header and set it using viewForHeaderInSection
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section == 0 {
var view = UIView()
view.backgroundColor = UIColor.blueColor()
return view
}
return nil
}