I am currently using a custom collection view cell with separate nib file and implementation files. I am also handling a certain type of animation for scrolling. When there are many cells, some of them overlaps. So i am exploring an option of using various cell identifiers for different cells based on the cell index path. Is there any way to achieve this because the registering function require the user to define the cell identifier in advance?
you can use the registerClass method for different types of custom cells and different custom cell identifier. example in Swift:
searchResultsTableView.registerClass(HolidayItemTableViewCell.self, forCellReuseIdentifier: "holidayItemCell")
searchResultsTableView.registerClass(EmployeeSearchResultsTableViewCell.self, forCellReuseIdentifier: "employeeSearchResultCell")
searchResultsTableView.registerClass(OfficeSearchResultTableViewCell.self, forCellReuseIdentifier: "officeCell")
Related
I have a type of UITableViewCell that lets the user add/remove as many UITextViews as they want at run time.
I'm running into issues when trying to reuse/dequeue cells of that type, as sometimes the tableview cells just start overlapping when you scroll up and down. When I dequeue/return the cell, I'm running a setup method (which initiates a teardown method internally first to remove all the previous views), and uses the model to setup/restore all the necessary views and layout constraints.
if let cell = tableView.dequeueReusableCell(withIdentifier: "MultipleContentCell", for: indexPath) as? MultipleChoiceTableViewCell {
cell.setupCellWithModel(model: model)
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
cell.delegate = self
return cell
}
I can't really figure out why that cells sometimes overlap in the tableview, but I'm guessing it has to do with the layout being recreated on the fly. I'm considering not reusing these types of cells and just storing them in a list.
My question is: are reusable cells always suppose to have the same general UIView layout, and only the content changes? Am I not supposed to use reuse these types of cells? Or has someone experienced this before?
Thanks
The UITextView are created each time you dequeue cell and never delete. To repair that use function prepareForReuse(). You have to define, what your cell should do before dequeue in MultipleChoiceTableViewCell. For example:
override func prepareForReuse() {
super.prepareForReuse()
for view in speciesName.subviews {
if view is UITableView {
view.removeFromSuperview()
}
}
}
I added similar question few days ago:
Cells in UITableView overlapping. Many cells in one place
If you have some question, I can try to help you more tomorrow.
Cheers!
In general, yes. You want the physical layout of your cells to be static, and only vary the contents when you recycle them. If you add views to your cells in cellForRow(at:) then the burden is on you to manage the extra fields to avoid duplicate views.
Your case where you add a variable number of views to a table view cell based on user interaction is an odd case where you might need to add and remove cells on the fly.
One way to handle this would be to put all of your text fields in a container view, add an outlet to that container view, and then simply use code like this in your prepareForReuse or cellForRowAt function:
containerView.subviews.forEach { $0.removeFromSuperview() }
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
What is the purpose of the reuseIdentifier in above constructor.
The reuseIdentifier is used to group together similar rows in an UITableView.
A UITableView will normally allocate just enough UITableViewCell objects to display the content visible in the table.
If reuseIdentifier has not been set, the UITableView will be forced to allocate new UITableViewCell objects for each new item that scrolls into view, potentially leading to laggy animations.
The doc says:
The reuse identifier is associated with a UITableViewCell object that
the table-view’s delegate creates with the intent to reuse it as the
basis (for performance reasons) for multiple rows of a table view. It
is assigned to the cell object in initWithFrame:reuseIdentifier: and
cannot be changed thereafter. A UITableView object maintains a queue
(or list) of the currently reusable cells, each with its own reuse
identifier, and makes them available to the delegate in the
dequeueReusableCellWithIdentifier: method.
reuseidentifier is an id from which you can get cell from it.
As a cell scrolls out of the viewable area of the screen, the object representing it gets reused for cells scrolling on to the screen. The reuse identifier tells the system that an object can be reused for a cell entering the screen for which you request the same identifier.
Reuse identifiers are required by UITableViewCell in order to support the dequeueing of reusable cells by uniquely identifying cell types. Normally you create a unique string reuse identifier for each kind of cell you have use.
refer this https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/occ/instp/UITableViewCell/reuseIdentifier
Recently I am using twitter official iphone app. I noticed their UITableViewCells have some elements like label, image view and button. But not all of the cells have the same elements, some cells have a someone retweet label, but some cells don't. and some cell have images and some cell don't. So the question how they do it? Are they using multiple dynamic prototype cell?
You can create multiple cells in your story board and assign them different identifier.
Now you can dequeue different cell base on your logic
if(SomeConditionIsSatisfied)
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell2"];
}
There are multiple approach to achieve this.
Use different prototype cell.
Use same cell and manager your UI in cellForRowAtIndexPath. As in write conditions and tweek your UI accordingly.
Best we to do it is using a different prototype cell.
In order to implement a custom UITableViewCell, I know of two options:
Create a prototype cell in the storyboard view and assign tags to the cell's constituent views
Create a subclass of UITableViewCell with an associated xib
Using the tags seems simpler. I see that it has a couple of disadvantages including the inability to re-use the custom cell in more than one scene and potentially a lot of cell specific code in the view controller which could be an issue with a bunch of different cells.
For one or two cells that do not need to be reused in multiple scenes, does anyone know of any other considerations that I should take into account that might lead me to prefer a UITableViewCell subclass?
My recommendation is to use a UITableViewCell subclass with a storyboard prototype cell. Simply link your constituent views to IBOutlet properties as you would with any other class.
If you want to use the same cell in multiple tables then you need to re layout the prototype cell in each tableView, but you can cut and paste. Using tags results in unnecessary code to get references to the UI elements.
I have the only cell template for items at two different UITableViewControllers/TableViews.
What I need is to define it once and then reuse at other UITableView via
UITableView.DequeueReusableCell(CellId);
The issue is that is when I call this method on UITableView which doesn't contain cell prototype I'm getting NULL.
How to reuse my prototyped cell across multiple table controllers?
I want to define cell template in storyboard, NOT xib.
It turned out that the only way to reuse a cell it to design it with xib and register at tableview that xib with cellid.
Just copy-paste your prototype cell in every table view controller where you need it.
And if I understand your question, in a standard and proper way, it's not possible to dequeue a cell from another table view, Apple implementation handles this mechanism itself.
Using xib for a reusable cell is beneficial while cell design is fixed in the whole app. But when there are conditional requirements or slight changes in design or functionality and remaining design and functionality is same for tableview cell, in this case if you still want to reuse the code then you can subclass tableview cell class.