UITableView with image change after scrolling - ios

I'm trying to create a custom UITableView with different cell identifiers. In the first cell should display an image and below to follow the rest of the cells. However when after scrolling the displayed image disappears. I tried to solve by looking for the answers provided by others for similar problems but without success.
Here's the code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
EventoCell *cell;
static NSMutableString *CellIdentifier;
if(i==0){
CellIdentifier = #"imgCell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
i++;
}
else{
CellIdentifier = #"CellaEvento";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.Nome.text=[[AShow objectAtIndex:indexPath.row]GetEvento];
cell.Localita.text=[[AShow objectAtIndex:indexPath.row]GetLocalita];
cell.Ora.text=[NSString stringWithFormat:#"%d:%d",[[AShow objectAtIndex:indexPath.row]GetOra],[[AShow objectAtIndex:indexPath.row]GetMinuti]];
[cell setValue:[[AShow objectAtIndex:indexPath.row]GetEvento] :[[AShow objectAtIndex:indexPath.row]GetGiorno] :[[AShow objectAtIndex:indexPath.row]GetMese] :[[AShow objectAtIndex:indexPath.row]GetAnno] :[[AShow objectAtIndex:indexPath.row]GetOra] :[[AShow objectAtIndex:indexPath.row]GetMinuti]];
}
return cell;
}

Do you want to display image in the first row? If so, I think you can change the line for judge whether it is the first row from
if ( i==0 )
to
if (indexPath.row == 0 && indexPath.section == 0)
I think the i must be a class member. The UITableView only creates limited number of UITableViewCell. Commonly, the number equals to to the number of displaying rows. For example, if the screen can only display 10 rows, UITableView creates 10 cell. After scrolling, It reuses the created cells by calling dequeueReusableCellWithIdentifier:forIndexPath, this makes the rows which are out of screen release their cells. When scroll back, each "new" entered item needs a cell. The UITableView will call tableView:cellForRowAtIndexPath for new cell. Therefore as your scenario, only the first time, the image row can be displayed, because after the first time, the i is non-zero even scroll back.

I believe "i" was used as an instance variable in your code. Instead you should rely to the indexPath variable passed as an argument of the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
Your very first item in your table view is identified by:
indexPath.row == 0 and indexPath.section == 0
.row is a row index within a given section .section
Make sure you have correctly implemented those two delegate methods also to correctly identify respectively your number of rows within a section and your number of sections:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

Related

Adding background for TableView sections iOS

I have a section with dynamic multiple rows and I need to separate all the section with the background as shown in the image below.
Specifically those border lines for all the section. Pease let me know how can I make it possible.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
return ProductArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *arr = [ProductArray objectAtIndex:section];
return arr.count;
}
Please refer to this
.
I tried adding header and footer, But I am not understanding how to add that rectangle box image for the entire section.
Put View in your cell after make outlet of that view. And use to cellForRowAtIndexPath this method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.viewBackGround.backgroundColor = [UIColor redColor];
return cell;
}
For above requirement, I would like to suggest you the below approach.
create only one section with multiple rows.
Each row of UITableView will have UITableViewCell
Inside UITableViewCell create content view for which we are gonna add the border
Each row of UITableViewCell will have another UITableView(inside content view) whose methods are handled by UITableViewCell cells
Change UITableView (inside) height based on number of rows.
provide height of UITableViewCell based on the number of rows + orderID Header.

iOS get current and previous selected UITableViewCells from cellForRowAtIndexPath method

