Hide UIPopover after selecting row - iphone

I am new to iPad developer,
I am using UIPopover in my application, when i select any row in my popover, my popover is not getting hide it still in the view, it is getting hide when i touch outside anywhere on the screen.
I want to hide popover after user selects any row.
here is my code snippet,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
for(int index=0;index<=indexPath.row;index++)
{
UITableViewCell *cell =[tableView cellForRowAtIndexPath:indexPath];
lbl.text=cell.textLabel.text;
}
}
Logic: When i select any row of popover corresponding text will be fetched and gets stored into label.
Any help will be appreciated.
EDIT
UIViewController* popoverContent = [[UIViewController alloc]init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(110, 0, 500, 4)];
popoverPolicyNameTable = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 250, 200) style:UITableViewStylePlain];// size of tableview inside popover
[popoverPolicyNameTable setDelegate:(id<UITableViewDelegate>)self];
[popoverPolicyNameTable setDataSource:(id<UITableViewDataSource>)self];
[self.view addSubview:popoverPolicyNameTable];
[popoverPolicyNameTable release];
[popoverView addSubview:popoverPolicyNameTable];
popoverContent.view = popoverView;
popoverContent.contentSizeForViewInPopover = CGSizeMake(250, 200); //size of popover border
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[self.popoverController presentPopoverFromRect:CGRectMake(350,100, 35, 35) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; //size of arrow
[popoverContent release];
[popoverView release];

You need to implement something like this
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController1{
[self.popoverController dismissPopoverAnimated:YES];
self.popoverController=nil;
}

Add one variable inside the Class which is having your UITableView:
id parent;
Then properties and synthesize it:
#property(nonatomic, retain) id parent;
#synthesize parent;
Then where you are creating the object of this ViewController to add in Popovercontroller, do like this
myTableViewController.parent = myPopoverControllerObject;
Now in didSelectRowAtIndexPath:
[parent dismissPopoverAnimated:YES];
And you are done!!!

Use delegation and notify your delegate that the user selected an item in the list. The delegate will know how to dismiss the view controller.
This approach is better because it's container agnostic, and you can reuse your view controller outside a popover: for example, using navigation controller on iPhone

Make Popover controller as class member variable.
Then on clicking on table view click method call dismiss method of that popovercontoller.

Related

scrollsToTop not working with UIViewController containment

Using SDK 6.1, Xcode 4.6.1, I make a new project Master-Detail iOS App, ARC, no storyboards.
Then in the DetailViewController, in the viewDidLoad I add two UITableViews contained in UIViewControllers and make sure the second one is hidden like this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIViewController *lViewController1 = [[UIViewController alloc] init];
UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView1.scrollsToTop = YES;
[lViewController1.view addSubview: lTableView1];
lTableView1.dataSource = self;
[self.view addSubview: lViewController1.view];
[self addChildViewController: lViewController1];
UIViewController *lViewController2 = [[UIViewController alloc] init];
UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView2.scrollsToTop = YES;
[lViewController2.view addSubview: lTableView2];
lTableView2.dataSource = self;
[self.view addSubview: lViewController2.view];
[self addChildViewController: lViewController2];
// now hide the view in view controller 2
lViewController2.view.hidden = YES;
}
(I make sure the DetailViewController is a datasource that returns 100 rows of UITableViewCells with the textLabel.text set to #"hello")
The presence of the second view controller makes that scrollsToTop (tapping on the status bar) does not work anymore. If I do not use UIViewController containment and just add two UITableViews and set the second one to be hidden, scrollsToTop does work.
What am I doing wrong?
scrollsToTop only works on a single visible view. From the documentation:
This gesture works on a single visible scroll view; if there are multiple scroll views (for example, a date picker) with this property set, or if the delegate returns NO in scrollViewShouldScrollToTop:, UIScrollView ignores the request. After the scroll view scrolls to the top of the content view, it sends the delegate a scrollViewDidScrollToTop: message.
You could try calling [tableView setContentOffset:CGPointZero animated:YES] on each of your table (or scroll) views manually instead. To do this, implement the scrollViewShouldScrollToTop: method in the UIScrollViewDelegate protocol:
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
[lTableView1 setContentOffset:CGPointZero animated:YES];
[lTableView2 setContentOffset:CGPointZero animated:YES];
return NO;
}
You can only set 1 ScrollView per ViewController with property .scrollsToTop = YES.
If you set 2 scrollview.scrollsTopTop = YES, it will simply stop functioning.
ie: your sample project (DetailViewController.m) update following lines,
line48: lTableView1.scrollsToTop = YES;
line56: lTableView2.scrollsToTop = NO;
then, scrollsToTop works correctly. If there are more than 1 scrollview you wish to concurrently setScrollsToTop, keep digging around. good luck!
I am currently experimenting with your project. When
lViewController2.view.hidden = YES;
is replaced with
lTableView2.hidden = YES;
then the scrolling works, even with controller containment.
I tried to insert a view between the controller's view and the table and then hide this view, but the table was not scrolling.
I tried to hide the controller by experimenting with shouldAutomaticallyForwardAppearanceMethods but the table was not scrolling.
Result: From my experiments, only one scroll view must be visible in the view hierarchy and the hidden property of the parent views is not checked out. hidden must be set to NO on all other scroll views, not their parent views.
After testing several options and various hits and try I finally settled to one final solution, i.e. setBounds: of scrollView (that is tableView in your case) and it works good. You'll have to put extra effort for animation although.
CGRect frame = scrollView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
[scrollView setBounds:frame];
By the way in your case, try returning YES to
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;
Although if not defined, assumes YES.
I have used this and now it works fine.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIViewController *lViewController1 = [[UIViewController alloc] init];
UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView1.scrollsToTop = YES;
[lViewController1.view addSubview: lTableView1];
lTableView1.dataSource = self;
[self.view addSubview: lViewController1.view];
[self addChildViewController: lViewController1];
lTableView1.tag=1;
UIViewController *lViewController2 = [[UIViewController alloc] init];
UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame];
lTableView2.scrollsToTop = NO;
[lViewController2.view addSubview: lTableView2];
lTableView2.dataSource = self;
[self.view addSubview: lViewController2.view];
[self addChildViewController: lViewController2];
lTableView2.tag=2;
// now hide the view in view controller 2
lViewController2.view.hidden = YES;
}
- (NSUInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSUInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const kCellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:#"hello %d %d",indexPath.row, tableView.tag];
return cell;
}

