I have UICollectionView with UICollectionViewCell created in storyboard. I customized cell by adding to it UIImage. After user taps cell I want to show image from particular cell increased by size. To implement that I added UIImageView to view, situated it on top and made:
[previewImage setAlpha:0]; and [previewImage setHidden:YES]; in -viewDidLoad. At -didSelectItemAtIndexPath: I want to set value of image in this UIImageView to the appropriate in touched cell. I tried
previewImage.image = [(CustomCell *)[collectionView cellForItemAtIndexPath:indexPath] image].image;
but it don't works. In logs I see that previewImage.image returns null. So how can I retrieve image value from cell in right way?
Solved by setting previewImage.image this way:
UIImage *preImage = [(CustomCell *)[collectionView cellForItemAtIndexPath:indexPath] image].image;
[previewView setImage:preImage];
hey here you just use the bellow delegate method of UICollectionView
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// TODO: Select Item
}
For More info see this UICollectionview-example
i hope this help you..
Related
I'm implementing simple collection view with images inside cells. The task that I want to achieve is when user taps on the cell - there should be flip animation and some details have to appear at the same cell.
I've tried a lot of things to achieve that, for example I've added two views on the ContentView of the cell. And when user pushes the button I called transitionToView method and everything worked fine, except that when the list contained more than 9-10 images, after scrolling the list some cells started to duplicate "flipped" view with no reason. I turned off dequeueReusableCellWithReuseIdentifier function and everything worked fine, but on older devices like iPhone4, application worked to slowly.
So the best solution i found is this:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
UICollectionViewCell *cell1 = [cv dequeueReusableCellWithReuseIdentifier:kCellID3 forIndexPath:indexPath];enter code here
UIView *contents = [[UIView alloc]initWithFrame:cell1.bounds];
contents.layer.borderColor = [[UIColor colorWithRed:0.119 green:0.108 blue:0.222 alpha:1]CGColor];
contents.layer.borderWidth = 10.0f;
contents.backgroundColor = [UIColor yellowColor];
[cell1.contentView addSubview:contents];
UIView *backgroundView = [[UIView alloc]initWithFrame:cell1.bounds];
backgroundView.layer.borderColor = [[UIColor colorWithRed:0.529 green:0.808 blue:0.922 alpha:1]CGColor];
backgroundView.layer.borderWidth = 4.0f;
backgroundView.backgroundColor = [UIColor greenColor];
cell1.selectedBackgroundView = backgroundView;
[cell1 bringSubviewToFront:cell1.selectedBackgroundView];
return cell1;
}
But is it possible to add some animation for the event when cell becomes selected?
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell1 = [collectionView cellForItemAtIndexPath:indexPath];
UIView *toSwitch = cell1.contentView;
[UIView transitionFromView:toSwitch toView:cell1.selectedBackgroundView duration:0.33 options:UIViewAnimationOptionCurveLinear |UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
}
also this attempt ruins my cells - when one or more of the cells are flipped some other start to copy it..
So I need an animation (What I achieved), but I need to keep other UICollectionView cells unique and don't reuse this flipped view..
please help! :) really desperate about this!
thanks in advance
Some Solution:
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
if(cell.selected)
{
[cell setSelected:NO];
[collectionView deselectItemAtIndexPath:indexPath animated:NO];
UIView *toSwitch = cell.contentView;
[UIView transitionFromView:cell.selectedBackgroundView toView:toSwitch duration:0.001 options:UIViewAnimationOptionCurveLinear |UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
}
}
Pretty good for a temporary solution.. anyone has some better advice?
When you scroll, "old cells" are reused - that's what makes your table view perform well. Of course, if the cell in question has a transitioned view, it will show that one instead.
So, like with the data in the cell which you also set anew in each call to the cellForItemAtIndexPath function, you have to set the right view to be visible - remember the state of a cell's view like you do with data, then show the according view when the cell is presented.
I have a UITableView populated with custom UITableViewCells. Within those custom cells, I have a UITextField and a "See More" UIButton. The purpose of the UIButton is to dynamically expand that particular UITableCell when the user wishes to read more of the text. In the same way, when the user wishes to return to the original size, the user clicks the Button again, and the UITableViewCell will shrink to the original size.
Since the cell isn't being selected, I setup an IBAction within the Custom Cell like such:
//Within CustomCell.m
- (IBAction)showMoreText:(id)sender
{
//instance bool variable to flag whether the cell has been resized
self.hasBeenResized = YES;
//turn off mask to bounds, otherwise cell doesnt seem to resize
[[self.cellView layer] setMasksToBounds:NO];
// Calculate the new sizes and positions for the textView and the button
CGRect newTextViewFrame = self.textView.frame;
newTextViewFrame.size.height = self.textView.contentSize.height;
self.textView.frame = newTextViewFrame;
CGFloat bottomYPos = self.textView.frame.origin.y + self.textView.frame.size.height;
CGRect buttonFrame = self.showMoreButton.frame;
buttonFrame.origin.y = bottomYPos;
self.showMoreButton.frame = buttonFrame;
// Call begin and end updates
[(UITableView*) self.superview beginUpdates];
[(UITableView*) self.superview endUpdates];
// Set mask and put rounded corners on the cell
[[self.cellView layer] setMasksToBounds:YES];
[[self.cellView layer] setCornerRadius:10.0];
}
Following this, I have this in my ViewController class:
// Within ViewController.m
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"heightForRowAtIndexPath");
CustomCell *cell = (CustomCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
if([cell hasBeenResized] == NO)
{
return cell.frame.size.height + 20;
}
else
{
return cell.frame.size.height + cell.textView.frame.origin.y + cell.textView.frame.size.height + cell.showMoreButton.frame.size.height + 20;
}
}
What happens now is I can see the custom cell change the size of its textview, however, the table does not update the row height for that particular cell. Checking on the If-else statement there, it appears that hasBeenResized is always false, even though I set it to YES within the IBACtion of the CustomCell.
I have looked at other solutions here, but they all seem to involve didSelectRowAtIndexPath, which I cannot use in this instance (I have another behavior for the cell when it is selected).
Am I doing this completely wrong? Ideally, what I would like to do is to have the "Show More" button animate downwards as the textview is expanded and vice versa when it's collapsed.
Thank you!
Method beginUpdates won't call reloadData for you - you have to do it manually.
For your case it would be best to call:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
And place your showMoreText code in tableView:cellForRowAtIndexPath: method (for selected cell only)
To Update your tableView, you have to reload it.
[tableView reloadData];
I can subclass the cell and resolve the problem, but I'd like to know why this doesn't work.
I set an image in the cell, then in this method, I move the image to the right:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell.imageView setFrame:CGRectMake(cell.contentView.bounds.size.width/2 - cell.imageView.frame.size.width/2 + 100,
cell.contentView.bounds.size.height/2 - cell.imageView.frame.size.height/2,
cell.imageView.frame.size.width,
cell.imageView.frame.size.height)];
NSLog(#"center: %#", NSStringFromCGPoint(cell.imageView.center));
NSLog(#"frame: %#", NSStringFromCGRect(cell.imageView.frame));
}
Notice the +100 I added to ensure it's over to the right.
When I check the console, it indicates this:
center: {250, 57.5}
frame: {{150, 7.5}, {200, 100}}
However the output is this:
The image is still aligned to the left side. Can this be changed, and if so, how?
if you go to the header file of UITableViewCell than there you will find...
> // Content. These properties provide direct access to the internal
> label and image views used by the table view cell. These should be
> used instead of the content properties below.
> #property(nonatomic,readonly,retain) UIImageView *imageView
> __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); // default is nil. image view will be created if necessary.
so as you can see it says readOnly property to the image view... I think this explains your inability to move the imageView.
You can not move the image view. Solution is or to subclass and do your own drawing in drawRect, or to add a subview to the cell.contentView.
Edit:
If an image is set, it appears on the left side of the cell, before
any label. UITableViewCell creates the image-view object when you
create the cell.
From UITableViewCell Class Reference
Is there any way that I can get a specific cell to change its style or background image while scrolling the table view?
I want to change the image of a cell which is on top of the visible cells. But only its image is going to be changed the others will stay same, until after scrolling the others come to top of the cells which are shown on the screen. Then the top one's image is going to change this time.
You need to implement scrollViewDidScroll: method of UIScrollViewDelegate in your controller then use visibleCells property of UITableView to get the visible cells of the table.
Something like the following code should work
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
UITableView* tableView;
NSArray* visibleCells;
BOOL first;
tableView = (UITableView*)scrollView;
visibleCells = tableView.visibleCells;
first = YES;
for (UITableViewCell* cell in visibleCells) {
if (first) {
//customize the top cell
first = NO;
}else {
//customize the other visible cells
}
}
}
I have a grouped UITableView that has 3 sections. I would like to show a UIImage with some text next to it (not a cell), but I am not sure how I can go about doing that? The image and text need to match the background of the pinstripes.
A UITableView has a backgroundView property that it uses to display the pinstripes for the grouped style. You can either replace the background view or add to it. If you replace it, you lose the pinstripes.
[myTable.backgroundImage addSubview:myImage];
[myTable.backgroundImage addSubview:myLabel];
You don't have to define a custom cell, you can use a standard UITableViewCell. It has properties for text and an image. Assign the image to the imageView property, put the text in the textLabel property.
Depending on the size of your image and your desired placement, you can use the imageView property of the UITableViewCell. Essentially, your cellForRowAtIndexPath will look like this:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Normal cell setup
cell.imageView.image = myImage;
cell.textLabel.text = imageDescription;
return cell;
}
That will create a cell with an image at the left edge with text after it in the middle/right edge
[self.tableView addSubview:myImageView];
[Self.tableView sendSubviewToBack:myImageView];
Or
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:"myimage.png"]];
Use Photoshop to place something on top of an image of the pinstripes.