Insert UITableViewCell With Animation and Scroll to it - ios

My requirement is simple , i just need to add a TableCell with rightRowAnimation and scroll to it. It happens as long as i am with within tableView height , as i cross the height of tableView to add cell further , it adds cell but displays no animation when scrolling to it.
Attached is a simple project with a UITableView for reference , Appreciate your help !!
Sample Project with a simple UItableView and Add Button
Code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell1"];
BOOL myBool = indexPath.row%2 == 0;
if(myBool){
cell.backgroundColor = [UIColor redColor];
}else{
cell.backgroundColor = [UIColor whiteColor];
}
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
return cell;
}
-(IBAction)addTapped:(id)sender {
[self.dataArray addObject:#"New Object"];
// [_tableView beginUpdates];
[_tableView insertRowsAtIndexPaths:#[[NSIndexPath indexPathForRow:self.dataArray.count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationRight];
// [_tableView endUpdates];
[_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.dataArray.count-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

Use bellow method for the animation.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.alpha = 0;
cell.layer.transform = CATransform3DMakeScale(0.5, 0.5, 0.5);
[UIView animateWithDuration:0.7 animations:^{
cell.alpha = 1;
cell.layer.transform = CATransform3DScale(CATransform3DIdentity, 1, 1, 1);
}];
}
change what ever your requirements

you can try this to animate row put in table.
-(void)viewWillAppear:(BOOL)animated
{
dispatch_async(dispatch_get_main_queue(), ^{
[UIView transitionWithView:yourtablename
duration:5.1f
options:UIViewAnimationOptionTransitionFlipFromTop
animations:^(void) {
[yourtablename reloadData];
} completion:NULL];
});
}
also you can change animation style.

Related

IOS: Force tableView cell to animate change on tap

I am trying to perform an animation on a cell when the accessory view is tapped. The tapped delegate method is firing and I can get the row to do something--change label, but it is ignoring the animation (or in another case--not even making the change.) How can I get the animation to work properly?
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
MyCustomCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:5.0
delay: 5.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
//NEXT TWO LINES HAVE NO EFFECT ON CELL SO COMMENTED OUT
//cell.nameLabel.text = #"Thank you. FIRST ANIMATE TRY";
// [self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//NEXT THREE LINES CHANGE TEXT BUT WITHOUT ANIMATION
[self.tableView beginUpdates];
cell.nameLabel.text = #"Thank you. Second try!";
[self.tableView endUpdates];
}
completion:^(BOOL finished){
NSLog(#"animation finished");
}];
}
BTW I also tried explicitly dispatching this in the main queue but it had no effect. It should already be in main queue.
First of all, you don't need to call beginUpdates or endUpdates. Second, you can't animate the change of a label's text value.
What you need to is have a label on the cell and initialize the alpha property to 0.0. When accessoryButtonTappedForRowWithIndexPath is called set the alpha property to 1.0 inside of your animation block.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
AwesomeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.thankYouLabel.text = #"Thank you";
cell.thankYouLabel.alpha = 0.0;
return cell;
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
AwesomeCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:1.0 animations:^{
cell.thankYouLabel.alpha = 1.0;
}];
}

How top expand collapse custom cell tableview and expanding the cell must be dynamic height in iOS objective c

How top expand collapse custom cell tableview and expanding the cell must be dynamic height in iOS objective c?
viewcontroller having custom tableview cells when click on the cell,cell must be expand/collapse having one view and display data in that view and height must be dynamic
You'll have to maintain a state (expanded/not expanded) for the custom table view cell. Every time it's tapped you make the necessary changes in the UI and toggle the state. You can then call
reloadData()
or
-(void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
withRowAnimation:(UITableViewRowAnimation)animation;
You can also calculate and set the new height of the cell and the reload function will take care of the animation.
You used tableview then easy manage expand and collapse custom cell tableview and expanding with animation.
Follow code for expand and collapse.
.h File
BOOL currentlyExpanded;
NSMutableIndexSet *expandedSections;
.m File
- (void)viewDidLoad
{
if (!expandedSections)
{
expandedSections = [[NSMutableIndexSet alloc] init];
}
}
Use Tableview Delegate and Datasource method..
#pragma mark - Tableview Delegate -
- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
{
return YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([self tableView:tableView canCollapseSection:section])
{
if ([expandedSections containsIndex:section])
return 6; //return your array count..
else
return 1;
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]
;
}
if ([self tableView:tableView canCollapseSection:indexPath.section])
{
//Display your dynamic cell contain..
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self tableView:tableView canCollapseSection:indexPath.section])
{
NSInteger section = indexPath.section;
currentlyExpanded = [expandedSections containsIndex:section];
NSInteger rows;
if (currentlyExpanded)
{
rows = [self tableView:tableView numberOfRowsInSection:section];
[expandedSections removeIndex:section];
}
else
{
[expandedSections addIndex:section];
rows = [self tableView:tableView numberOfRowsInSection:section];
}
// Animation when cell expand and collapse
if(currentlyExpanded)
{
[tableView deleteRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationTop];
CGFloat startRadians, endRadians;
startRadians = M_PI/2;
endRadians = 0.0f;
btnArrow.layer.affineTransform = CGAffineTransformMakeRotation(startRadians);
[UIView animateWithDuration:0.3f animations:^{
btnArrow.layer.affineTransform = CGAffineTransformMakeRotation(endRadians);
}completion:^(BOOL finished){
}];
}
else
{
[tableView insertRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationTop];
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
[btnArrow setTransform:CGAffineTransformRotate(btnArrow.transform, M_PI/2 )];
}completion:^(BOOL finished){
}];
}
}
}

