I have a page in my App with a slider on top and a repeated list on the bottom. now I'm looking for a solution that can be done this entire UI with a single UICollectionView, is that possible to have a single cell with custom design and dataSoruce from other cells?
Here is my design:
Or should I use tow different UICollectionView separately? what is the best solution out there?
Also, I created UI programmatically. is not Storyboard.
As I mentioned in comment you have to take
One collection view
Two Sections
In section one pass items : 1
In Section two pass items: Array count
gallery here is sample code
GalleryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kGalleryCell forIndexPath:indexPath];
if (cell.gestureRecognizers.count <= 0) {
UISwipeGestureRecognizer *swipeNext = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(cellDidSwipe:)];
swipeNext.direction = UISwipeGestureRecognizerDirectionLeft;
UISwipeGestureRecognizer *swipePrev = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(cellDidSwipe:)];
swipePrev.direction = UISwipeGestureRecognizerDirectionRight;
[cell setGestureRecognizers:#[swipeNext,swipePrev]];
}
Related
I want to detect when a user swipes left or right in a collectionView in which one cell occupies the entire screen width. Is it possible to do without adding gesture recognizer. I have tried adding gesture recogniser, but it only works when we set scrollEnabled property of collectionView to NO.
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipeRight:)];
swipeRight.delegate = self;
swipeRight.numberOfTouchesRequired = 1;
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwipeLeft:)];
swipeLeft.delegate = self;
swipeLeft.numberOfTouchesRequired = 1;
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.collectionView addGestureRecognizer:swipeLeft];
[self.collectionView addGestureRecognizer:swipeRight];
Maybe you have disabled userInteraction. Did you check it? And define gestures as property to the class.
self.collectionView.setUserInteractionEnabled=true;
Try to override scrollViewWillEndDragging:scrollView withVelocity:velocity targetContentOffset:targetContentOffset, since the collection view inherits from a scroll view. This way you should be able to evaluate the velocity parameter to determine the direction. Therefore you'll want to implement the UIScrollViewDelegate protocol.
I add swipe gesture to collectionView.
And it work fine.
So like Stephen Johnson said.
I guess your cell have a scrollView.
So It block gestures.
I am not sure I fully understand the context of your problem. I see that you have a collection view within a collection view. I am going to assume that the outer collection view scrolls vertical and the inner one scrolls horizontal. You will want to set up a fail dependency between the gesture recognizers for both collections.
//Data source for your outer collection view
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
...
UICollectionView* innerCollectionView = ...;
[collectionView. panGestureRecognizer requireGestureRecognizerToFail:innerCollectionView. panGestureRecognizer];
...
}
If there is more going on than this with nested collection views can you give some more details?
I have a static UITableView (created in storyboard) with a fix amount of sections and cells. Now, I'd like to make one specific cell swipable. I don't want to delete the row, I just want to display a print button where normally is the delete button when swiping a cell in a non-static UITableView .
How do I make exactly one cell in my static UITableView swipable?
U can add UISwipeGestureRecognizer on top the cell:
//The setup code (in viewDidLoad in your view controller)
UISwipeGestureRecognizer *swipeGesture =
[[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[cell addGestureRecognizer:swipeGesture];
//The event handling method
- (void)handleSingleTap:(UISwipeGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
//Do stuff here...
}
When I add Gesture for UIImageView inside UITableView, it works only in the top of position when Im trying tap on the center of any (x,y) dimensions it doesn't work
This my code:
cell.mainImage.tag = indexPath.section;
[cell.mainImage setUserInteractionEnabled:YES];
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(likeTappedDouble:)];
tapped.numberOfTapsRequired = 1;
tapped.numberOfTouchesRequired = 1;
tapped.cancelsTouchesInView = NO;
tapped.delegate = self;
[cell.mainImage addGestureRecognizer:tapped];
Look at the image HERE to get the point please.
Any idea ?
EDIT
When I set the UITapGesture for the cell it works well, but I want to understand why the Gesture works only on the top position of UIImageView !!
[cell addGesture ...]
[cell setUser ...]
Usually this type of situations happen when the parent of your imageView is smaller than your imageView.
I suspect that your cell has an height inferior to the imageView or that you have some sort of container that has the frame smaller than the imageView.
In these situations is useful to use an application like Reveal to help you out debugging the issue.
In my tableview, I am using custom cells, which have many subviews on them, two egoimageviews (subclass of imageview that takes a URL and fetches images from the web and then caches them for later use), a textview with link detection turned on, 4 labels, and a button. I have added tap gestures to the egoimageview as well as the textview. The height of the textview is calculated as per the size of the text it holds. The height calculations are done well in advance, so that the scroll performance is not affected due to height calculation on the fly while the user scrolls. All this data is fetched from the web, then text heights and cell heights are calculated and stored in an array, before tableview gets added as a subview. For some cells, there are no images to display, so in those cases I simply hide my egoimageview after setting its frame to cgrectzero. The images occupy some 170 px X 100 px on the iphone screen, and are approximately 250 KB each. When i scroll, the scroll is quite jerky. I have done a bit of research on slow scrolling cells, and I have implemented the following so far without a significant performance improvement:
Heights are calculated well in advance, not in heightforrow method.
Cell backgrounds, and backgrounds of their subviews are opaque.
There are two ways in which the data layout has to look like, so I have two similar kinds of custom cell classes with some differences, so as per the content, the cell type to return is decided, though 90% of the times, only the first kind is used.
I am not really satisfied with this jerky scroll, and have been looking up the web in frustration for something to get it scrolling butter smooth despite all that complex layout, but nothing has helped so far. Please help!
The code is
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if([type intValue] == POSTS) {
Feed *feed = [postsArray objectAtIndex:indexPath.row];
FeedCellFormattedDataObject *feedCellFormattedDataObject=[postsCellFormattedDataArray objectAtIndex:indexPath.row];
if(feed.feedTypeIndex==0){//SIMPLEST CELL
SimplestCell *simplestCell=[tableView dequeueReusableCellWithIdentifier:#"simplestcell"];
if(!simplestCell){
simplestCell=[[SimplestCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"simplestcell"];
simplestCell.delegate=self;
simplestCell.isInDetailedPostView=NO;
simplestCell.selectionStyle = UITableViewCellSelectionStyleNone;
[simplestCell.likeBtn addTarget:self action:#selector(likeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
simplestCell.cellIndex=indexPath.row;
[simplestCell setDataWithFeed:feed andFeedCellFormattedDataObject:feedCellFormattedDataObject];
return simplestCell;
}
if(feed.feedTypeIndex==1){//SIMPLEFEEDCELL WITH IMAGE
SimpleFeedCell *simpleCellWithImage=[tableView dequeueReusableCellWithIdentifier:#"imagecell"];
if(!simpleCellWithImage){
simpleCellWithImage=[[SimpleFeedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"imagecell"];
simpleCellWithImage.delegate=self;
simpleCellWithImage.isInDetailedPostView=NO;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(photoOrVideoTapped:)];
[simpleCellWithImage.feedImageView addGestureRecognizer:tapGesture];
simpleCellWithImage.selectionStyle = UITableViewCellSelectionStyleNone;
[simpleCellWithImage.likeBtn addTarget:self action:#selector(likeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
simpleCellWithImage.cellIndex=indexPath.row;
[simpleCellWithImage setDataWithFeed:feed andFeedCellFormattedDataObject:feedCellFormattedDataObject];
return simpleCellWithImage;
}
if(feed.feedTypeIndex==2){//SIMPLEFEEDCELL WITH VIDEO
SimpleFeedCell *simpleCellWithVideo=[tableView dequeueReusableCellWithIdentifier:#"videocell"];
if(!simpleCellWithVideo){
simpleCellWithVideo=[[SimpleFeedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"videocell"];
simpleCellWithVideo.delegate=self;
simpleCellWithVideo.isInDetailedPostView=NO;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(photoOrVideoTapped:)];
[simpleCellWithVideo.feedImageView addGestureRecognizer:tapGesture];
simpleCellWithVideo.selectionStyle = UITableViewCellSelectionStyleNone;
[simpleCellWithVideo.likeBtn addTarget:self action:#selector(likeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
simpleCellWithVideo.playVideoImageView.hidden=NO;
}
simpleCellWithVideo.cellIndex=indexPath.row;
[simpleCellWithVideo setDataWithFeed:feed andFeedCellFormattedDataObject:feedCellFormattedDataObject];
return simpleCellWithVideo;
}
if(feed.feedTypeIndex==3){//LINKFEEDCELL
LinkFeedCell *linkFeedCell=[tableView dequeueReusableCellWithIdentifier:#"linkcell"];
if(!linkFeedCell){
linkFeedCell=[[LinkFeedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"linkcell"];
linkFeedCell.delegate=self;
linkFeedCell.isInDetailedPostView=NO;
linkFeedCell.selectionStyle = UITableViewCellSelectionStyleNone;
[linkFeedCell.likeBtn addTarget:self action:#selector(likeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
linkFeedCell.cellIndex=indexPath.row;
[linkFeedCell setDataWithFeed:feed andFeedCellFormattedDataObject:feedCellFormattedDataObject];
return linkFeedCell;
}
}
else {
EventCell * eventCell=(EventCell*)[tableView dequeueReusableCellWithIdentifier:#"eventcell"];
if(!eventCell){
eventCell=[[EventCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"eventcell"];
eventCell.selectionStyle=UITableViewCellSelectionStyleGray;
}
[eventCell setCellDataWithEvent:[eventsArray objectAtIndex:indexPath.row]];
return eventCell;
}
}
Code for setting data
//set data and properties
self.dateLabel.text=feed.when;
self.msgTextView.text=feed.message;
self.likesCountLabel.text=feedCellFormattedDataObject.likesString;
self.commentsCountLabel.text=feedCellFormattedDataObject.commentsString;
self.userImageView.imageURL=feedCellFormattedDataObject.posterPicURL;
self.feedImageView.tag=self.cellIndex;
self.feedImageView.imageURL=feedCellFormattedDataObject.imageURL;
self.likeBtn.tag=self.cellIndex;
if(feed.canUserLike){
self.likeBtn.hidden=NO;
[self.likeBtn setBackgroundImage:feedCellFormattedDataObject.likeButtonImage forState:UIControlStateNormal];
}
else self.likeBtn.hidden=YES;
//adjust frames on the fly
self.msgTextView.frame=feedCellFormattedDataObject.msgTextViewFrame;
self.feedImageView.frame=feedCellFormattedDataObject.feedImageViewFrame;
self.likeBtn.frame=feedCellFormattedDataObject.likeBtnFrame;
self.likesCountLabel.frame=feedCellFormattedDataObject.likesCountLabelFrame;
self.commentsCountLabel.frame=feedCellFormattedDataObject.commentsCountLabelFrame;
self.commentsImageView.frame=feedCellFormattedDataObject.commentsImageViewFrame;
self.bgView.frame=feedCellFormattedDataObject.bgViewFrame;
For my app, I want a number of cells that can have both a checkmark and a detail disclosure button. That is, I want them to appear exactly like the Wi-Fi network selection in the iOS settings: checkmark on the left side, content in the middle, and detail disclosure button on the right.
Is there a proper way to do this, or am I supposed to just use an image of a checkmark in the image part of the cell content? If you know of any sample code doing this sort of thing, please point me to it.
The standard styles for UITableViewCell do not include one that works as you want, so you'll have to do this yourself by manually adding a subview to the cell.
You could use the example here as a starting point.
You can achieve it by simply prepending a couple of unicode symbols:
Put checkmark in the left side of UITableViewCell
Why don't you add a image to the standard imageView of the cell then a tapGesture on it ?
Here is how I did in willDisplayCell:
//Reset the cell
cell.imageView.image=nil;
cell.imageView.userInteractionEnabled=NO;
for(UIGestureRecognizer *recognizer in cell.imageView.gestureRecognizers)
[cell.imageView removeGestureRecognizer:recognizer];
//Add the gesture
cell.imageView.userInteractionEnabled=YES;
cell.imageView.image=[UIImage imageNamed:#"myImage"];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(geolocationAction:)];
[cell.imageView addGestureRecognizer:tapGestureRecognizer];