Navigation inside a UIPopoverController - ios

I have a UIPopoverController that consist of table view. This pop over controller displayed well, and I already set the delegate didSelectRowAtIndexPath just fine.
Right now, I want to make some transition into "detail view controller" based on table item clicked. Then on destination view, it has back button like a pushViewController but it doesn't work well. It wont navigate into detail view Controller. This is my didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailSummaryViewController *detailVC = [[DetailSummaryViewController alloc] initWithNibName:#"DetailSummaryViewController" bundle:nil];
[self.navigationController pushViewController:detailVC animated:YES];
}
This is my popupover method
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
CalendarCell *cell = (CalendarCell *)[collectionView cellForItemAtIndexPath:indexPath];
UIPopoverController *popC = [[UIPopoverController alloc] initWithContentViewController:[SummaryViewController new]];
[popC setPopoverContentSize:CGSizeMake(320, 400)];
[self setPop:popC];
[[self pop] presentPopoverFromRect:[cell frame]
inView:collectionView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
Those navigation wont work, but if I NSLog-ing selected index it works nicely. Is there some step at setting up navigation that I am missed?

when you create the UIPopoverController, instead of setting the MyViewController inside the UIPopoverController, you should set a UINavigationController
UINavigationController *insidePopoverNavigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
popoverController = [[UIPopoverController alloc] initWithContentViewController:insidePopoverNavigationController];
......
[popoverController presentPopoverFromRect:... etc];

You donot have a Navigation Controller in your popover controller, so the method self.navigationController pushViewController wont work. Try this below:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
CalendarCell *cell = (CalendarCell *)[collectionView cellForItemAtIndexPath:indexPath];
UINavigationController *insidePopoverNavigationController = [[UINavigationController alloc] initWithRootViewController:[SummaryViewController new]];
UIPopoverController *popC = [[UIPopoverController alloc] initWithContentViewController:insidePopoverNavigationController];
[popC setPopoverContentSize:CGSizeMake(320, 400)];
[self setPop:popC];
[[self pop] presentPopoverFromRect:[cell frame]
inView:collectionView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
Additional Credits: Raica Dumitru Cristian

Related

Programmatically Push VC on Table Row Tap

I am attempting to do a onRowTap method without using a storyboard segue to push to a new View Controller, however when tapped it only displays information from the first item of the indexPath no matter which row is tapped. Here is my code:
- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
NSInteger row = [[self tableView].indexPathForSelectedRow row];
NSDictionary *insta = [self.instaPics objectAtIndex:row];
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"Main"
bundle:nil];
InstaPicDetailViewController* vc = [sb instantiateViewControllerWithIdentifier:#"InstagramDetail"];
vc.detailItem = insta;
[self.navigationController pushViewController:vc animated:YES];
}
Move your deslectRowAtIndexPath message call below the assignment of your row variable:
NSInteger row = [[self tableView].indexPathForSelectedRow row];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];

deselecting UITableViewCell

I'm calling a view controller from a table view. When I return back the caller view the table cell that I pressed before stays selected so that I couldn't select it again before selecting another cell.
I've added deselectRowAtIndexPath method like below but it didn't worked.
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *ctrl = [storyboard instantiateViewControllerWithIdentifier:#"node"];
self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationItem.hidesBackButton = NO;
[self.navigationController pushViewController:ctrl animated:YES];
}
didDeselectRowAtIndexPath is only called AFTER your row has already been deselected, so your call to deselectRowAtIndexPath is useless. Simply place this in your didSelectRowAtIndexPath to deselect it after tapping on it:
[tableView deselectRowAtIndexPath:indexPath animated:YES];
If you are using UITableViewController there is a property for that. You can set it in you -viewDidLoad method of your UITableViewController subclass:
self.clearsSelectionOnViewWillAppear = YES;
Otherwise you have to do it manually. Just deselect it in -viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow];
}
The method you have shown is not necessary for this.
You are committing an error on the delegate method. When you select a row in a tableView, is called:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
So your code should be in this method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *ctrl = [storyboard instantiateViewControllerWithIdentifier:#"node"];
self.navigationController.navigationBarHidden = NO;
self.navigationController.navigationItem.hidesBackButton = NO;
[self.navigationController pushViewController:ctrl animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
So now that you call deselectRowAtIndexPath is called also:
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath;
But in your case, you don't need to implement something in this method.

Detail View Controller from Table View Controller WITHOUT Storyboard?

I have a tableview in a controller that shows receipts and their image, date created, etc.
I made it so when the user taps a cell, it goes to DetailViewController. Using this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
}
I'd like to pass the image, date, category, etc, to my new view in a UIImageView, textView, etc.
This is the code for my Table in the first controller:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Receipt *receipt = [self.receiptsArray objectAtIndex:indexPath.row];
ReceiptCategory *category = receipt.relationshipToCategory;
ReceiptImage *image = receipt.relationshipToImage;
cell.textLabel.text = category.receiptCategory;
cell.detailTextLabel.text = receipt.date.description;
if(self.imageCache.count <= indexPath.row) {
[self.imageCache addObject:[UIImage imageWithData:image.data]];
}
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
imageView.image = [self.imageCache objectAtIndex:indexPath.row];
cell.imageView.image = imageView.image;
return cell;
}
How do I pass this data? I have searched around for two days now and all solutions include a storyboard, which I am not using.
You should get reference to your receipt in didSelectRowAtIndexPath: and pass it to ReceiptDetailViewController. I assume you have property to accept the data in ReceiptDetailViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get reference to receipt
Receipt *receipt = [self.receiptsArray objectAtIndex:indexPath.row];
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
// Pass data to controller
controller.receipt = receipt;
[self.navigationController pushViewController:controller animated:YES];
}
It this example you should create property in ReceiptDetailViewController.h file:
#property(nonatomic, strong) Receipt *receipt;
Now you can use it in your ReceiptDetailViewController object.
You should just use Table View Delegate Method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
There you can retrieve the selected receipt and pass the data to the detail view like that:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
Receipt *selectedReceipt = [self.receiptsArray objectAtIndex:indexPath.row];
controller.receipt = selectedReceipt;
[self.navigationController pushViewController:controller animated:YES];
}
You can create a custom class for your detailed view controller and create an object of the same when the user clicks on any cell.
Something like this
DetailViewControllerClass *newObject = [[DetailViewControllerClass alloc] init];
newObject.data1 = dataToBeSent ; //assign data
You should make an object of Receipt in ReceiptDetailViewController and make the property nonatomic and strong Than in tour view controller Write this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Receipt *receipt = [self.receiptsArray objectAtIndex:indexPath.row];
ReceiptDetailViewController *controller = [[ReceiptDetailViewController alloc] initWithNibName:#"ReceiptDetailViewController" bundle:nil];
controller.objReceipt= receipt;
[self.navigationController pushViewController:controller animated:YES];
}

