I have a table view with a prototype cell designed in ViewController scene of storyboard.
Now my objective is when the app will start and the view will be loaded then the data in tableview should not come at once rather it will come one by one with animation.
Here is the code how I am doing my animation:-
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (![shownIndexes containsObject:indexPath]) {
[shownIndexes addObject:indexPath];
[UIView animateWithDuration:2.0f delay:0.0f usingSpringWithDamping:0.5f initialSpringVelocity:1.0f options:UIViewAnimationOptionAllowAnimatedContent animations:^{
vw.frame = frame;
} completion:^(BOOL finished) {
}];
}
Other methods:-
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
return 1; //count of section
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20; //count number of row from counting array hear cataGorry is An Array
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 120;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"CellA";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
The following code is animating the first 5 cells which are displaying in tableview initially at once , but after that when I am scrolling it is happening one by one.
So major issue is
How to display the rows or cells in UITableview one by one with animation not at once?
Any info or help will be appreciated.
Thanks.
Tell the table first that in only has one row, in numberOfRows…. After a delay, return 2 instead of 1. And so on.
Related
I am making a chat page, where I scroll on top, I reload the previous message from API. After getting response, reload the table, and the table moves to first cell. But I want it to be stay where it was during loading the messages. Following are the solutions that I tried:
Solution 1:
Declared this:
NSMutableDictionary *cellHeightsDictionary;
Added this in viewDidLoad:
self.chatTableView.rowHeight = UITableViewAutomaticDimension;
cellHeightsDictionary = #{}.mutableCopy;
Then added the below mentioned methods:
// save height
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[cellHeightsDictionary setObject:#(cell.frame.size.height) forKey:indexPath];
}
// give exact height value
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];
if (height) return height.doubleValue;
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
And here reloading my tableview:
- (void)reloadAllMessagesHere {
[UIView performWithoutAnimation:^{
[self.chatTableView reloadData];
[self.chatTableView beginUpdates];
[self.chatTableView endUpdates];
}];
}
But still the same issue is happening.
Then I thought I should use the bottom contentOffset of the page. So, I used this method to reload the data:
Solution 2:
Removed all above codes and used these methods:
For TableView Height:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
and tableview reload
- (void)reloadWithoutMoving {
CGPoint contentOffsetVal = CGPointMake(0, self.chatTableView.contentSize.height - self.chatTableView.bounds.size.height);
[self.chatTableView reloadData];
[self.chatTableView layoutIfNeeded];
[self.chatTableView setContentOffset:contentOffsetVal];
}
BUT NO LUCK!!
Here check the two images shown below:
Image 1: Here I am loading the tableview.
Image 2: Here I got the response and the data shown in Image 1 move to bottom automatically
How can I fix this?
[P.S. Please don't mark this as duplicate as I have tried previous the solutions but couldn't fix it.]
I am having such an issue right now. I have a UIViewController that has a UITableView, I have it set up so that when the UITableView is in editing mode it returns 3 - circles with the check marks. My UITableView has custom cells with in image and text. When I put the UITableView in edit mode, I am trying to pass an array of the images from multiple selected rows to a second view controller to use those images in a collection view, but I am just having a hard time passing the array of images. Any suggestions would be appreciated.
here is my TableView code:
-(void)didTapEditBUtton:(id)sender{
if ([self.ribbonTableView isEditing]) {
viewButton.hidden = YES;
headerLabel.hidden = NO;
[ribbonTableView setEditing:NO animated:YES];
[selectButton setTitle:#"select"];
}
else {
[selectButton setTitle:#"Cancel"];
// Turn on edit mode
headerLabel.hidden = YES;
viewButton.hidden = NO;
[ribbonTableView setEditing:YES animated:YES];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection (NSInteger)section{
return [ribbonsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
RibbonCustomCell *cell = (RibbonCustomCell *) [ribbonTableView dequeueReusableCellWithIdentifier:#"RibbonDetail"];
if (cell != nil)
{
RibbonsInfo *ribbonsInfo = [ribbonsArray objectAtIndex:indexPath.row];
//NSLog(#"%#", ribbonsInfo);
//Ribbon Image
cell.ribbonImageView.image = ribbonsInfo.ribbonImage;
cell.ribbonLabel.text = ribbonsInfo.ribbonName;
}
return cell;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return 3;
}
-(void)tableView:(UITableView *)tableView didSelectRowsAtIndexPath:(NSIndexPath *)indexPath{
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
}
You should take the property of NSMutableArray...
#property (nonatomic, strong) NSMutableArray *selectedImages;
- (void)viewDidLoad {
[super viewDidLoad];
self.selectedImages = [NSMutableArray new];
}
now when you select or deselect the cell the delegates are called -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",indexPath);
RibbonsInfo *ribbonsInfo = [ribbonsArray objectAtIndex:indexPath.row];
[self.selectedImages addObject:ribbonsInfo.ribbonImage];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",indexPath);
if (self.selectedImages.count > 0) {
[self.selectedImages removeObjectAtIndex:indexPath.row];
}
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return 3;
}
Now the selectedImages array contains the selected cell images and you can pass this array.
Hope it will solve your problem.
I have a custom UITableViewCell, and I it expands on selection. What I want to do is make the cells height go back to normal (44), if the cell that was selected was reselected. Here is my code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath isEqual:self.selectedCell] && ![[tableView indexPathForSelectedRow] isEqual:indexPath]) {
return 100;
}
return 44;
}
The code works fine, but it seems to be ignoring the 2nd term in the if statement. Apparently I'm doing it wrong. Is there a way to fix it?
I don't know why you compare cell with indexPath.
[indexPath isEqual:self.selectedCell]
If you just want expand selected cell.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[tableView indexPathForSelectedRow] isEqual:indexPath])
{
return 100;
}
return 44;
}
UITableViewDelegate has deselect method
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
You need reload cell in this delegate
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
You need to store that particular index path in array to indicate that it is expanded Lets say you had selected 5 row that store that row number in an array, and reload that row after selecting it
Here is small code snippet that can help you to achieve this
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([_arrExpandedRows containsObject:indexPath.row]){
[_arrExpandedRows removeObject:indexPath.row];
}else{
// [_arrExpandedRows removeAllObjects]; // IF you only want to make it work for single row
[_arrExpandedRows addObject:indexPath.row];
}
[tableView reloadData];
}
And in your heightForRowAtIndexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([_arrExpandedRows containsObject:indexPath.row]){
{
return 100;
}
return 44;
}
So what will it do if your array contains object of expanded row it will make reduce its row height and back to 44 and if not it will make it back to 100.
And above code will also work for multiple rows to expand and collapse at same time.
I think what you want is unselect cell when tap on a selected cell.
Store selectedIndexPath and compare in delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([selectedIndexPath isEqual:indexPath])
{
[tableView deselectRowAtIndexPath:indexPath animated:1];
}
else
{
selectedIndexPath = indexPath;
}
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
You can do something like this:
#interface ViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView* tableView;
#property (nonatomic, strong) NSMutableArray* selectedIndexPaths;
#end
<...>
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:CELL_ID];
cell.textLabel.text = [NSString stringWithFormat:#"%i", (int)indexPath.row];
return cell;
}
#pragma mark UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height = 44.0;
if ([_selectedIndexPaths containsObject:indexPath])
{
height = 100;
}
return height;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{//store or remove selected indexPaths
if ([_selectedIndexPaths containsObject:indexPath])
{
[_selectedIndexPaths removeObject:indexPath];
}
else
{
[_selectedIndexPaths addObject:indexPath];
}
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
Good day. How to change the count and label of the cells by clicking using reloadData?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSLog(#"test");
[tableView numberOfRowsInSection:3];
[tableView reloadData];
}
If you want to change the number of rows in section you should modify your dataSource from your delegate method. You shouldn't call any of dataSource methods.
Below you can find one of the simplest way to modify data of yoru table view:
// In your category or header file:
#property (nonatomic) NSInteger numberOfRows;
- (void)viewDidLoad {
self.numberOfRows = 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) {
self.numberOfRows = 3;
[self.tableView reloadData];
}
//Method in your table view datasrouce
- (void)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.numberOfRows;
}
In the code reacting to the selection of a cell, update the datasource of your UiTableView
and after that reload the table.
So I've been working on a UITableView and I can't hit the statusbar to scroll up, however it seems like it's trying to scroll up, but it doesn't.
Here you can see a video of it (Decided to use mp4 instead of GIF since it was so laggy)
http://i.gyazo.com/4c7be7437116e420411ac879b6d0d784.mp4
If you look at the video you can see that you indicator on the right side tries to scroll up but doesn't ? Has anyone experienced something similar ?
I'm also using ECSlidingViewController
My current code
Called upon -viewDidLoad
-(void)setTableViewStuff {
[self.myTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[self.myTableView registerNib:[UINib nibWithNibName:#"YouTubeTableCell" bundle:nil] forCellReuseIdentifier:CellIdentifier];
self.myScrollView.scrollsToTop = NO;
self.myTableView.scrollsToTop = YES;
}
Table View Code
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 256;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return myVideoTitles.count;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
YouTubeTableCell *cell = (YouTubeTableCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (indexPath.section == 0) {
NSString* thumbnailURL = myVideoThumbnails[indexPath.row];
[cell.myThumbnail setImageWithURL:[NSURL URLWithString:[thumbnailURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:nil];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return NO;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
EDIT:
Found a solution to this!!, Apperiantely if you're using ECSlidingViewController you must have yourtableview.scrollstotop = NO; inside the "drawer"
Found a solution to this!!, Apperiantely if you're using ECSlidingViewController you must have yourtableview.scrollstotop = NO; inside the "drawer"