Add overlay to CollectionViewCell once it's clicked - ios

It's there a way to add an semi transparent overlay to a CollectionViewCell on it's clicked? (I want to "darken" the entire cell when a user taps on the cell).
I found a way to change the background color but I don't know if there'a way to add an overlay.
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:0.1 delay:0 options:(UIViewAnimationOptionAllowUserInteraction) animations:^{ [cell setBackgroundColor:[UIColor colorWithRed:232/255.0f green:232/255.0f blue:232/255.0f alpha:1]]; } completion:nil];
}
EDIT
I added an UIView with a semi transparent background to the Cell once it's tapped:
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
UIView *overlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 172, 210)];
overlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.1];
[cell addSubview:overlay];
}

The simplest solution, I find, is to add to the cell, right from the start, a UIImageView with no image but with a highlighted image:
UIImageView* iv = [[UIImageView alloc] initWithImage:nil highlightedImage:im];
iv.userInteractionEnabled = NO;
[cell addSubview: iv];
The result is that the image im magically becomes visible in the cell when - and only when - the cell is highlighted (selected).

Related

Buttons created programmatically doesn't receive touch up inside events... UICollectionViewCell

I'm creating Collection View Cells programmatically using Facade framework to position it right. Unfortunately buttons inside cells doesn't react to touches.
Collection View is created using storyboard.
CollectionViewCell appearance loading:
_likesButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_likesButton setBackgroundColor:[UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:0.10]];
_likesButton.contentEdgeInsets = UIEdgeInsetsMake(5, 8, 5, 8);
_likesButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
_likesButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
[_likesButton setAttributedTitle:[self attributedSpacedStringFromString:#"+10039" withColor:[UIColor flatWhiteColor] withFont:[UIFont fontWithName:#"OpenSans-Bold" size:12]] forState:UIControlStateNormal];
_likesButton.layer.cornerRadius = 12;
[_likesButton sizeToFit];
_likesButton.userInteractionEnabled = YES;
In Collection View:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.likesButton.tag = indexPath.row;
[[cell likesButton] addTarget:self action:#selector(showAlert:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
What I'm doing wrong?
Best regards,
Adrian.
Ok I just figured it out...
I had image as background (UIButton was subview) and UIImageView has userInteractionEnabled disabled as default. Setting this property to YES, fixed issue.

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;
}];
}

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) {
}];
}];

can't set subview's frame in scrollview after scrolling

I have an Horizontal-only UIScrollView.
it contains several UIImageViews and a borderView for indicating which one is selected.
borderView is a UIView with border and no content.
what I want to do:
when the user tap the imageView, I wish the borderview can move to and overlay on the tapped imageView for indicating.
what I did in my code:
1.Add imageViews with UITapgesture event and borderView to the scrollView
-(void)setStaticFilterToBar
{
_filterList = [APIHelper getStaticFilterList:_originBackgroundImage];
filterScrollView.contentSize = CGSizeMake(320,filterScrollView.contentSize.height);
filterScrollView.backgroundColor = [[UIColor blackColor]colorWithAlphaComponent:0.7f];
int xAis = 64;
for(int i=0; i<_filterList.count; i++)
{
UIImageView *filter = [[UIImageView alloc]initWithImage:[_filterList objectAtIndex:i]];
[filter setUserInteractionEnabled:YES];
[filter setFrame:CGRectMake(i * xAis,5,60,60)];
[filter setTag:i];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self
action:#selector(filterElementTapToApplyFilter:)];
[tap setDelegate:self];
[filter addGestureRecognizer:tap];
[filterScrollView addSubview:filter];
if((i+1) * xAis > 320)
{
filterScrollView.contentSize = CGSizeMake(filterScrollView.contentSize.width + xAis,
filterScrollView.contentSize.height);
}
}
//add borderview
UIView *borderView = [[UIView alloc]init];
borderView.layer.borderColor = [UIColor redColor].CGColor;
borderView.layer.borderWidth = 3.0f;
borderView.layer.cornerRadius = 6;
[filterScrollView addSubview:borderView];
}
-(void)filterElementTapToApplyFilter:(UITapGestureRecognizer *) recognizer
{
//apply filter
[self applyFilterByUIView:recognizer.view];
//move the borderview to the tapped imageView
[self selectSubViewsFromScrollView:filterScrollView TargetFrame:recognizer.view.frame];
}
2.Tap the imageview to change the borderview's frame value to that of imageView's.
(no matter using animationwithDuration:animations:completion: or set the frame directly)
-(void)selectSubViewsFromScrollView:(UIScrollView *)scrollView TargetFrame:(CGRect)targetFrame
{
//borderView is the last subview.
UIView *borderView = [scrollView.subviews objectAtIndex:scrollView.subviews.count-1];
NSLog(#"Before: borderView.frame:(%d,%d,%d,%d)",(int)borderView.frame.origin.x,
(int)borderView.frame.origin.y,
(int)borderView.frame.size.width,
(int)borderView.frame.size.height);
//1
borderView.frame = targetFrame;
//2 for animation
//[UIView animateWithDuration:0.3 animations:^{
// borderView.frame = targetFrame;
//}];
NSLog(#"After: borderView.frame:(%d,%d,%d,%d)",(int)borderView.frame.origin.x,
(int)borderView.frame.origin.y,
(int)borderView.frame.size.width,
(int)borderView.frame.size.height);
}
The problem I have:
it works just fine as I predicted for beginning.
But after scrolling the filterScrollView, click on imageview and the borderview won't change its position anymore.but still apply the right filter correctly.
the value of borderview's frame is changed, but the position in screen didn't change.
what happened here? Did I miss anything? Any help would be appreciated.
Note. I use storyboard and use No autolayout for all views.
We can use Collection View ,collection view also internally work same as scroll view and also we can handle selecting items easily .
in cellforItemAtIndexPath method add selected and normal cells like below
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"collectionViewCell" forIndexPath:indexPath];
if (cell.selected) {
cell.backgroundColor = [UIColor blueColor]; // highlight selection
}
else
{
cell.backgroundColor = [UIColor clearColor]; // Default color
}
return cell;
}
//once it is selected add the color
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *datasetCell =[collectionView cellForItemAtIndexPath:indexPath];
datasetCell.backgroundColor = [UIColor blueColor]; // highlight selection
}
//when deselected make it as normal style
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *datasetCell =[collectionView cellForItemAtIndexPath:indexPath];
datasetCell.backgroundColor = [UIColor ClearColor]; // Default color
}

How to make table cell's accessoryView appear on top of highlight?

I'm dynamically adding an accessoryView to my UITableVieCell when it is tapped. It appears to me that the cell highlight is blocking the accessoryView. I don't see my acessoryView until the highlight disappears via tapping a different table cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[tableView selectRowAtIndexPath:indexPath
animated:YES
scrollPosition:UITableViewScrollPositionNone];
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = #"Loading server stuff";
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, 20, 10);
button.frame = frame;
button.backgroundColor = [UIColor redColor];
cell.accessoryView = button;
}
The highlight of a cell swaps the background of all the views within. Place an image of your button with this instead:
- (void)setImage:(UIImage *)image forState:(UIControlState)
That way, the background is swapped, but the image remains on top.

Resources