Load UIWebView in UITableViewCell and Make UITabViewCell's height as per the content of UIWebview

I am working on a project, where I have a UITableViewCell containing UIImageView, UILable and UIWebView.
I need to open a webview (with added HTML string in it) on didselectrowatIndexpathmethod and cell height should be increase to the content size of UIWebView. I have tried following code. But this is not working as per the expectation. Kindly advice.
#pragma mark - Table view data source
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [faqContentArray count];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
FAQCell *cell = (FAQCell*)[tableView cellForRowAtIndexPath:indexPath];
[cell.faqContentWebView loadHTMLString:[[faqContentArray objectAtIndex:indexPath.row] objectForKey:#"content"] baseURL:nil];
NSString *wrappedText = [[faqContentArray objectAtIndex:indexPath.row] objectForKey:#"content"];
cell.faqContentWebView.frame=CGRectMake(8.0f, 43.0f, 304.0f, [self minHeightForText:wrappedText]);
[self rotateIconToExpanded:cell.faqImage];
[self.faqTableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
}
//-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
// FAQCell *cell = (FAQCell*)[tableView cellForRowAtIndexPath:indexPath];
//
// [cell.faqContentWebView loadHTMLString:#"" baseURL:nil];
// cell.faqContentWebView.frame=CGRectMake(8.0f, 43.0f, 304.0f, 5);
// [self rotateIconToCollapsed:cell.faqImage];
// [self.faqTableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationTop];
//}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FAQCell *cell = (FAQCell*)[tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (!cell) {
[tableView registerNib:[UINib nibWithNibName:#"FAQCell" bundle:nil] forCellReuseIdentifier:#"MyCell"];
cell = (FAQCell*)[tableView dequeueReusableCellWithIdentifier:#"MyCell"];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
cell.faqContentWebView.delegate=self;
cell.faqContentWebView.layer.cornerRadius = 0;
cell.faqContentWebView.userInteractionEnabled = NO;
cell.faqContentWebView.multipleTouchEnabled = YES;
cell.faqContentWebView.clipsToBounds = YES;
cell.faqContentWebView.scalesPageToFit = NO;
cell.faqContentWebView.scrollView.scrollEnabled = NO;
cell.faqContentWebView.scrollView.bounces = NO;
cell.faqContentWebView.autoresizingMask=UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
cell.faqTitleLbl.text=[[faqContentArray objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.faqImage.image=[UIImage imageNamed:#"downarow.png"];
return cell;
}
- (void)rotateIconToExpanded:(UIImageView *)iconImage {
[UIView beginAnimations:#"rotateDisclosure" context:nil];
[UIView setAnimationDuration:0.2];
iconImage.transform = CGAffineTransformMakeRotation(M_PI * 2.5);
[UIView commitAnimations];
}
- (void)rotateIconToCollapsed:(UIImageView *)iconImage {
[UIView beginAnimations:#"rotateDisclosure" context:nil];
[UIView setAnimationDuration:0.2];
iconImage.transform = CGAffineTransformMakeRotation(M_PI * 2);
[UIView commitAnimations];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
id celll = [self tableView:tableView cellForRowAtIndexPath:indexPath];
FAQCell *cell=(FAQCell *)celll;
[cell setNeedsLayout];
[cell layoutIfNeeded];
NSLog(#"height------>%f",[cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height);
return [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
}
You will need to calculate (and possibly monitor) the size of your content in the UIWebView. One way is through UIWebView's UIScrollView:
CGFloat webViewContentHeight = myWebView.scrollView.contentSize.height;
another is:
CGFloat webViewContentHeight = [myWebView stringForEvaluatingJavaScript:#"document.body.offsetHeight"].floatValue;
When you retrieve that height is important, you will want it once the content of the UIWebView has finished loading (once it has you can invalidate/update the constraints of your UITableViewCell, for example).

How to simultaneously animate a cell and table change in iOS?

I am trying to simultaneously animate a custom UITableViewCell and the UITableView that contains it.
When clicked, the subviews of the UITableViewCell slightly re-arrange such that the height of the cell increases. I want the re-arrangement within the cell to happen concurrently with the resizing of the UITableView's slot for that cell, so that it doesn't overlap with the cell below it.
When clicked again, the reverse is to happen.
This is what I've tried so far.
The UITableView
When the UITableView is clicked, I use didSelectRowAtIndexPath to update a selectedPath property:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
self.selectedPath = nil;
} else {
self.selectedPath = indexPath;
}
[tableView reloadData];
}
Note, it calls reloadData, which triggers each visible cell to re-fetch the prototype and configure it based on whether it is selected or not:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
QueueItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"QueueCell" forIndexPath:indexPath];
[cell setImage:[UIImage imageNamed:[self.imageList objectAtIndex:indexPath.row]]];
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
[cell makeSelected:YES];
} else {
[cell makeSelected:NO];
}
return cell;
}
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*) indexPath {
CGFloat height = 210;
if (indexPath.row == [self.imageList count] - 1) {
height += 10;
}
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
height += 35;
}
return height;
}
The UITableViewCell subclass
In the custom cell class, its animation happens when it is made selected or not selected:
- (void)makeSelected:(BOOL)selected {
if (selected) {
[UIView animateWithDuration:0.5 animations:^{
self.customImage.frame = CGRectMake(5, 5, 310, 210);
}];
} else {
[UIView animateWithDuration:0.5 animations:^{
self.customImage.frame = CGRectMake(10, 10, 300, 200);
}];
}
}
What is happening
The table view immediately snaps to the new the allotted height for the cell, and then the cell's contents slowly animate to the new state. I want the two things to happen concurrently, and smoothly.
You might want to call
[UIView animateWithDuration:0.5 animations:^{
[self.tableView reloadData];
}];
and re-write the custom cell as following:
- (void)makeSelected:(BOOL)selected {
if (selected) {
self.customImage.frame = CGRectMake(5, 5, 310, 210);
} else {
self.customImage.frame = CGRectMake(10, 10, 300, 200);
}
}
I hope it helps.
try this... reload particular cell insteade
NSIndexPath* indexPath1 = [NSIndexPath indexPathForRow:selectedRowIndexPath inSection:section];
// Add them in an index path array
NSArray* indexArray = [NSArray arrayWithObjects:indexPath1, nil];
// Launch reload for the two index path
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
You need to reload particular cell while tap use like this..
- (void)makeSelected:(BOOL)selected {
if (selected) {
self.customImage.frame = CGRectMake(5, 5, 310, 210);
} else {
self.customImage.frame = CGRectMake(10, 10, 300, 200);
}
}
Declare BOOl isSelect; as Global
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
isSelect = NO;
} else {
self.selectedPath = indexPath;
isSelect = YES;
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
QueueItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"QueueCell" forIndexPath:indexPath];
[cell setImage:[UIImage imageNamed:[self.imageList objectAtIndex:indexPath.row]]];
if (self.selectedPath && indexPath.row == self.selectedPath.row && isSelect) {
[cell makeSelected:YES];
} else {
[cell makeSelected:NO];
}
return cell;
}
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*) indexPath {
CGFloat height = 210;
if (indexPath.row == [self.imageList count] - 1) {
height += 10;
}
if (self.selectedPath && indexPath.row == self.selectedPath.row && isSelect) {
height += 35;
}
return height;
}
It reload the cell with animation.. I hope it will help you.. Now you check it will work as you want...

Animating UITableView update, succeeded but needs more detail

I want to show animation when add cells to UITableView.
Here's is what I implemented (pseudo code)
[self.tableView beginUpdates];
// remove row exists
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:(rows exists) withRowAnimation:UITableViewRowAnimationFade];
(chang data source here, for me, it's NSFetchedResultsController)
// insert new rows
[self.tableView insertRowsAtIndexPaths:(new rows) withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
This code shows animation well, but it has a small problem.
The cells are shows moving animation from frame rect (0, 0, 0, 0) to it's actual position, not only fading animation.
I think problem is that initial frame of cells are (0, 0, 0, 0), so I set up initial frame property of cell in cellForRowAtIndexPath, but it does not work.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
cell.frame = CGRectMake(0, indexPath.row * 64, 320, 64);
NSLog(#"set frame");
....
}
How can I show shade anmation only, with no cell moving animation?
The code is untested, but the idea should work:
BOOL animateRowsAlpha = NO;
- (void)reloadData {
[UIView animateWithDuration:0.2
animations:^{
for (UITableViewCell *cell in self.tableView.visibleCells) {
cell.alpha = 0.0f;
}
} completion:^(BOOL finished) {
animateRowsAlpha = YES;
[self.tableView reloadData];
}
];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
if(animateRowsAlpha)
cell.alpha = 0.0;
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (!animateRowsAlpha) {
return;
}
[UIView animateWithDuration:0.2
animations:^{
cell.alpha = 1.0f;
}];
NSArray *indexPaths = [tableView indexPathsForVisibleRows];
NSIndexPath *lastIndexPath = [indexPaths lastObject];
if(!lastIndexPath || [lastIndexPath compare:indexPath] == NSOrderedSame) {
animateRowsAlpha = NO;
}
}

Resources