Create a Popover view from UIButton which shows a TableView with the list on inApp purchase items

I have created a popover and it is showing me my in app purchase items list. I have implemente classes used by Ray Wenderlich tutorials. But something is definitely wrong. My problems are:
Popover is being shown with Max height. (I don't want it to be shown with MAX height of iPad)
If i close popover by clicking some where else, and again click the button to show popover, It opens popover but doesn't load the view in it.
Please help guys I'm in real confusion/problem.
I am displaying popOverViewController from SearchDelivery.xib that contains tableView & Search bar in it. In other .xib file I am showing popover on button click code is below that can help you .
-(IBAction)deliveryList:(UIButton*)sender
{
SearchDelivery *searchDel1=[[SearchDelivery alloc]initWithNibName:#"SearchDelivery" bundle:nil];
[searchDel1 loadDelAdd:self.arr];
self.searchDel=searchDel1;
[searchDel1 release];
UIPopoverController *popover=[[UIPopoverController alloc]initWithContentViewController:searchDel];
popover.delegate=self;
CGRect rect=searchDel.view.frame;
popover.popoverContentSize=rect.size;
self.popOverController=popover;
[popover release];
[popOverController presentPopoverFromRect:self.view.frame inView:self.view permittedArrowDirections:0 animated:YES];
}
popoverContentSize Property is used to set width and height of popOverView.
Try the below given code
-(IBAction)setData1:(id)sender
{
UIViewController *popoverContent=[[UIViewController alloc] init];
UITableView *tableView1=[[UITableView alloc] initWithFrame:CGRectMake(265, 680, 0, 0) style:UITableViewStylePlain];
UIView *popoverView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 300)];
popoverView.backgroundColor=[UIColor whiteColor];
popoverContent.view=popoverView;
popoverContent.contentSizeForViewInPopover=CGSizeMake(200, 420);
popoverContent.view=tableView1; //Use this if you like to add a tableView in popover
tableView1.delegate=self;
tableView1.dataSource=self;
self.popoverController=[[UIPopoverController alloc] initWithContentViewController:popoverContent];
[self.popoverController presentPopoverFromRect:CGRectMake(400, 675, 1000, 1000) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}

popOver table view

In my project , On clicking the button the string present in the button Action method should store in popover table view cell.
I cam able to store a single sting , to the first cell ....
And now my problem is i had Four buttons each button action consists of 4 strings , and now the should at a time to the popover table view ,,,
#import "SecondDetailViewController.h"
-(IBAction)viewButtonPressed:(id)sender
{
[super viewDidUnload];
//create the view controller from nib
self.tablePopoverController = [[[TablePopoverController alloc]
initWithNibName:#"TablePopover"
bundle:[NSBundle mainBundle]] autorelease];
////-------------------------------
myArray = [[NSMutableArray alloc] initinitWithObjects:myString,myString2,myString3,myString4,myString5,myString6,nil];
tablePopoverController.getingOrder = myArray ;
NSLog(#"table popo %#",myArray);
tablePopoverController.contentSizeForViewInPopover = CGSizeMake(250, 250);
//create a popover controller
self.popoverController = [[[UIPopoverController alloc]
initWithContentViewController:tablePopoverController] autorelease];
//present the popover view non-modal with a
//refrence to the button pressed within the current view
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
-(IBAction)orderButtonPressed
{
myString = staterlable1.text;
[myArray addObject:myString];
NSLog(#"myArray%#",myString);
}
-(IBAction)orderButton2Pressed
{
myString2 = staterlable2.text;
NSLog(#"myArray%#",myString2);
[myArray addObject:myString2];
}
-(IBAction)orderButton3Pressed
{
myString3 = staterlable3.text;
[myArray addObject:myString3];
NSLog(#"myArray%#",myString3);
}
-(IBAction)orderButton4Pressed
{
myString4 = staterlable4.text;
[myArray addObject:myString4];
NSLog(#"myArray%#",myString4);
}
-(IBAction)orderButton5Pressed
{
myString5 = staterlable5.text;
[myArray addObject:myString5];
NSLog(#"myArray%#",myString5);
}
-(IBAction)orderButton6Pressed
{
myString6 = staterlable6.text;
[myArray addObject:myString6];
NSLog(#"myArray%#",myString6);
my Problem Is after clicking these buttons the myString1 - to - myString6 NSString objects Should Store into NSMutableArray so That i will display all the strings in the TableViewPopOverController which will popover when clicking the another button in the second detailViewController........
thanks in Advance......
The usual way to do this is to embed TablePopoverController in a UINavigationController. Then, in TablePopoverController when handling tableView:tableView didSelectRowAtIndexPath:indexPath push detailViewController into the UINavigationController.
For example, you could build Controller structure the following way (based on your example):
//create a popover controller
self.popoverController = [[[UIPopoverController alloc] initWithContentViewController:[[[UINavigationController alloc] initWithRootViewController:initWithContentViewController:tablePopoverController] autorelease]] autorelease];
It is similar to your popover-creation code, put inserts a UINavigationController under the popover. Now, in TablePopoverController you should handle row selections the usual way with a UINavigationController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
DetaiViewController *detail = [[DetaiViewController alloc] init];
/* Configure detail using indexpath here indexPath
...
*/
[self.navigationController pushViewController:detail animated:YES];
}
This will work as expected (by pushing the new view into the UINavigationController) because we set controller structure with a UINavigationController.

Pushing UIViewController onto a UINavigationController

The other day I asked about using a UINavigationController as a child of a UIViewController. I got that working via the answer. Now what I'm trying to do is push a controller onto the nav stack. When a table cell is touched, I do the following:
- (void) showSetup {
NSLog(#"Showing Setup");
SetupViewController *controller = [[SetupViewController alloc]initWithNibName:#"SetupViewController" bundle:nil];
self.setupViewController = controller;
self.setupViewController.title = #"Setup";
[self.navigationController pushViewController:self.setupViewController animated:YES];
[controller release];
}
I can see the log statement in my console, but the view never changes. Am I missing something?
Hmmm, well it's a bit tricky without knowing the details of your implementation -- I assumed that you implemented your navigation controller as in the linked article. Also although you give no details it sounds like you've added a table view controller somewhere along the line, so I made the UIViewController conform to the UITableView protocols to handle everything in one place:
#interface SOViewController : UIViewController<UITableViewDelegate,UITableViewDataSource > {
UINavigationController* navController;
}
- (IBAction) pushMe:(id)sender;
#end
I dropped a button on the SOViewController's view in IB and wired the pushMe: action to it. I also created another UIViewController-based class called JunkController and dropped a "Junk" label on it's view in IB -- that's all I did in IB. In the SOViewController's viewDidLoad:
navController = [[[UINavigationController alloc] init] retain];
navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
navController.toolbarHidden = YES;
UITableViewController* tvController = [[UITableViewController alloc] init];
UITableView* tv = [[UITableView alloc] init];
tvController.tableView = tv;
tv.delegate = self;
tv.dataSource = self;
[navController setViewControllers:[NSArray arrayWithObject:tvController]];
In the pushMe: action implementation:
[self presentModalViewController:navController animated:YES];
Implemented the tableView delegate and datasource methods; for selection:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"row selected");
JunkController* junk = [[JunkController alloc] initWithNibName:#"junkcontroller" bundle:nil];
[navController pushViewController:junk animated:YES];
[junk release];
}
This should yield an app that surfaces a screen with a "Push me" button. When that button is pressed you should get an animated modal navigation-based table view -- mine had one row in it that contained a label "select me". Touching this row should animate the junk controller into view.
There is no need to make setupViewController a declared property in this view controller. Also, I could be mistaken but I thought "controller" was a reserved name in Cocoa, I'd change that name. So make sure you have registered with the UITableViewDelegate and use - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath to hook into and push your new view controller as follows:
SetupViewController *detailViewController = [[SetupViewController alloc] initWithNibName:#"SetupViewController" bundle:nil];
detailViewController.title = #"Setup";
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
Goodluck!

Showing Master/Detail UITableView inside UIPopOverController

I have a UIPopOverController that shows a UIViewController with a UITableview in its view. The cells in the table have a detailedView, but whenever that view gets pushed, the PopOverController increases in size, and I am left with all this white space inside it.
Question is this: Can anyone show me how I can have a Master/Detail UITableview show inside a PopOverController whilst preserving its dimensions?
Some of my code if it helps you:
//Creating the PopOver with the UIViewController
addTaskViewController = [[AddTaskViewController alloc] initWithNibName:#"AddTaskViewController" bundle:nil];
UINavigationController *addTaskNavController = [[UINavigationController alloc] initWithRootViewController:addTaskViewController];
UIPopoverController *addTaskPopOver = [[UIPopoverController alloc] initWithContentViewController:addTaskNavController];
self.addTaskPopOverController = addTaskPopOver;
addTaskPopOverController.delegate = self;
//...neccessary releases...
//Showing the popover when a button is pressed
- (void) addTasksButtonPressed:(id)sender {
//Display the Popover containing a view from AddTaskViewController
[self.addTaskPopOverController setPopoverContentSize:CGSizeMake(400, 700)];
[addTaskPopOverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
You should set the detail view controller's contentSizeForViewInPopover property to the same value as the parent controller.