Images only update after scrolling UITableView - uitableview

I have a horizontal scrolling table view. Each cell takes the whole screen to show full pictures. I'm doing lazy loading of the pictures. The problem I'm having is that when the pictures finish downloading, the UIImageview.image from the cell is not updated automatically. I need to scroll to another cell and back for it to show.
Here is the method called when the picture is finished downloading:
- (void)imageDownloaderDidFinish:(PictureDownloadOperation *)downloader {
NSLog(#"image download finished");
NSIndexPath *indexPath = downloader.indexPathInTableView;
PictureRecord *theRecord = downloader.photoRecord;
[self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.pendingOperations.downloadsInProgress removeObjectForKey:indexPath];
}
This is the cellforwoeatindexpath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"HorizontalCell";
HorizontalTableCell *cell = [self.myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[HorizontalTableCell alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width)];
}
cell.contentView.transform = CGAffineTransformMakeRotation(-M_PI/-2);
PictureRecord *aRecord = [self.photos objectAtIndex:indexPath.section];
[cell.indicator startAnimating];
if (aRecord.hasImage) {
[cell.indicator stopAnimating];
[cell.pic setImage:aRecord.image];
[cell setNeedsDisplay];
cell.username.text = aRecord.username;
}
else if (aRecord.isFailed) {
[cell.indicator stopAnimating];
cell.pic.image = [UIImage imageNamed:#"first.png"];
}
else {
[cell.indicator startAnimating];
if (!myTableView.dragging && !myTableView.decelerating) {
[self startOperationsForPhotoRecord:aRecord atIndexPath:indexPath];
}
}
return cell;
}
Thanks
UPDATE:
One more information about this problem. After troubleshooting I found that the problem is with reloadRowsAtIndexPaths. It does not call cellForRowAtIndexPath for the image to load. However I'm still not sure it does not call cellForRowAtIndexPath. I have also tried [tableview reloadData] and no luck.
FIXED IT:
The problem was fixed by adding another tableview inside this existing table view. The way I had before was a UITableView inside a UIView. I modified it so I had one UITableView with one cell. Created a custom cell and added another table in that cell so I could scroll it horizontally and added another custom cell for the horizontal tableview with the imageview. That did the trick.

Related

UITableView ScrollToRowAtIndexPath method not working

I have a UITableView as a subview of a View. In the ViewController when the table is being populated I'm highlighting one of the rows and keeping a record of the indexPath for that row. I'm doing this in the cellforRowAtIndexPath method.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
favouriteCellView *cell = [tableView dequeueReusableCellWithIdentifier:#"reuseID"];
QBCOCustomObject *favouriteObject = [_favouriteResults objectAtIndex:indexPath.row];
if (favouriteObject.userID == self.user.ID) {
UIView *bgColor = [[UIView alloc] init];
bgColor.backgroundColor = [UIColor colorWithRed:173.0f/255.0f green:146.0f/255.0f blue:237.0f/255.0f alpha:.5];
self.highlightedRowIndex = indexPath;
[cell setSelectedBackgroundView:bgColor];
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}
return cell;
}
Then in the viewDidAppear Method I want the table to scroll to the highlighted cell.
-(void)viewDidAppear:(BOOL)animated{
[self.tableView scrollToRowAtIndexPath:self.highlightedRowIndex atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
However I've double checked that the method is being hit with a breakpoint, but unfortunately the highlighted row is not being scrolled to the top of the table as I'd expected. AM I misunderstanding the scrollToRowAtIndexPath method? Or have I left something out of the above code.
If the row is not on screen, it will not yet be loaded by the table view. This means your cellForRowAtIndexPath for that cell will not yet be called. You'll want to choose this index in a way that does not depend on the view loading. Try this before you call scrollToRowAtIndexPath:
NSInteger row = 0;
for (QBCOCustomObject *object in _favouriteResults) {
if (object.userID == self.user.ID) break;
row++;
}
self.highlightedRowIndex = [NSIndexPath indexPathForRow:row inSection:0];

Show/Hide custom class elements when uitableviewcell is selcted

I am new to iOS development. I have doubt related to UITableViewCell height.
I am using one tableview, I have taken prototype cell in storyboard. The cell height I have given is 75. But what I need is when I select cell height will be increase and show 1 button (which is in black color in the image). The button is declared in UITableViewCell's custom class. Below of that image I have one label. If button is showing I need to place the label at the bottom of button or else in the place of button I need to show that label.
Thanks in advance.......
You can use [tableView beginUpdates] and [tableView endUpdates];
for Ex:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self hideControlMethodsTable];//Declare method to hide when button tableview loads initially
[tableList beginUpdates];
[tableList deselectRowAtIndexPath:indexPath animated:YES];
CellRes = (ReservationTableViewCell*)
[tableList cellForRowAtIndexPath:indexPath];
if (cellSelectedFirstTime == true) {
self.selectedRow = indexPath.row;
[self showControlsMethodsTable];
cellSelectedFirstTime = false;
}
else{
if(self.selectedRow == indexPath.row){
self.selectedRow = -1;
[self hideControlMethodsTable];
}
else{
self.selectedRow = indexPath.row;
[self showControlsMethodsTable];
}
}
[tableList endUpdates];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if(openForFirstCell == true){
if (cellSelectedFirstTime==true) {
CellRes = [UIColor lightGrayColor];
return 180.;
}
return 60;
}
}
Hope this helps you.

