iOS: How to add/insert specific cell with identifier into UITableView? - ios

I have grouped static cells in a UITableView. Now I'd like to add or delete (what is easier?) one specific cell, which I've already created in my storyboard. It depends on one NSString: If my string == YES, the cell should be displayed, else it shouldn't.
already tried tableView:insertRowsAtIndexPaths:withRowAnimation:

What you need is:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
This method is part of the UITableViewDelegate protocol and will be called when the table view is about to draw a cell for a particular row. This provides a UITableViewCell for you to work with.
To identify which cell you need to hide, you can add a tag to the UITableViewCell in the storyboard. This is easier because you are adding static cells.
Then you can just do:
if ([cell tag] == someInteger) {
cell.hidden = YES;
}
You can wrap this in a condition based on the value of your string that you have mentioned.
I have added some example code on Github to illustrate this.

Related

How to get reference to current UITableViewCell

At my experiment I need to have reference to first UITableViewCell in tableView. By some action I need to set image and some other cell properties and to keep this state of this only cell even if the tableView will be scrolled. All of this properties can be potentially nulled via scrolling (and they actually are) because of reusing. For set this properties every time cell appears on screen, inside of `-cellForRowAtIndexpath' I tried to catch first cell using:
UITableViewCell *firstCell = (UITableViewCell *)[atableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
but looks like this way I can only catch every next first cell on next scrollable "screen".
So, how can I get ref to first UITableView cell?
If I understand you correctly, you are trying to do something special if the cell at (0, 0) is about to be displayed, right? If that's the case, you can easily implement UITableViewDelegate's tableView:willDisplayCell:forRowAtIndexPath: method as follows:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath) {
// Do something special
}
}
There is also a corresponding tableView:didEndDisplayingCell:forRowAtIndexPath: method if you need to undo things.
Hope it helps!
There is no "first" table view cell. The entire table view typically uses a single cell to improve performance.
You can change that, by implementing your own cell reuse system (search for reuse in the documentation). But generally the cell is the wrong place to store any data related to a specific index in the table view.

how to identify a view object without assigning its tag property

I place textview in the prototype cells by storyboard and assign the textview's tag.
In the implantation method of
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:,
I wanna assign the textview another identifier so that I can obtain the textview by this identifier. The reason why I don't use the TAG property to do this is because that all the cells in my table view has the same prototype for reusing.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
ETPost *post = postList[indexPath.row];
UITextView *textView = (UITextView*)[cell viewWithTag:TEXT_TAG];//TEXT_TAG 1000
textView.text =post.content;
return cell;
}
as you can see above, I use the viewWithTag, all the cells in my tableview have the same tag, so I have to another solution instead of assigning the indexPath to the TAG.
Alright, the answer is probably simpler than you think. But just subclass UITableViewCell and make sure that your table view is using your new subclass (you set this up in the prototype cell Custom Class in IB and StoryBoards). The only thing the subclass adds is a property that allows you to identify it.
#property short specialIdentifier;
Here's a more general link on UITableViewCells which I generally refer to when I need something done: cusomizing uitableviewcells
in -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath: you could assign the indexPath's row number to your textView's tag like:
cell.textView.tag = indexPath.row;
so this tag would correspond with your cell's indexPath distinct assuming you place all cells in ONE section.

Mixing static and dynamic sections in a grouped table view

I need a grouped UITableView similar to the one for Twitter accounts in Settings app:
That is, a sort of form or menu where some of the sections have a beforehand known set of static cells, and some other sections have to be dynamic and allow inserting additional rows the same way the "Add Account" does here. I'm managing the UITableView in a .xib file. For the static cells, I have separated .xib files that I can load within the cellForRowAtIndexPath: method in the view controller.
How should I handle this kind of table? I donĀ“t find any example code.
How the cellForRowAtIndexPath: method should look like? May I need to keep strong properties for the static cells? Would it be better to design each static cell directly within the same .xib file where the table view is, and to set outlets for them? (Though this does not allow to reuse my custom cells design...)
I need some guidelines for achieving this and correctly managing cells and memory. Thanks in advance
Dynamic prototype cells can behave like static ones if you just return the cell without adding any content in cellForRowAtIndexPath, so you can have both "static like" cells and dynamic ones (where the number of rows and the content are variable) by using dynamic prototypes.
In the example below, I started with a table view controller in IB (with a grouped table view), and changed the number of dynamic prototype cells to 3. I adjusted the size of the first cell to 80, and added a UIImageView and two labels. The middle cell is a Basic style cell, and the last one is another custom cell with a single centered label. I gave them each their own identifier. This is what it looks like in IB:
Then in code, I did this:
- (void)viewDidLoad {
[super viewDidLoad];
self.theData = #[#"One",#"Two",#"Three",#"Four",#"Five"];
[self.tableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 1)
return self.theData.count;
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0)
return 80;
return 44;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if (indexPath.section == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"TitleCell" forIndexPath:indexPath];
}else if (indexPath.section == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:#"DataCell" forIndexPath:indexPath];
cell.textLabel.text = self.theData[indexPath.row];
}else if (indexPath.section == 2) {
cell = [tableView dequeueReusableCellWithIdentifier:#"ButtonCell" forIndexPath:indexPath];
}
return cell;
}
As you can see, for the "static like" cells, I just return the cell with the correct identifier, and I get exactly what I set up in IB. The result at runtime will look like your posted image with three sections.
Static is just a provision on top of dynamic layout. Basically static is a WYSIWYG.
If you are not resistant to experiment with values, I would recommend go dynamic. There are hundreds of examples available, such as this and this.
As you go further, you would see yourself diverging towards two options when customizing dynamic table views:
Subclass UITableViewCell (more effort , but good in the long run). Again, follow this.
Play with UITableViewCell properties inside cellForRowAtIndexPath: (less effort and quick result but may or may not be performance-friendly due to possible redrawing)
The possibilities are endless, such as here where cell background view is customized.

Using the UIView-Glow category on UITableViewCell

I'm using the UIView-Glow category trying to highlight certain UITableViewCells. But it doesn't work if it's used in tableView:cellForRowAtIndexPath:.
I guess it must be used after the certain view appeared on the screen. So, is there a possibility to let certain UITableViewCells glow (even when scrolling the table view)?
Yes, there is possibility to let certain UITableViewCells glow with the category file you mentioned. You need to call the category methods in the table view delegate willDisplayCell instead of cellForRowAtIndexPath.
For example:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell startGlowing];
}

dim everything but selected row ios

How could I easily dim the complementary set of rows, when one gets selected.
Right now I have the code to select a cell so I can call a method on it, but I would like to set opacity of all the other rows.
-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SummaryCell * selectedCell = [tableView cellForRowAtIndexPath:indexPath];
[selectedCell manageContent];
}
Edit: I dont want to iterate through all the other cells (because there will be a lot of them) - wouldn't it be easier to add an UIView above all other cell (this would also prevent user interaction) and place the selected cell above that view (something like increasing z-index in HTML).
It depends what you mean by "dim" the other rows. The process to iterate over all visible rows and to set a property on all the rows other than the one selected is as follows:-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
for (UITableViewCell *otherCell in self.tableView.visibleCells) {
NSIndexPath *otherIndexPath = [self.tableView indexPathForCell:otherCell];
if (![indexPath isEqual:otherIndexPath]) { // exclude the selected cell
// Do whatever you want with otherCell here
}
}
}
Where my comment is, you can set whatever properties you like on otherCell. For example, otherCell.alpha which is the alpha (transparency) of that cell.
You can iterate all the visible cells, configure them to be dimmed, then on the datasource cellForIndex method check if there's a selected cell, if there is, check if it is at the asked index, if so configure the cell as selected, if not as dimmed.

Resources