How to access to a textLabel in a static cell - ios

After much searching and reading I unfortunately do not come from the following. I want to use static tables to display certain data. (Are there better options?)
In my view I first put an onion picture with a container view underneath. The container view again refers to a Table View Controller.
I made an outlet from the cells and then I thought I could easily adjust the text.
Now I want to change the text of the fields in the table, but unfortunately I do not succeed.
When I start the app then the table is completely empty as seen on the screenshot.
What am I doing wrong ?
class TableViewController: UITableViewController {
var data: [String] = ["Muis", "Aap", "Koe", "Vis"]
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let iets = data[indexPath.row]
cell.textLabel?.text = iets
return cell
}
}

If you want to use static cells
Forget dequeueing UITableViewCell instances and all tableview data source and delegate methods.
In Interface Builder select the table view and select Static Cells from the Content popup
Drag the amount of static cells you need into the canvas
In the view controller declare IBOutlets and connect them directly to the UI elements in the cells

You need to change your way of thinking for this one. You do not own the cells, the UITableView does. It will provide cells as it seems fit by using your implementations of UITableViewDataSource:
func numberOfSections(in: UITableView) -> Int
func tableView(UITableView, numberOfRowsInSection: Int) -> Int
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
Normally, the texts (your actual data) would be held in a list available to this data source.
Example:
var data: [String] = []
// Other functions
func numberOfSections(in: UITableView) -> Int {
return 1
}
func tableView(UITableView, numberOfRowsInSection: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_IDENTIFIER")
cell.text = data[indexPath.row]
return cell
}
Now, if you want to change this cell's text, all you have to do is update your data list and reload the data.

What I have done after a lot of testing and reading. I have create a segue to the statutable class.
if (segue.identifier == "myEmbeddedSegue") {
let childViewController = segue.destination as! hondDetialTableViewController
childViewController.hondId = hondData["hondId"]!
}
In this segue I send only the hondId, everything else i ask entities.

I'm sorry but this is not at all how UITableView works. The UITableViewCell that you define in the Xib/Storyboard within the tableview are just "models" or templates, they don't actually exists until you dequeue them.
You can read how UITableView works here: http://www.thomashanning.com/uitableview-tutorial-for-beginners/
You have to return numberOfSections > 0 if you want anything displayed in your tableview; similarly, that section has to also have numberOfRows > 0 otherwise again, nothing will be displayed (ok, maybe headers and footers if those are properly setup).
At any rate, cells are only accessible after you dequeue them. Creating an outlet in a XIB to a UITableViewCell is useless in most cases.
You can explore other options, such as UIStackView, or maybe what you need is just plain custom UIView with labels that you properly set and layout using NSLayoutConstraints. There are plenty of resources out there, this is just one I quickly Googled for you to get started: https://www.youtube.com/watch?v=de0sthle44I
Good Luck.

Related

Swift 3.0 Using a Table View to Show and Add Comments

I am interested in having a tableview for comments (something similar to instagram comments). So far, I have used a custom cell to set up a textView for comments in my set array, dataName. I was wondering how I could go about setting up a textfield and button on the last row of the tableview that would act as the place to input more comments. Do I need to create another customcell for this and implement this in cellForRowAt indexPath ?
var comments = ["I like this item","Where did you get this?", "I can't believe you found this!", "Hello", "Yay"]
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.commentView.text = dataName[indexPath.row]
cell.commentView.textColor = UIColor.lightGray
cell.commentView.isEditable = false
cell.commentView.isScrollEnabled = false
return cell
}
You can accomplish you desired effect by adding a view that contains a text field and a button as the footer view of the tableview. And when a new comment is added you will proceed to add the comment to the array, and reload the tableview or insertRow with animation.
You already have one cell prototype called "Cell". Just add another cell prototype called "Comment". Now you have two cell prototypes with two different identifiers. If you're on the last row, ask for the "Comment" cell prototype in your dequeue call.

Swift 3 - Expandable table view cells without closing other ones

I am using Swift 3.
I've been following this tutorial: https://www.youtube.com/watch?v=VWgr_wNtGPM , supplemented by this answer on StackOverflow.
However, the way that this works is that if I click on a cell, it expands while hiding other cells. How do I make it such that when I expand it, the other already-expanded cells stay expanded?
The best approach I suggest you for achieving this in an elegant way is implementing it through UIStackView elements.
Take a look this post http://www.atomicbird.com/blog/uistackview-table-cells
if you wanna do this yourself, you could try this way.
first step is you should create a model list just like:
var cellsData: [CustomData] = [];
the CustomData seem like:
class CustomData {
var isExpanded: Bool = false;
// whatever other variables
}
then your custom cell should whatever look like but you must do something in the tableView:didSelectItemAt like:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = indexPath.row;
self.cellsData[row].isExpanded = !self.cellsData[row].isExpanded;
self.tableView.reloadRows(at: [indexPath], with: .none); // or the other animations
}
then in the "tableView:cellForRowAt" seems like:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell;
if(cell.isExpanded){
// do something when the cell is expanded
}else{
// do something when the cell is not expanded
}
}
remember, the cell is reusable, means if you have used the cell more than one time, then the cell will keep the state when it was used the last time.
You can use ExpyTableView, which makes an expandable section from your given header cell. Compatible down to iOS 8.0.
All you have to do is to import ExpyTableView and then:
class ViewController: ExpyTableViewDataSource, ExpyTableViewDelegate {
#IBOutlet weak var expandableTableView: ExpyTableView!
// First, set data source and delegate for your table view.
override func viewDidLoad() {
super.viewDidLoad()
expandableTableView.dataSource = self
expandableTableView.delegate = self
}
// Then return your expandable cell instance from expandingCell data source method.
func expandableCell(forSection section: Int, inTableView tableView: ExpyTableView) -> UITableViewCell {
// this cell will be displayed at IndexPath with section: section and row 0
}
}
You can see your former table view section is now an expandable table view section. You can also download the example project and see more detailed examples.