Tableview reloadData and getting CGRect of new cell

I have a UITableView with cards. Every time I want to add a new card after pushing the draw button I want it to be moved from the center of the view to the location in the table it should be placed with some basic animation. I have managed to get the destination of the new drawn card with this code:
cellRectInTableDrawnCard = [[self playerCardsTable] rectForRowAtIndexPath:drawnCardIndexPath];
cellInSuperviewDrawnCard = [[self playerCardsTable] convertRect:cellRectInTableDrawnCard toView:[[self playerCardsTable] superview]];
However, to determine the cellRectInTableDrawnCard I need to reload the playerCardsTable with reloadData but this shows the drawn card already. It is just a fraction of a second because I place the new card in the table with an animation which fires just after the reloadData. Doing a reload after the animation is not an option, because I don't have the drawnCardIndexPath then.
Is there a way I can get the rect without reloading the tableview? Or else, is there a way I can hide the new cell after reloadData and show it after the animation is done?
Thanks!
You probably want to insert the row and populate it individually and not do a complete table reload.
The code snippet shows a button that uses insertRowsAtIndexPaths:indexPathArray to add a new row which gives you the cell rect to do you animation stuff.
When you're done with animation just use reloadRowsAtIndexPaths to populate the cell value (show you're card I'd guess).
Use a bool to decide in cellForRowAtIndexPath when you should display the new card (basically after you call reloadRowsAtIndexPaths).
- (IBAction)butAddCardToHandAction:(id)sender {
// Add a blank record to the array
NSString *strCard = #"New Card";
_showCard = NO;
[_arrayHandCards addObject:strCard];
// create the index path where you want to add the card
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(_arrayHandCards.count - 1) inSection:0];
NSArray *indexPathArray = [NSArray arrayWithObjects:indexPath,nil];
// Update the table
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
// Ok - you got a blank record in the table, get the cell rect.
CGRect cellRectInTableDrawnCard = [[self tableView] rectForRowAtIndexPath:indexPath];
NSLog(#"My new rect has y position : %f",cellRectInTableDrawnCard.origin.y);
//Do the animation you need to do and when finished populate the selected cell
_showCard = YES;
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
Code to control whats displayed in cell:
- (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:CellIdentifier];
}
// Set up the cell and use boolean to decide what to show
NSString *strToDisplayInCell;
if (!_showCard)
{
strToDisplayInCell = #"";
}
else
{
NSString *strToDisplayInCell = [_arrayHandCards objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:15];
cell.textLabel.text = strToDisplayInCell;
}
return cell;
}

setContentOffset not scrolling my UITableView

