I don't know if this is possible. I have UITableview when the user click one cell or row, the tableview will automatically scroll to top then do an action method after it reach at the top.
Here's my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[UIView animateWithDuration:5.0 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[self.tableView setContentOffset:CGPointZero animated:YES]; // scroll to top
} completion:^(BOOL finished) {
[self connectToSubMenu:indexPath.row];
}];
}
I don't know if I miss anything here. Sorry I'm still learning objective-c.
Add this to set your tableview to scroll top automatically.
-(void)tableView:(UITableView *)tableview didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Your custom code
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
// Call your custom method here, Now tableview scrolled to top
}
I think you were pretty close. Using UIView's animateWithDuration is good, just need to use the right method to scroll the table position.
-(void)tableView:(UITableView *)tableview didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[UIView animateWithDuration:5.0 animations:^{
[self.tableView scrollToRowAtIndexPath:0 atScrollPosition:UITableViewScrollPositionTop animated:NO];
} completion:^(BOOL finished){
[self connectToSubMenu:indexPath.row];
}];
}
Note also that I set animated:NO in the inner method call, since the outer method is doing the animating.
Related
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;
}];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
..
//this cell is custom cell.
[cell.textview setContentOffset:CGPointZero animated:YES]; //did not work
..
}
////////////////
- (void)tableView:(UITableView *)tableView willDisplayCell:(CustomCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
..
[cell.textview setContentOffset:CGPointZero animated:YES]; //did not work
..
}
all of them not effect. textview scroll was shown bottom.
I got it myself
solution here.
- (void)tableView:(UITableView *)tableView willDisplayCell:(CouponCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
CGPoint bottomOffset = CGPointMake(0, cell.textview.frame.size.height - cell.textview.contentSize.height);
if (cell.textview.contentSize.height >= cell.textview.bounds.size.height) {
[cell.textview setContentOffset:bottomOffset animated:NO];
}else{
[cell.textview setContentOffset: CGPointMake(0,0) animated:NO];
}
}
scrolled positon is set (0,0) by iOS inner...maybe.
so setting minus y values.
thanks for answer.
have a good day all!
Try to use without animation
[cell.textview setContentOffset:CGPointZero]
Or add animation block
[UIView animateWithDuration:0.5 animations:^{
[cell.textview setContentOffset:CGPointZero]
}];
Hope this help
Try with below code:
[cell.textview scrollRangeToVisible:NSMakeRange(0, 0)];
OR
[cell.textview setContentOffset:CGPointZero animated:NO];
This is a hack that works well. In cellForRow you disable textView scrolling. Then in viewDidAppear you find the specific index path that contains the textView and you enable scrolling again. If you want you can delete padding from textView:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:4 inSection:0];
FileInfoNotesTableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.notesTextView.scrollEnabled = YES;
//I cut the padding from the textview
cell.notesTextView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
I lost a bit nerves on this case. I have UIView with few images as buttons. I would like to insert it with insertRowsAtIndexPaths:
I have no idea how to start with that, and I really searched every site on google. I even found something that works like a charm ( http://jackkwok.github.io/JKExpandTableView/ ) but I still cannot make it right.
Here is my didSelectRowAtIndexPath method:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
int selectedRow = indexPath.row;
NSLog(#"touch on row %d", selectedRow);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
PrototypeCell *prototypeCell =(PrototypeCell *)[tableView cellForRowAtIndexPath:indexPath];
if (prototypeCell.stretched == NO){
[UIView animateWithDuration:1 animations:^{
prototypeCell.View.frame = CGRectMake(0, 0, 320, 120);}
completion: nil];
prototypeCell.stretched = YES;}
else {
[UIView animateWithDuration:1 animations:^{
prototypeCell.View.frame = CGRectMake(0, 0, 15, 120);}
completion: nil];
prototypeCell.stretched = NO;
}
// Start a new core animation transaction
[CATransaction begin];
// Set a completion block for the animation
[CATransaction setCompletionBlock:^{
//
// Update the data model to add a new section
// [_data addObject:[DetailView init] alloc];
NSInteger item = self.thingList.count-1;
// Animate the new section apperance
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForItem:item inSection:0], nil] withRowAnimation:UITableViewRowAnimationFade];
NSLog(#"Array is: %#", _data);
// [tableView endUpdates];
}];
[CATransaction commit];
}
My head is already numb from that problem. I cannot even understand basic inserting, how I write what I would like to insert here?
Any Help appreciated!
Based on your described intent, I'm not entirely sure you need or want to insert table rows. It looks like what you are trying to achieve is to simply expand the height of a given row to reveal some extra buttons when that row is selected.
Changing the height of row is covered How to dynamically resize UITableViewCell height
Essentially you can have your PrototypeCell have some extra content (the buttons) that is usually clipped. When the view is selected, you simply change the height to make sure all of the buttons would be visible and you indicate to the tableview to reload the row that was selected.
Should you need to insert rows, this was covered in how to properly use insertRowsAtIndexPaths?
Good luck!
I am animating a view over table view when user taps a cell. Although my DidSeclectRowAtIndexPath is getting called when I tap the cell first time but the animation does not take place. On the second tap the animation block gets triggered.
What may be causing this issue?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.ChosenSubCategory=[self.SubCategoryListArray objectAtIndex:indexPath.row];
[self getUserSpecificLevelDetails];
// [self ShowLevelPickerView];
[UIView animateWithDuration:1.0 animations:^{
[self.ChooseLevelView setCenter:CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2)];
[player prepareToPlay];
[player play];
}];
}
Might be because of the threading issue.
Please try the below solution. Hope it works.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath
{
self.ChosenSubCategory=[self.SubCategoryListArray objectAtIndex:indexPath.row];
[self getUserSpecificLevelDetails];
// [self ShowLevelPickerView];
[self performSelector:#selector(performOperation) withObject:nil afterDelay:0];
}
- (void)performOperation
{
[UIView animateWithDuration:1.0 animations:^{
[self.ChooseLevelView setCenter:CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2)];
[player prepareToPlay];
[player play];
}];`
}
When I select a row in a UITableView, I'm calling scrollRectToVisible:animated on the GCRect of the row's frame, and immediately afterwards doing some other animations. My problem is that I don't know when the animation from scrollRectToVisible:animated is complete.
My code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRwoAtIndexPath:indexPath];
[self.tableView scrollRectToVisible:cell.frame animated:YES];
//more animations here, which I'd like to start only after the previous line is finished!
}
I ran across this UIScrollViewDelegate method:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// Do your stuff.
}
Only called for animated scrolls. Not called for touch-based scrolls. Seems to work great.
An easier way is to encapsulate the scrolling code in a UIView animateWith[...] block, like this:
[UIView animateWithDuration:0.3f animations:^{
[self.tableView scrollRectToVisible:cell.frame animated:NO];
} completion:^(BOOL finished) {
// Some completion code
}];
Note that animated == NO in the scrollRectToVisible:animated: method.
The protocol UITableViewDelegate conforms to UIScrollViewDelegate. You can set BOOL parameter when you scroll manually and than check it in scrollViewDidScroll:
BOOL manualScroll;
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRwoAtIndexPath:indexPath];
manualScroll = YES;
[self.tableView scrollRectToVisible:cell.frame animated:YES];
}
...
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (manualScroll)
{
manualScroll = NO;
//Do your staff
}
}
Don't forget to set UITableViewDelegate.