iOS: Not able to navigate to another view controller

I have a main view controller in which I have a UITableView. And in the didSelectRowAtIndexPath(), I am initializing a new view controller and trying to navigate to it. Below is my code. But I am unable to go to the other view controller.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SubViewController *subView = [[SubViewController alloc] init];
[subView setData:[[sources getSubCategories] objectAtIndex:[indexPath row]]];
[[self navigationController]pushViewController:subView animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Try this one Adding Go through the initwith Nibname...
SubViewController *subView = [[SubViewController alloc]initWithNibName:#"SubViewController" bundle:Nil];
// Puishing a view controller in naviogation bar.
[self.navigationController pushViewController:subView animated:YES];
Try this one might be helpful to you...

how to make pushViewController: work in the following case?

I have a Navigation Controller embedded in a RootViewController. The elements present inside the RootViewController are a segmented control and a UIView. As the different segments are selected, the UIView displays a corresponding ViewController.
Now each of the ViewController being displayed in the UIView is a UITableViewController.
I need to display the table values as per the segment selections. And also if any of the row of the table is selected, it has to move to a newer ViewController with the detailed view.
I am able to display the UITableViewControllers as per the segment change. However, when i click on the row of the table, the newer ViewController that comes up is blank (Black Screen) even though I have created the particular ViewController in the Storyboard and set up an identifier as well.
Code for the Segmented Control change in ViewController.m
- (void)segmentedControlChangedValue:(UISegmentedControl*)segmentedControl {
int selIndex = segmentedControl.selectedIndex;
if (selIndex == 0)
{
aTable = [[aTableViewController alloc] init];
aTable.view.frame = self.myView.bounds;
[self.myView addSubview:aTable.view];
[self addChildViewController:aTable];
}
if (selIndex == 1)
{
bTable = [[bTableViewController alloc] init];
bTable.view.frame = self.myView.bounds;
[self.myView addSubview:bTable.view];
[self addChildViewController:bTable];
}
if (selIndex == 2)
{
//NSLog (#"Well you selected a 3rd option");
}}
Code for the didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
newDetailController* newController = [self.storyboard instantiateViewControllerWithIdentifier:#"Detail"];
newController = [[newDetailController alloc] init];
[[self navigationController] pushViewController:newController animated:YES];}
The pushViewController pushes an empty view for me even though I have specified the ViewController to use in the Storyboard design and also using an identifier.
Please help me in understanding what I must do to rectify this error.
UPDATE - The above problem has been resolved.
The problem I face now is being unable to access the data in the newViewController.
I pass the data to the newViewController as follows:
Create a class named newClass which contains all the elements I want to pass across.
Create a NSMutableArray "newObjects" in the firstViewController.
Create each newClass object at this method.
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"Cell";
customBigTableCell *cell = (customBigTableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[customBigTableCell alloc] init];
}
cell.name.text = [object objectForKey:#"objName"];
newClass* newObj = [[newClass alloc] init];
newObj.objName = cell.name.text;
[newObjects addObject:newObj];
return cell;
}
Pls pardon me .. for the indenting with the code block is messed up...
Also the PFObject is cos i use Parse for database.
Add the created object to the newObjects array.
In the - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method, this is the code
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]];
newDetailController* newController = [storyboard instantiateViewControllerWithIdentifier:#"UpcomingDetail"];
obj = [[newClass alloc] init];
NSIndexPath* path = [self.tableView indexPathForSelectedRow];
obj = [newObjects objectAtIndex:path.row];
NSLog(#"Row selected is %ld", (long)path.row); //this returns the correct row selected
NSLog(#"Movie selected is %#", [[newObjects objectAtIndex:path.row] objName]);//however this is not the right one as per the cellForRowAtIndexPath method.
[newController setNewObj:obj];
[[self navigationController] pushViewController:newController animated:YES];
}
When I run this code, the row is selected correctly. However I dont get the corresponding row in the database. The array gets stored with redundant data.
You need to get rid of that middle line:
newController = [[newDetailController alloc] init];
That just redefines newController (as an empty controller with no view set up), which you defined in the first line.

Resources