Animation in willSelectRowAtIndexPath after validation - ios

I have a table view delegate which checks if a specific cell may be selected. If not, the selection is aborted. In order to give the user a visual feedback I want to dye a label of this cell red and after a short amount of time dye it back to black:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (true) { // Some simplification
MyTableViewCell cell = ... // The correct cell is loaded here
[UIView animateWithDuration:0.5 animations:^{
cellToSelect.labelAmount.textColor = [UIColor redColor];
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
cellToSelect.labelAmount.textColor = [UIColor blackColor];
}];
}];
return nil;
}
return indexPath;
}
The animations are not performed. Instead, the cell is just (visually) deselected.
EDIT: I just tried the proposed solutions and neither seemed to work. So I digged a little bit further and found out that I can do animations but am not able to change the textColor of any label inside a cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyTableViewCell cell = ...
cell.labelAmount.textColor = [UIColor redColor];
// Now, although the property was set (as I can see in the debugger)
// the label is still drawn with standard black text.
}
Also, setting the color via a colorful attributed string does not work.
On the other hand, a change of highlightedTextColor is presented accordingly. So this works.

This property - textColor - is not animatable. Use transitionWithView:duration:options:animations:completion:
[UIView transitionWithView:label duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
label.textColor = [UIColor redColor];
} completion:^(BOOL finished) {
[UIView transitionWithView:label duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
label.textColor = [UIColor blackColor];
} completion:nil];
}];

Conforming to apple documentation you can't animate all you want:
From apple :
The following properties of the UIView class are animatable:
#property frame
#property bounds
#property center
#property transform
#property alpha
#property backgroundColor
#property contentStretch
Now this is a trick to animate what you want:
For instance, set alpha to 1.0
- will result in no visual change to the view but launch animation
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (true) { // Some simplification
MyTableViewCell cell = ... // The correct cell is loaded here
[UIView animateWithDuration:0.5 animations:^{
//here the trick set alpha to 1
self.view.alpha = 1;
cellToSelect.labelAmount.textColor = [UIColor redColor];
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
cellToSelect.labelAmount.textColor = [UIColor blackColor];
}];
}];
return nil;
}
return indexPath;
}

Related

Pop collectionview cell out and zoom - uicollectionviewcell animation

Im trying to create a cool animation with my collection view selection. Basically I have a collection view of photo cells displayed. What I want to happen is have the cell pop out of its location, scale and move to the center of the screen where the user will be prompted to confirm the selection.
Here is my code so far, but currently the animation takes the cells original frame location, so if I scroll it doesnt take into account that the frame position is no longer the same.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
PhotoCell *cell = (PhotoCell *)[collectionView cellForItemAtIndexPath:indexPath];
collectionView.allowsSelection = NO;
[self createAnimationWithCell:cell];
}
- (void)createAnimationWithCell:(PhotoCell *)cell {
UIImageView *selectedImage = [[UIImageView alloc] initWithFrame:cell.bounds];
selectedImage.center = cell.center;
selectedImage.image = cell.imageView.image;
[self.view addSubview:selectedImage];
[UIView animateWithDuration:2.5 animations:^{
selectedImage.center = self.view.center;
} completion:^(BOOL finished) {
[selectedImage removeFromSuperview];
self.collectionView.allowsSelection = YES;
}];
}
I solved it myself:
For those who are experiencing the same problem, we have to take into account how much the collection view has scrolled (offset) and use that information. I created a variable called collectionViewOffset and gave it an initial value of 0.0
then used:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// getting the scroll offset
collectionViewOffset = scrollView.contentOffset.y;
NSLog(#"offset: %f", collectionViewOffset);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
PhotoCell *cell = (PhotoCell *)[collectionView cellForItemAtIndexPath:indexPath];
//collectionView.allowsSelection = NO;
//collectionView.scrollEnabled = NO;
[cell.superview bringSubviewToFront:cell];
[UIView animateWithDuration:2.0 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:.2 options:UIViewAnimationOptionCurveLinear animations:^{
cell.center = CGPointMake(self.view.vWidth/2, self.bannerView.vBottomEdge + collectionViewOffset + 40);
} completion:^(BOOL finished) {
}];
}

How to darken an image (in a collection view) on highlight?

I have a CollectionView where I display my custom CollectionViewCell which consists of a UIImageView (called "thumbnailView").
What I want is that when the user presses one of the collection cell, then the image becomes darker (exactly the same behaviour in the iPhone home menu with all the apps).
I've tried with the Quartz Framework and did so in the MyCustomCollectionViewCell.m :
-(void) setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
[self setNeedsDisplay];
}
-(void) drawRect:(CGRect)rect {
[super drawRect:rect];
if (self.highlighted) {
[self.thumbnailView.layer setBackgroundColor:[UIColor blackColor].CGColor];
[self.thumbnailView.layer setOpacity:0.9];
}
}
but it just adds black corners to my images in the collection cell but without darkening them like I want.
You can add another view to do the highlighting.
In the custom cell add a property:
#property (nonatomic, strong) UIView *highlightView;
Initialize and add it to the cell's contentView. Notice that the alpha is initially set to zero:
self.highlightView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
self.highlightView.backgroundColor = [UIColor blackColor];
self.highlightView.alpha = 0;
[self.contentView addSubview:self.highlightView];
In your custom UICollectionView override the highlight methods and change the alpha of the cell's highlight view:
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCollectionViewCell* cell = (MyCustomCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:0.3 animations:^()
{
cell.highlightView.alpha = 0.5;
}];
}
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCollectionViewCell* cell = (MyCustomCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:0.3 animations:^()
{
cell.highlightView.alpha = 0;
}];
}

