I have made a tableview controller with static cells in my storyboard(I used static cells because its a settings screen where almost all the cells are static except one). There is one cell which takes different contents(from different UITableViewCell xib s) on different conditions. If I try to assign that cell some value in func tableView(tableView: UITableView, cellForRowAtIndexPath..., then I ve to set the other cells also. Is there a way where I can set only one cell and take the other cells as how they are in the xib.?
Also if at all it is possible can I assign a static cell with contents of a cell's xib in case I already have one made?
use willdisplaycell function
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if (indexPath.row == 5){ //your row where you want to change
}
}
other row will be as it is in stroybord
There is no need of implementing cellForRowAtIndexPath for UITableViewController with static cells. You only need to make IBOutlet of your cell labels or the controls whose value you want to change at runtime on conditional bases. After that in UITableViewController class viewDidLoad or ViewDidAppear change the required control values based on your conditions.
Related
What is a better way:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
return cell
}
or
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) //cell has empty prototype in storyboard where setted this cellIdentifier
return cell
}
I know dequeueReusableCellWithIdentifier will reuse cells. But it would be better for performance in this case if we use simple UITableViewCell?
You should never use the first method. Performance wise the dequeuing method is much much better.
If you want a cell with a different style or different labels then create that in the storyboard or create a subclass.
But always use the dequeuing method.
Both are absolutely fine. It depends on you what type of setting you want. As far as dequeueReusableCell is consider it just save the memory. It allocates only some number of cell which can easily be shown into you device screen. For example if your screen can view 7 cells it will allocate 8 cells and then try to reuse these cell for different number of objects with respect to their indexPath.
I want to expand my UITableViewCells with a UITableView that has multiple sections. The way I'm doing it is as follows:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRowIndex = indexPath
habitTableView.beginUpdates()
habitTableView.endUpdates()
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if (selectedRowIndex != nil && indexPath == selectedRowIndex!){
return 147
}
return 90
}
However there are some strange behaviors, for example, if one cell expands it sort of "eats up" the next section header underneath it so the section header disappears. I am just wondering - is there any nuances with a UITableView that has multiple sections?
So, you can do one thing is to have two protocol type of UITableViewCell. One is for normal and another one is for expanded. Once you type on a cell, you just need to update the delegate to use expanded one instead normal one. When updating, you only need to call reloadRowsAtIndexPaths to prevent reload everything.
You only need to create one more cell prototype and have a boolean value for indicating the state. Then, add your logic to cellForRowAtIndexPath.
Hi I am newbie of swift ios, how can I add custom UIView(s) with different height (depends on condition) into UITableViewCell one by one, and one below another. Just like the reminder app in iphone but each cell with different/same customViews - depends on condition. What's the best approach or practice for this. Thanks gurus.
To use custom views into UITableViewCell you have to add a xib file and add to a class extended of UITableViewCell.
To specify your custom view and UITablaView you must do it here:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell.
Example:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("yourCellIdentifier") as! CustomView
...
return cell
}
To set auto height and more info you can follow this tutorial:
dynamic table view cell height ios 8 swift
i have a static table view with 2 sections. Each section has two rows. The first row is a date picker cell (DVDatePickerTableViewCell). Now i put manually a textfield into the second cell.
In the view controller i load the cells with this code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let CellID : NSString = "Cell"
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(CellID) as UITableViewCell
if indexPath.section == 0 && indexPath.row == 0 {
return cells[indexPath.section][indexPath.row] as UITableViewCell
}
return cell
The Cell with the identifier "Cell" has the textfield in it. But when the table view is load, the first cell works perfectly but the others are just empty cells. How can i return the cells with the "style", which i created in the storyboard?
Thanks in advance!
In case you would like to use static cells in your table view, make sure that "Static cells" is selected in your table view settings:
In this case you don't need to implement override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell, table view will handle cells loading and displaying automatically.
To link any outlets from Interface Builder to your code you don't even have to create custom classes for your cells, you can link your views from table view's cells in Interface Builder directly to your view controller:
So I have a UITableView which I plan to use 2 prototype cells inside of it. Let's call them Cell A and Cell B. Cell A has it's own layout and Cell B has it's own layout.
Here's the thing, in a typical UITableView implementation with only 1 prototype cell, after setting up all the cell and it's properties, cellForRowAtIndexPath takes care of populating all the rows based on the (x) number of items from numberOfRowsInSection.
Here is where I am having a problem. I've implemented both my prototype cells in my UITableView and when I run it, I notice cellForRowAtIndexPath is only being called twice, even though I have a value in (x) number of items which is greater than 2. Doesn't matter what I set it to, it only gets called twice. I already have the necessary if statements to pick a cell prototype based on the cell index etc...so that's not the issue. The issue is cellForRowAtIndexPath just gets called twice instead of looping thru all the items.
Why is this and how can I fix it?
This is my code for the DataSource methods:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
Scripts.log("Data Count = \(indexPath.row)")
if indexPath.row == 0{
var cell: ContactDetailImageCell = tableView.dequeueReusableCellWithIdentifier(NAME_OF_CUSTOM_IMAGE_CELL) as ContactDetailImageCell
cell.cardPhoto.image = aContact.profilePicture
cell.fullName.text = aContact.getDisplayName()
cell.workplace.text = aContact.workplace
return cell
}
else{
var cell: ContactDetailPhoneNumCell = tableView.dequeueReusableCellWithIdentifier(NAME_OF_CUSTOM_PHONE_CELL) as ContactDetailPhoneNumCell
return cell
}
return UITableViewCell()
}
What height are your cells? cellForRowAtIndexPath will only get called if the table thinks it needs to display the cell. Hence the whole reuse mechanism. So if you have 8 cells and it thinks 2 fill the screen it will not ask for any more until you scroll up/down.
What are you returning for heightForRowAtIndexPath.