I am trying to scroll my UITableViewCell up one UITableViewCell position when the selected cell reaches the last position in the UITableView
I have the logic correct for identifying the last visible UItableViewCell of the UITableView. However the code to make the UITableView scroll up one position is not working. This is the code I have written.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cellSelectedBool = YES;
cell = (CustomFinishingCell *)[tableView cellForRowAtIndexPath:indexPath]; // error
[cell.widthTexField becomeFirstResponder];
// Gets an array of current visible cells in UITableView
NSArray *visibleCells = [tableView visibleCells];
NSLog(#"%#", visibleCells);
// get indexpath of last cell
UITableViewCell *lastCell = [visibleCells lastObject];
NSIndexPath *lastCellIndex = [finishingTableView indexPathForCell:lastCell];
// perform scroll when last visible cell is selected
if (indexPath.row == lastCellIndex.row) {
NSLog(#"BIGGER");
int cellHeight = 44;
[UIView animateWithDuration:.25 animations:^{
[finishingTableView setContentOffset:CGPointMake(finishingTableView.contentOffset.x,finishingTableView.contentOffset.y + cellHeight) animated:YES];
}];
}
you should use:
NSIndexPath *rowToSelect; // assume this exists and is set properly
UITableView *myTableView; // assume this exists
[myTableView selectRowAtIndexPath:rowToSelect animated:YES scrollPosition:UITableViewScrollPositionNone];
[myTableView scrollToRowAtIndexPath:rowToSelect atScrollPosition:UITableViewScrollPositionNone animated:YES];
if (indexPath.row == lastCellIndex.row) {
[finishingTableView scrollToRowAtIndexPath:indexPathatScrollPosition:
UITableViewScrollPositionNone animated:YES];
}

Resizing height of UITableViewCell doesn't work correctly neither with [tableview reloadData] nor with [tableview reloadRowsAtIndexPaths:]

This may be a long question in order I'll be able to explain all the problem I've encountered.
So, I want to implement such UI functionality:
So I have a UITableView which is implemented in one file and it's cells which is implemented in other file TableViewCell.m
And I need after clicking on button read more to expand UILabel with text mesage as on the second screen and after clicking on close message button to restore UILabel and consequently resize TableView cell (this is one button i only change images of it). So in order to resize UILabel I use [UILabel sizeToFit] and change label.numberOfLines from 3 to 0 (iOS 6 feature as far as I know).And here code of creating cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
CPNTalkCell *cell = (CPNTalkCell *)[tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
NSString *modelId = [[models objectAtIndex:indexPath.row] valueForKey:#"modelId"];
NSDictionary *model = [[models objectAtIndex:indexPath.row] valueForKey:#"model"];
return [self setupCell:cell forModel:model withId:modelId];
}
In setupCell method I do additional adjustments and in CPNTalkCell the cell is described vi IB.
And here the code of button ReadMore event handler where I try to resize cell and label:
-(void)ResizeLabel:(id)sender
{
UIView* sender_button = (UIView*)sender;
UIButton* _resizingSenderButton = (UIButton*)sender;
CGRect _button_before = _resizingSenderButton.frame;
NSIndexPath* indexPath = [listView indexPathForCell:(UITableViewCell*)[[ sender_button superview]superview ]]; //In such an ugly way may be i
//access NSIndexpath of the current cell from
// which button was clicked
CPNTalkCell *cell = (CPNTalkCell*)[listView cellForRowAtIndexPath:indexPath];
if (cell.messageLabel.numberOfLines==3) {
[self.listView beginUpdates];
cell.messageLabel.numberOfLines=0;
[cell.messageLabel sizeToFit];
_button_before.origin.y = cell.messageLabel.frame.origin.y+ cell.messageLabel.frame.size.height+7;
_resizingSenderButton.frame=_button_before;
[_resizingSenderButton setBackgroundImage:[UIImage imageNamed:#"readmore2.png" ] forState:UIControlStateNormal];
[cell sizeToFit];
// [self.listView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[self.listView reloadData];
[self.listView endUpdates];
}
else
{
cell.messageLabel.numberOfLines = 3;
[self.listView beginUpdates];
[cell.messageLabel sizeToFit];
CGRect _button_after = _resizingSenderButton.frame;
_button_after.origin.y = cell.messageLabel.frame.origin.y+ cell.messageLabel.frame.size.height+7;
_resizingSenderButton.frame=_button_after;
[_resizingSenderButton setBackgroundImage:[UIImage imageNamed:#"readmore1.png" ] forState:UIControlStateNormal];
[cell sizeToFit];
[self.listView reloadData];
//[self.listView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[self.listView endUpdates];
}
}
So this code work and after clicking cells resize to fit the text and it's length but works strange - sometimes buttons disappear or appear on the text after scrolling the list buttons also may disappear or even text.I use reloadData when I change cell - i know it's not optimal, but as you see I've commented code of reloading of one cell because it works even more strange or not from the first clicking.
I also overload heightForRowatIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *modelId = [[models objectAtIndex:indexPath.row] valueForKey:#"modelId"];
NSDictionary *model = [[models objectAtIndex:indexPath.row] valueForKey:#"model"];
CPNTalkCell *cell = [_cells objectForKey:modelId];
if (cell == nil) {
cell = [self setupCell:nil forModel:model withId:modelId];
}
return cell.rowHeight;
}
But in it i describe initial cell parameters before clicking on a button via calling of rowHeight described in TalkCell file!
I know it's a long question and I sometimes explain not all clear but I think iOS experts will be able to understand my problem and propose solution of this problem. I really need a help because I try to solve this problem not for a one day.Great thanks in advance!
You need to overload heightForRowAtIndexPath to return the appropriate value based on the expanded cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *mode
lId = [[models objectAtIndex:indexPath.row] valueForKey:#"modelId"];
NSDictionary *model = [[models objectAtIndex:indexPath.row] valueForKey:#"model"];
CPNTalkCell *cell = [_cells objectForKey:modelId];
if (cell == nil) {
cell = [self setupCell:nil forModel:model withId:modelId];
}
if ( indexPath == expandedIndexPath )//save the expanded cell's index path somewhere
{
return expandedCellHeight;
}
return cell.rowHeight;
}

Resources