UITableViewController shows nothing but horizontal lines

I'm just starting with Swift and xCode, and currently messing around with UITableView, I can't manage to just write 'test' into a table.
I created a UITableViewController in the Storyboard, specified a custom class for it (my swift file below), filled in 'ClientCell' as a reuse identifier of the cell and the code is as follows:
class TableViewController: UITableViewController {
#IBOutlet var clientTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
clientTable.dataSource = self.dataSource;
clientTable.delegate = self;
}
func numberOfRowsInSection(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ClientCell", forIndexPath: indexPath) as! CustomTableViewCell
cell.tableLabel.text = "test"
return cell
}
}
In the storyboard, I added a 'UILabel' into the prototype cell, and created an outlet for it named 'tableLabel' in the CustomTableViewCell.swift.
I confused by all the side-things I've to consider when doing something as simple as this.
When I run it, the simulator just shows a table with a lot of horizontal lines, but nowhere it says 'test'.
You haven't used the numberOfRowsInSection method.....
Additionally you also need to set the table view's data source and delegate to be the class you are writing these methods in (in case you haven't).
At a bare minimum you need this:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1 // this should really be from your data source
}
If you create a UITableViewController subclass in Xcode the template will have commented-out versions of all the methods you likely will want to fill out.

Xcode 7.3 UITableViewController cell not displaying correctly

I try to display a simple cell with one label and an add item button. I can't get it to display correctly. I spent a lot of time but I can't find the solution.
This is the result:
There is no add item button and no correct row. I have just two items in coredata.
This is my code:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return items.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
let data = items[indexPath.row] as Item
cell.textLabel?.text = data.body
return cell
}
What are the problems? Can anyone help me to display add item button, correct row count, and customize height of the cell correctly? Thanks in advanced.
First lets return the correct number of rows unto the table view.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellContent.count
}
Next lets get it to output unto the prototype cells.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel?.text = cellContent[indexPath.row]
return cell
}
Also lets call the unto the view controller the following so that it can run properly.
ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
One last thing, your prototype's cell has the same identifier as the one in your code. In my code I would make sure that the identifier in the prototype cell is "Cell" since I called it in UITableViewCell(...reuseIdentifier: "Cell").
View picture to see where to add the identifier in your storyboard

SWIFT: Prototype Cells not being loaded after performSegueWithIdentifier

I have a ViewController that calls (clicking on a button) another View using this function
#IBAction func btnSeeContact(sender: AnyObject) {
self.performSegueWithIdentifier("segueSeeContact", sender: self)
}
and my prototype cell is "linked" to a custom View Controller named ContactsTableViewCell that I have created and it implements:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! ContactsTableViewCell
cell.txtName.text = "test"
cell.txtPhone.text = "1234567890"
return cell
}
When I run the project, the button calls the table, but there is no Cell on it, and I put a breakpoint on those tableView functions and they are not being reached.
What am I missing here that those functions are never being called?
I am adding a new answer since my previous answer was up voted, so I don't want to make massive edits that one, and is still a valid way to fix your issue.
The issue is you have your custom classes confused. In your screen shot you can see that the the Table View Controller is not set to a custom class, it just says Table View Controller. That is the object that needs to get a custom implementation of the UITableViewController class.
Instead you seem to be setting the cell's class to a custom class, and implementing the delegate methods there. You still need a custom class for the table view cell, but it should be a custom class of UITableViewCell.
So your cell class should look something like this:
import UIKit
class YourCustomTableViewCell: UITableViewCell {
#IBOutlet weak var yourLabel1: UILabel!
#IBOutlet weak var yourLabel2: UILabel!
}
You will be given an instance of this cell to configure in cellForIndexPath.
So your Table view controller class should be set to a class that looks like below. The YourTableViewController is were you want to implement all the delegate methods.
Note: if you are using a UITableViewController dragged out from the storyboard, it will already have the tableView, and delegate / data source stuff already wired up for you. You will also notice that you are overriding the delegate methods as the UITableViewController class has default implementations of these. If you are just using a normal view controller, then see my previous answer for more details on how to set that up.
import UIKit
class YourTableViewController: UITableViewController {
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
if let cell = cell as? YourCustomTableViewCell {
cell.yourLabel1.text = "some text"
cell.yourLabel2.text = "some other text"
}
return cell
}
}
As others have commented, you really need to provide a little more context.
Here are a few things that might be going wrong, providing more context would confirm or deny this guesses.
First you don't show the numberOfSectionsInTableView method.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 0
}
I think you would need to provide a value other than 0
Secondly, since I don't see override in front of what I am sure you are intending to be UITableViewDelegate methods function calls, that means your view controller is not a UITableViewController. This makes me wonder if you defined this view controller as conforming to the UITableViewDelegate protocol and if you set the table view outlet delegate to self. (or even wired up the UITableView to an outlet)
If you use a plain UIViewController to host a table view you need to do the following:
Wire up your UITableView to an outlet in your view controller
Declare the view controller as conforming to the UITableViewDeleagate (and maybe UITableViewDataSource) protocol
set the table view's outlet delegate (and maybe dataSource) properties to self (the view controller implementing the protocols)
Implement the required methods
So something like this:
class MyTableViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("your PrototypeCell", forIndexPath: indexPath)
// Configure the cell...
return cell
}
}

Resources