Why can't I tap on an UITableViewCell when it is animating between two cell background colors?

I have an simple animation for changing background colors repeatedly on my UITableViewCell. Here is a snippet of my code. For some reason doing this will not all me to call my didSelectRowAtIndexPath method???? I know this because when I remove the code below, it works fine. Any solutions to this? Thanks!
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.3 animations:^{
cell.backgroundColor = [UIColor colorWithRed:3.0/255.0 green:165.0/255.0 blue:136.0/255.0 alpha:1.0];
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.textLabel.textColor = [UIColor whiteColor];
}];
} completion:nil];
}
Add the UIViewKeyframeAnimationOptionAllowUserInteraction option to your keyframe animation. I tested it, and this works for me:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat | UIViewKeyframeAnimationOptionAllowUserInteraction animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.3 animations:^{
cell.backgroundColor = [UIColor colorWithRed:3.0/255.0 green:165.0/255.0 blue:136.0/255.0 alpha:1.0];
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.textLabel.textColor = [UIColor whiteColor];
}];
} completion:nil];
}

Animate tableView Cell on didSelectRowAtIndexPath?

I would like to resize my tableView cell when the user selects a row, the cell becomes smaller then larger again. This is what I have tried so far:
#pragma mark UITableView Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// My animation
cell.contentView.transform = CGAffineTransformMakeScale(0.95,0.95);
cell.contentView.alpha = 1.f;
[UIView beginAnimations:#"button" context:nil];
[UIView setAnimationDuration:0.2];
cell.contentView.transform = CGAffineTransformMakeScale(1,1);
cell.contentView.alpha = 1.0f;
[UIView commitAnimations];
}
This is my tableView data source:
#pragma mark UITableView Datasource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up cell
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:21];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.highlightedTextColor = [UIColor lightGrayColor];
cell.selectedBackgroundView = [[UIView alloc] init];
}
// Images in my cell
NSArray *images = #[#"Songs", #"Albums", #"Artists", #"Playlists"];
UIImageView *cellImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:images[indexPath.row]]];
cellImage.frame = CGRectMake(0, 0, 90, 90);
[cell addSubview:cellImage];
return cell;
}
But this does not work. The image in the cell simply stays the same size. Any ideas? Thanks.
I seriously advise going with a UICollectionView for something like this. With it, you only have to call performBatchUpdates and you can put any frame setting inside of it's block. It's practically magic!
I don't know if you can or should do what you ask about, but if you can it would probably be with a custom UITableViewCell. But, you might be able to fake it with a custom cell, maybe with a UIView that holds all the cell's contents. The UIView would animate inside the cell, and if you are not showing separators on the table it could look like the cell itself is animating. So basically you're hiding the actual cell, and using a UIView in the cell to simulate animating the cell. Maybe like this:
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.customCell.frame = CGRectMake(110, 20, 100, 20);
} completion:^(BOOL finished) {
[UIView animateWithDuration:SLIDE_TIME delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.customCell.frame = CGRectMake(0, 0, 320, 60);
} completion:^(BOOL finished) {
}];
}];

How to make an iOS Drop down menu

How do I create a good looking drop down menu in iOS. It should open when the user clicks a button in the navigation bar.
I tried creating a table, but got the error Static table views are only valid when embedded in UITableViewController instances. If I use UITableViewController, then it has to be full width.
Maybe you could try using a CollectionView instead of TableView, and if you need sopport for iOS 4+, PSTCollectionView is a good option :)
What I did is added a Button and on button tap one table view is shown, whenever any row is selected that row title is set to button title.
- (void)addOrganizationButton {
self.organizationButton = [UIUtils createButtonWithFrame:CGRectMake(203,115,451,38)
titleText:#"Organization"
type:UIButtonTypeCustom
normalImage:nil selectedImage:nil
target:self
view:self.registerView
tag:0
selector:#selector(organizationButtonTap)];
self.organizationButton.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
[self.organizationButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
self.organizationButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.organizationButton.layer.borderWidth = 1;
}
//Show table view on button tap
- (void)organizationButtonTap {
self.organizationTable = [[UITableView alloc]initWithFrame:CGRectMake(203,153, 451,220)];
self.organizationTable.layer.borderWidth = 1;
self.organizationTable.dataSource = self;
self.organizationTable.delegate = self;
[UIView animateWithDuration:1
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame = self.organizationTable.frame;
frame.size.height = 220;
self.organizationTable.frame = frame;
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
[self.registerView addSubview:self.organizationTable];
}
//Table view delegates
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;//to be changed
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return 3;//get dictionary count
}
- (UITableViewCell *) tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
NSString *cellIdentifier=#"Cell Identifier";
cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = [NSString stringWithFormat:
#"Section %ld, Cell %ld",
(long)indexPath.section,
(long)indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.organizationButton setTitle:#"faf" forState:UIControlStateNormal];
[UIView animateWithDuration:1
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
CGRect frame = self.organizationTable.frame;
frame.size.height = 0;
self.organizationTable.frame = frame;
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
}
You can prepare a custom view for that and add it as a subview in your ViewController.
Use UIView animations for simulating "drop down" effect.

Resources