So basically what I am doing now is expanding my cells by selecting on them and using heightForRowAtIndexPath to change their height and if I select on it again or select a different cell those cells will expand or go back to their normal size.
However, upon the cell expanding I have some extra data to show in the expanded section, change the background color of the cell and set some other properties that I have defined in my tableviewcell subclass. So as an example when the cell is in its normal height the background will be light green. When its expanded it needs to be white. I set my tableviewcell subclass property (a BOOL) so that when its time to loop through the cells again (cellforRowatindexpath) i can update these properties as needed. Unfortunately, I haven't been able to find a way to get the current cell thats been selected in cellForRowAtIndexPath.
Here is the relevant code below. Keep in mind that I want to keep track of the current cell selected and the previous cell (if different from the current one) so that i can update both cells properties. Only one cell can be expanded at a time. When the current cell is selected and expanded the previous one(if applicable) will contract back to normal height. My configureCell method is just there to assign the properties based its BOOL property.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:myIdentifier forIndexPath:indexPath];
[cell configureCell:self.item[indexPath.row] isCollapsed:cell.isCollapsed];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell *currentCell;
MyCustomCell *previousCell;
self.currentSelectedIndex = indexPath;
//assign previous and current if previous is nil
if(!self.previousSelectedIndex){
self.previousSelectedIndex = self.currentSelectedIndex;
currentCell = [tableView cellForRowAtIndexPath:self.currentSelectedIndex];
currentCell.isCollapsed = NO;
}
//we have tapped the same cell as before
else if(self.previousSelectedIndex == self.currentSelectedIndex){
previousCell = [tableView cellForRowAtIndexPath:self.previousSelectedIndex];
previousCell.isCollapsed = YES;
self.previousSelectedIndex = self.currentSelectedIndex = nil;
}
//if they aren't equal, then collapse the previous selected cell
//and expand the current selected cell
else{
previousCell = [tableView cellForRowAtIndexPath:self.previousSelectedIndex];
previousCell.isCollapsed = YES;
currentCell = [tableView cellForRowAtIndexPath:self.currentSelectedIndex];
currentCell.isCollapsed = NO;
self.previousSelectedIndex = self.currentSelectedIndex;
}
[tableView beginUpdates];
if(self.currentSelectedIndex){
[tableView reloadRowsAtIndexPaths:#[self.currentSelectedIndex, self.previousSelectedIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
}
[tableView endUpdates];
}
So, obviously my current and previous cell will be trashed once we leave this method since they are local but I am struggling with how to:
a. reload the cells which would cause cellForRowAtIndexPath to execute again(this works when trying to use reloadRows - but maybe I'm doing that wrong)
b.once cellForRowAtIndex starts going through the cells how to capture the currentCell and the previousCell so that i can update its content as I described above. [dequeueReusableCellWithIdentifier:myIdentifier] just gets a new cell which I do not want obviously.
The cells expand and contract fine so thats not an issue.

Drawing string on uiview over contentview of tableviewcell draws same content again and again

Because using three labels over UITableViewCell slowed down tableview scroll performance I tried drawing directly on UIView that I dragged over the prototype cell. While this significantly improved scroll performance, this got me into another problem.
Actually I am drawing the contents of a feed. After six or seven unique rows (for 20 records), rows are duplicate. They show the same content starting from top of tableview. However When I tap on those repeated cells the content changes to what it should have been.
After researching I found six or seven is the number of rows actually visible on the screen. So this should have been display update error but I am not sure should I do to fix this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"newsCell";
NewsCell *cell = (NewsCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (indexPath.row < feeds.count) {
dict = [feeds objectAtIndex:indexPath.row];
[cell setNewsHeading:[dict objectForKey:#"title"] pubDate:[dict objectForKey:#"pubDate"] newsExcerpt:[dict objectForKey:#"attributedDescription"]];
}
dict = nil;
return cell;
}
-(void)setNewsHeading:(NSString *)newsHeading pubDate:(NSString *)pubDate newsExcerpt:(NSAttributedString *)newsExcerpt
{
self.newsView.newsHeading = newsHeading;
self.newsView.pubDate = pubDate;
self.newsView.newsExcerpt = newsExcerpt;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [feeds count];
}
That sounds like it could be a caching issue - have you tried overriding the prepareForReuse method in your cell subclass to reset the cell contents back to the default values?

uitableview hiding 2 cells from scroll

made a table view, and it does not make sense at all but my table view is hiding some cells.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 25;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
}
object= [self.results objectAtIndex:indexPath.row];
cell.textLabel.text=[object valueForKey:#"hLabel"];
return cell;
}
It does render 25 cells but I am only able to view up to 23. 2 cells are hidden below. Though if I scroll further I can see them but if I leave the scroll the view comes back, 23rd being the last cell. Hence user is not able to select either 24 or 25.
Even if I reduce the cell count, lets say to 23, still the tableview is hiding 2 cells and I am not able to access them as the scroll ends at 2 cells prior.
I think your tableview height is more than screen height.
Decrease the height of the tableview (make it fit to view bound) and it will display all the cell.
And also check that this autoresizing constraint is setted in in the zib/storyboard for tableview.
I faced a similar issue and i don't know how but when i unchecked Autolayout, the issue gets resolved. Try turning off Autolayout. i hope it helps you too.

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