I implemented a CollectionView with ImageViews in the cells. I want a DetailViewController to appear when the cell is tapped. I set the User Interaction Enabled in the Interface Builder for the ImageView and the Cell. What am I making wrong? I have this code in the ViewController:
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section;
{
return 9;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
PhotosCell *cell = [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
// load the image for this cell
NSString *imageToLoad = [NSString stringWithFormat:#"%d.jpg", indexPath.row +1];
// NSLog(imageToLoad);
cell.imageView.image = [UIImage imageNamed:imageToLoad];
return cell;
}
// the user tapped a collection item, load and set the image on the detail view controller
//
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// NSLog(#"inside!");
if ([[segue identifier] isEqualToString:#"showDetail"])
{
NSIndexPath *selectedIndexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
// load the image, to prevent it from being cached we use 'initWithContentsOfFile'
NSString *imageNameToLoad = [NSString stringWithFormat:#"%d_full", selectedIndexPath.row+1];
NSString *pathToImage = [[NSBundle mainBundle] pathForResource:imageNameToLoad ofType:#".jpg"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathToImage];
PhotoDetailViewController *detailViewController = [segue destinationViewController];
detailViewController.myImage = image;
}
}
But the method "prepareForSegue" is not being called when the cell is tapped...
implement collectionview delegate method
collectionView:didSelectItemAtIndexPath:
there call
[self performSegueWithIdentifier:#"showDetail" sender:self];
Related
Can we make a rank like prepareForSegue after didSelectRowAtIndexPath?
My NSLog sends a good sentence, this NSLog is that I want (in didSelectRowAtIndexPath but assign AFTER to my NSLog in prepareForSegue) I would like the NSLog in prepareForSegue sends the same sentence that didSelectRowAtIndexPath.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
self.cellSelected = cell.textLabel.text;
NSLog(#"la : %#", self.cellSelected);
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showPhotoView"]) {
NSLog(#"ou %#", self.cellSelected);
PhotoViewController *viewController = (PhotoViewController *)segue.destinationViewController;
viewController.cellSelected = self.cellSelected;
}
}
If you use a segue that originates from a UITableViewCell the sender parameter will actually contain the UITableViewCell that was selected. So you could just use the sender parameter to get the data you need.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showPhotoView"]) {
UITableViewCell *cell = sender;
PhotoViewController *viewController = (PhotoViewController *)segue.destinationViewController;
viewController.cellSelected = cell;
}
}
Yes you can ! You need just to fix some things
Here is an example i used
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"friends2" sender:self];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"friends2"]) {
NSString * object = nil;
NSIndexPath *indexPath2 = nil;
if (self.searchDisplayController.isActive) {
indexPath2 = [[ self.searchDisplayController searchResultsTableView]indexPathForSelectedRow];
object = self.results[indexPath2.row];
NSLog(#"is active : %#", object.self);
} else
{
indexPath2 = [self.tableView indexPathForSelectedRow];
object = sortedArray.self[indexPath2.row];
NSLog(#"is not active : %#", object.self);
}
with didSelect.. i just made the segue, and with performSegue you do what you want to do
How do I reference a specific UICollectionViewCell so that each of them segue to different VCs?
Here is the code for the cells:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MY_CELL" forIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:self.myCellImages[0]];
UIImage *cellImage = [[UIImage alloc] init];
cellImage = [UIImage imageNamed:[self.myCellImages objectAtIndex:indexPath.row]];
cell.imageView.image = cellImage;
return cell;
}
So this displays a bunch of different cells depending on how many images I load in to my array.
say my array is:
self.myCellImages = #[#"1.jpg", #"2.jpg",.... #"20.jpg"];
how do I reference an individual cell so that it segues into different VC? For example, clicking on the cell that has image 1.jpg segues into 1VC and clicking on the cell with17.jpg segues to 17VC
Is it something like:
if (NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];)
{
//segue here
}
I can't figure out the correct syntax
Thanks to Timothy, I added
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:indexPath
{
NSString *storyboardId = #"main_to_VC1";
[self performSegueWithIdentifier:storyboardId sender:indexPath];
}
You need to establish segues between your collection view controller (not the cell) and the destination controllers, giving each a unique storyboard ID.
Then in the collectionView:didSelectItemAtIndexPath: delegate method, decide which controller you want to segue to based on the indexPath and initiate the segue programmatically:
- (void)collectionView:collectionView didSelectItemAtIndexPath:indexPath
{
NSString *storyboardId = ...; // determine storyboard ID based on indexPath
[self performSegueWithIdentifier:storyboardId sender:indexPath];
}
So I'm completely stumped here. I'm using xcode 5 and I have a table view with 2 segues. I tried to set the segues originally with two different prototype cells, but that didn't work. So I now have both segues set at the UITableViewController. It seems like whichever segue I created last is the one it goes to. I'm not getting any errors and when I step through the code, it fires on the correct line to execute the segue.
This seems to execute perfectly every time but it just doesn't go to the correct view.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([currentTableViewType isEqualToString:#"feedbackOnly"]){
// hits this line correctly
[self performSegueWithIdentifier:#"ShowSendFeedback" sender:indexPath];
} else {
// hits this line correctly
[self performSegueWithIdentifier:#"ShowTicketDetails" sender:indexPath];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSIndexPath *)selectedIndexPath {
if ([[segue identifier] isEqualToString:#"ShowTicketDetails"])
{
TicketDetailsViewController *tdv = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
tdv.tPriority = currentTicket.ticketPriority;
tdv.tId = currentTicket.ticketId;
tdv.tStatus = currentTicket.ticketStatus;
}
if ([[segue identifier] isEqualToString:#"ShowSendFeedback"]){
FeedbackViewController *fvc = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
fvc.tPriority = currentTicket.ticketPriority;
fvc.tId = currentTicket.ticketId;
fvc.tStatus = currentTicket.ticketStatus;
}
}
To be thorough, I've included my entire controller that has the issue.
#import "TicketsViewController.h"
#interface TicketsViewController ()
#end
#implementation TicketsViewController
#synthesize json, ticketsArray, ticketsTableView, currentTableViewType;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Tickets";
AppDataClass *appData=[AppDataClass getInstance];
currentTableViewType = appData.tableViewType;
[self retrieveData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return ticketsArray.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if([currentTableViewType isEqualToString:#"feedbackOnly"]){
return #"Requires Feedback";
} else {
return #"Issues";
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
Ticket * currentTicket = [ticketsArray objectAtIndex:indexPath.row];
cell.textLabel.text = currentTicket.ticketName;
cell.detailTextLabel.text = currentTicket.ticketAddress;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if([currentTicket.ticketPriority.lowercaseString isEqualToString:#"high"]) {
cell.imageView.image = [UIImage imageNamed:#"alert.png"];
if([indexPath row] % 2) [cell setBackgroundColor:[UIColor lightGrayColor]];
}
return cell;
}
#pragma mark - Methods
- (void)retrieveData
{
// NSURL * url = [NSURL URLWithString:getDataURL];
// NSData * data = [NSData dataWithContentsOfURL:url];
AppDataClass *appData=[AppDataClass getInstance];
NSString *args = #"userid=%#&authid=%#";
NSString *values=[NSString stringWithFormat:args, appData.userId, appData.authId];
json = [appData getPostData:appData.URL_LIST_TICKETS:values];
ticketsArray = [[NSMutableArray alloc] init];
// segeue names
// allTickets
// feedbackOnly
for(int i=0; i<json.count; i++){
NSString * tId = [[json objectAtIndex:i] objectForKey:#"id"];
NSString * tName = [[json objectAtIndex:i] objectForKey:#"name"];
NSString * tPriority = [[json objectAtIndex:i] objectForKey:#"priority"];
Ticket * myTicket = [[Ticket alloc] initWithTicketId:tId andTicketName:tName andTicketPriority:tPriority];
[ticketsArray addObject:myTicket];
}
[self.ticketsTableView reloadData];
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([currentTableViewType isEqualToString:#"feedbackOnly"]){
[self performSegueWithIdentifier:#"ShowSendFeedback" sender:indexPath];
} else {
[self performSegueWithIdentifier:#"ShowTicketDetails" sender:indexPath];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSIndexPath *)selectedIndexPath {
if ([[segue identifier] isEqualToString:#"ShowTicketDetails"])
{
TicketDetailsViewController *tdv = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
tdv.tPriority = currentTicket.ticketPriority;
tdv.tId = currentTicket.ticketId;
tdv.tStatus = currentTicket.ticketStatus;
}
if ([[segue identifier] isEqualToString:#"ShowSendFeedback"]){
FeedbackViewController *fvc = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
fvc.tPriority = currentTicket.ticketPriority;
fvc.tId = currentTicket.ticketId;
fvc.tStatus = currentTicket.ticketStatus;
}
}
#end
Ok... so it seems to be a bug in XCode. I had originally copied the 2nd ViewController that I was trying to segue to and changed the class of it as well as some of the view components. I figured StoryBoard would be smart enough to reassign this view as its own. I was wrong. XCode didn't seem to like that. Starting from scratch with a new ViewController seems to fix everything and the segues are working correctly now. The exact same code works.
So if anyone is having this issue, make sure you didn't copy and paste a ViewController that you are trying to segue to. This will save you hours of headaches :-)
It probably had a reference to the same ViewController which is why whatever the last segue I setup was the only one working.
I know similar questions have been asked few times about how to add badge to tableviewcell, but I could not make it working
Basically what I want is to show user a simple notification either a red number at the right part of the table view cell or a rectangle or like native email app.
So I have tried both of this two source code TDbadgcell and DDbadgecell
Now the problem is I can not delegate them, I have to import their .h classes and call either one of the below functions in my table view
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
TDBadgedCell *cell = [[TDBadgedCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
or
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
DDBadgeViewCell *cell = (DDBadgeViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DDBadgeViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
But when I do that my tableView didSelectRowAtIndexPath: and (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender methods are not working, I can click the rows but they stay higlihted blue nothing happens also my arrow at the right side of the table is dissappears.
So how can I achieve to add a badge to table view cell row either with above source codes or any other methods?
EDIT:::
After putting NSLOG I can see that did select row is called but perform segue still does not work. Without adding any of the above code it works perfect.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//static NSString *CellIdentifier = #"MeetingCell";
static NSString *CellIdentifier = #"Cell";
DDBadgeViewCell *cell = (DDBadgeViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DDBadgeViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSString *description =#":";
NSString *name =#"";
NSString *fileStatus=#"";
name = [[self agenda] getFileNameWithSection:[indexPath section] Row:[indexPath row]];
description = [[self agenda] getFileDescriptionWithSection:[indexPath section] Row:[indexPath row]];
fileStatus = [[self agenda] getFileStatusWithFileName:name];
NSString * cellLabel = [NSString stringWithFormat:#" %# : %#",description,name];
//alloc row images
UIImage *docImage = [UIImage imageNamed:#"ICON - Word#2x.png"];
UIImage *xlsImage = [UIImage imageNamed:#"ICON - Excel#2x.png"];
// UIImage *picImage = [UIImage imageNamed:#"ICON - Image#2x.png"];
UIImage *pdfImage = [UIImage imageNamed:#"pdf icon#2x copy.png"];
UIImage *pptImage = [UIImage imageNamed:#"ICON - PPT#2x.png"];
//Determine what status to display for a file
//No need to that since wee use push notification
if ([fileStatus isEqualToString:#"new"]){
cellLabel = [NSString stringWithFormat:#"%# (%#)",cellLabel,#"New"];
cell.badgeText = [NSString stringWithFormat:#"Update"];
cell.badgeColor = [UIColor orangeColor];
}else if ([fileStatus isEqualToString:#"outdated"]){
cellLabel = [NSString stringWithFormat:#"%# (%#)",cellLabel,#"Outdated"];
cell.badgeText = [NSString stringWithFormat:#"Update"];
cell.badgeColor = [UIColor orangeColor];
}else if ([fileStatus isEqualToString:#"updated"]){
cellLabel = [NSString stringWithFormat:#"%# (%#)",cellLabel,#"Latest"];
}
UIFont *font1 = [UIFont fontWithName:#"Century Gothic" size:15.0f];
cell.textLabel.font=font1;
//if there is no file user can not tocuh the row
if ([name length]==0) {
cell.userInteractionEnabled = NO;
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.text = description;
}else{
//set cell title
cell.textLabel.text = cellLabel;
}
//set row images
if ([name rangeOfString:#"docx"].location != NSNotFound) {
cell.imageView.image= docImage;
}else if ([name rangeOfString:#"xlsx"].location != NSNotFound){
cell.imageView.image= xlsImage;
}
else if ([name rangeOfString:#"pdf"].location != NSNotFound){
cell.imageView.image= pdfImage;
}
else if ([name rangeOfString:#"ppt"].location != NSNotFound){
cell.imageView.image= pptImage;
}
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rounded corner box center#2x.png"]];
// At end of function, right before return cell
cell.textLabel.backgroundColor = [UIColor clearColor];
NSLog(#"%#",cell.textLabel.text);
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];.0
*/
NSLog(#"didselect row is called %d",indexPath.row);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[DBSession sharedSession] isLinked]) {
if([[segue identifier] isEqualToString:#"pushDocumentView"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSInteger section =[indexPath section];
NSInteger row = [indexPath row];
NSString *fileName = [[self agenda] getFileNameWithSection:section Row:row];
NSDictionary * agendaDic = [[[self agenda]revision] objectForKey:fileName];
NSString *fileStatus =[agendaDic objectForKey:#"status"];
DocumentViewController *docViewController = [segue destinationViewController];
//This will display on the Document Viewer
docViewController.fileName=fileName;
//This will determine remote or local copy display
docViewController.fileStatus=fileStatus;
}
}else {
[self displayError];
[self setWorking:NO];
}
}
Just called a perfromseguewith Identifier
because this is called - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender also when you call [self performSegueWithIdentifier:#"yoursegue" sender:self];
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];.0
*/
[self performSegueWithIdentifier:#"yoursegue" sender:self];
NSLog(#"didselect row is called %d",indexPath.row);
}
I've created a subclass of UITableViewCell. Until now, I've only been using cells which is "designed" in my storyboard where I can setup segues.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[super prepareForSegue:segue sender:sender];
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
if ([[segue identifier] isEqualToString:#"showNews"]) {
NewsViewController *newsViewController = [segue destinationViewController];
News *news = (News*)[self.fetchedResultsController objectAtIndexPath:indexPath];
newsViewController.news = news;
}
}
After I've created my subclass of UITableViewCell I'm no longer able to use the Storyboard to create segues for the custom cell, right? I've tried to create a cell in the storyboard and set its class to my custom class -- but then the cell is just blank when I run the App.
So instead I'm just alloc and init the custom cell in my tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"WSTableViewCell";
WSTableViewCell *cell = (WSTableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[WSTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
WSObject *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
[cell.titleLabel setText:item.title];
return cell;
}
Then in tableView:didSelectRowAtIndexPath I'm trying to creating the NewsViewController, setting the news item and push it to the navigationController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
News* news = [self.fetchedResultsController objectAtIndexPath:indexPath];
NewsViewController *newsViewController = [[NewsViewController alloc] init];
newsViewController.news = news;
[[self navigationController] pushViewController:newsViewController animated:YES];
}
But when I select a row my NewsViewController is not shown -- but instead I see a blank view with a black background. How can I deal with this? Is it possible to still use seques?
The problem I think is that you are using alloc-init to instantiate NewsViewController. That does not create your NewsViewController from storyboard. You have to use [UIStoryboard instantiateViewControllerWithIdentifier:(NSString *)identifier] to instantiate from storyboard.
However, I think the easier way is to call
[self performSegueWithIdentifier:#"showNews" sender:indexPath]
in your didSelectRowAtIndexPath. You have to change your prepareForSegue... a little bit.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = (NSIndexPath *)sender;
if ([[segue identifier] isEqualToString:#"showNews"]) {
NewsViewController *newsViewController = [segue destinationViewController];
News *news = (News*)[self.fetchedResultsController objectAtIndexPath:indexPath];
newsViewController.news = news;
}
}