delegate method from popover not called? - ios

edit: solved. see my comment why.. sorry this mess, not able to post an answer myself yet as a newbie..
iPad App: I have a table view and instantiate from the accessoryView a popover with another tableview. in the popover I want to select a cell and pass that index back to the rootView.
I implemented a protocol in PopoverController and conform RootViewController to it.
Why is that backPopover method in the root view not being called?
Any hint much appreciated!!
Edit: That storyboard reference points to a navigation controller. The popover itself works fine..
RootViewController.h
#import "PopoverViewController.h"
#interface rootViewController : UITableViewController <UIPopoverControllerDelegate, UITableViewDelegate, AddDelegate>
{
UIPopoverController *popOverController;
}
#property (nonatomic, retain) UIPopoverController *popOverController;
#property (nonatomic) PopoverContent *popoverContent;
RootView.m
-(void) backPopover:(int)index
{
NSLog(#"index sent:%i", index);
[popOverController dismissPopoverAnimated:YES];
}
// accessoryView Button
- (void) popOver:(UIButton*)paramSender
{
UITableViewCell *cell = (UITableViewCell*)paramSender.superview;
if (cell != nil)
{
//Table position for popover
UIButton *button = (UIButton *)cell.accessoryView;
if(![self popoverContent])
{
popoverContent = [[self storyboard]instantiateViewControllerWithIdentifier:#"PopoverContent"];
[popoverContent setDelegate:self];
popOverController = [[UIPopoverController alloc]initWithContentViewController:popoverContent];
popOverController.popoverContentSize = CGSizeMake(320.0, 600.0);
[popOverController setDelegate:self];
}
CGRect rect = button.frame;
[popOverController presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
PopoverController.h
#protocol AddDelegate <NSObject>
- (void)backPopover: (int)index;
#end
#property (nonatomic, weak) id <AddDelegate> delegate;
PopoverController.m
#synthesize delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate backPopover:indexPath.row];
}

Please try this.
MyViewController *viewController=[[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
UIPopoverController* aPopover = [[UIPopoverController alloc]
initWithContentViewController:popupController];

The problem was that storyboard reference, it actually pointed to a navigation controller. Above code works like a charm.

Related

UILabel never gets initialized in viewDidLoad

I have a UILabel in interface builder that I've connected to a property, but it's staying nil through the viewDidLoad on that view controller. I've been stepping through and as soon as the DetailViewController is initialized, the label property is there but it is nil and it never seems to be initialized.
It was working until I switched from using segues to doing pushViewController on the navigation controller.
// DetailsViewController.h
#import <UIKit/UIKit.h>
#import "TLitem.h"
#interface DetailsViewController : UIViewController
#property (nonatomic, strong) TLitem *entry;
#property (weak, nonatomic) IBOutlet UILabel *entryLabel;
#end
Then in a table view in another view controller:
// EntryListViewController.m
DetailsViewController *details = [[DetailsViewController alloc] init];
[details setEntry:entry];
[self.navigationController pushViewController:details animated:YES];
And in the viewDidLoad:
// DetailsViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor yellowColor]];
TLitem *entry = [self entry];
UILabel *label = [self entryLabel];
label.text = [entry valueForKey:#"text"];
[[DetailsViewController alloc] init] is not loading the view controller from the storyboard. It creates a new DetailsViewController, but nothing from IB will be connected. Look into -instantiateViewControllerWithIdentifier:
It will look something like
DetailsViewController *details = [self.storyboard instantiateViewControllerWithIdentifier:#"Some Storyboard Identifier You Create"];
details.entry = entry;
[self.navigationController pushViewController:details animated:YES];

Pushing new UIViewController from custom UIPopOver issue

Hello I'm using this library to show my PopOver which contain tableView with searchBar.
The problem is that one user try to select row from the tableView instead dismissing the popOver and displaying the slected row in hole screen I got this :
.
I've tried to use [self.parentViewController.navigationController ...] to push my view but didn't worked.
This is my popOver code (in MainVC.h):
-(IBAction)showPopoverSearch:(id)sender{
UIBarButtonItem *btn = (UIBarButtonItem *) sender;
NSInteger width = 600;
NSInteger height = 400;
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
searchVC.modalInPopover = NO;
UINavigationController* contentViewController = [[UINavigationController alloc] initWithRootViewController:searchVC];
popoverController = [[WYPopoverController alloc] initWithContentViewController:contentViewController];
popoverController.delegate = self;
//popoverController.passthroughViews = #[btn];
popoverController.popoverContentSize = CGSizeMake(width, height);
popoverController.popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
popoverController.wantsDefaultContentAppearance = YES;
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}
And this is the didSelctRow method (SearchViewController.m) :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"bundle:nil];
PostReaderViewController *postReaderView =
(PostReaderViewController *)
[storyboard instantiateViewControllerWithIdentifier:#"postReader"];
postReaderView.thePost = [_postsArray objectAtIndex:indexPath.row];
// if ([self.parentViewController.po .popoverController isPopoverVisible])
// [popoverController dismissPopoverAnimated:YES];
[self.navigationController pushViewController:postReaderView animated:YES];
}
To solve this issue I've passed the Navigation controller and popoverController from The parent View MainVC.h to child controller SearchViewController.h and then use those vars to dismiss my PopOvercontroller and push the new VC. Code snippet :
SearchView
#interface SearchViewController : UIViewController
#property (strong, nonatomic) WYPopoverController *parentPopoverVC;
#property (strong, nonatomic) UINavigationController *parentNavigationController;
#end
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
...
[self.parentPopoverVC dismissPopoverAnimated:YES];
[self.parentNavigationController pushViewController:postReaderView animated:YES];
}
MainVC.h
-(IBAction)showPopoverSearch:(id)sender{
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
[searchVC setParentPopoverVC:popoverController];
[searchVC setParentNavigationController:self.navigationController];
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}

Close popover by clicking UIButton in popover that created from program

I have a UIButton in tableViewCell that perform
-(IBAction)buttonClicked:(id)sender{
UIStoryboard *SB = [UIStoryboard storyboardWithName:#"ABC" bundle:nil];
UIViewController *VC = [SB instantiateViewControllerWithIdentifier:#"someID"];
popoverController = [[UIPopoverController alloc] initWithContentViewController:VC];
[popoverController setDelegate:self];
..............................
[popoverController presentPopoverFromRect:rect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
to popover a controller which consist of a UITextField and a UIButton. Now I'm going to pass back the string in UITextField from the popover controller by clicking the UIButton?
retain this view controller in in .h
UIViewController *VC;
change this
UIViewController *VC = [SB instantiateViewControllerWithIdentifier:#"someID"];
to
self.VC = [SB instantiateViewControllerWithIdentifier:#"someID"];
It will be deallocated from the memory when the .h object destroyed from memory.
When you dismiss the popover, still the last popover exists and you can access like
VC.yourTextField.text
When you present again on popover make sure to empty the text field to empty by setting #"".
If you are using a TableView with your custom TableViewCell you can create a method in your TableViewCell class for when you push your button:
CustomTableViewCell.h
#interface CustomTableViewCell : UITableViewCell
#property (nonatomic, strong) IBOutlet UIButton *cellButton;
#property (nonatomic, strong) IBOutlet UITextField *cellTextField;
- (NSString*)getText;
#end
CustomTableViewCell.m
- (NSString*)getText {
return self.cellTextField.text;
}
And in your CustomTableView class:
CustomTableView.m
in delegate method of your CustomTableView set self as delegate to your CustomTableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomTableViewCell *cellCustom = [tableView dequeueReusableCellWithIdentifier:#"CustomTableViewCell"];
...
[cellCustom.cellButton setTag:indexPath.row];
...
return cell;
}
And finally in your IBAction method of your button:
- (IBAction)pushButton:(id)sender{
UIButton *btn = (UIButton*)sender;
CustomTableViewCell *cellSelected = (CustomTableViewCell *)[self.tableView cellForRowAtIndexPath:btn.tag];
NSString *strWritten = [cellSelected getText];
NSLog(#"Text written: %#", strWritten);
}

UIPopoverController showing empty frame

So I am trying to display a UITableView inside a UIPopoverController using the piece of code shown below
vc = [[ActionsViewController alloc] init];
initWithContentViewController:vc];
actionsController = [[UIPopoverController alloc] initWithContentViewController:vc];
actionsController.delegate = self;
NSLog(#"Try to sho it ");
[actionsController presentPopoverFromBarButtonItem:(UIBarButtonItem*)sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
And this is ActionsViewController.m which is a subclass of UITableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray* list = [[NSMutableArray alloc] initWithCapacity:4];
self.actionList = list;
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 400.0);
[self.actionList addObject:#"Print as book"];
[self.actionList addObject:#"Print page"];
[self.actionList addObject:#"Save Page"];
[self.actionList addObject:#"Share"];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"in number of section");
return 1;
}
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString* lab = [self.actionList objectAtIndex:indexPath.row];
NSLog(#"here in there");
cell.textLabel.text = lab;
return cell;
}
- (NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [self.actionList count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.delegate != nil) {
[self.delegate actionSelected:indexPath.row];
}
}
The corresponding .h file
#import <UIKit/UIKit.h>
#protocol KLActionsViewControllerDelegate
- (void)actionSelected:(NSInteger)index;
#end
#interface KLActionsViewController : UITableViewController <UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, retain) NSMutableArray* actionList;
#property (nonatomic, assign) id<KLActionsViewControllerDelegate> delegate;
#end
Also, I don't think the functions cellForRowAtIndexPath and numberOfSectionsInTableView are getting called because I don't see any console output.
EDIT: This is what I see in the popover
:
In viewDidLoad I added self.tableView = [[UITableView alloc] init]
I guess, the problem would be in that line:
vc = [[ActionsViewController alloc] init];
if you have a NIB file, you should load the UIViewController with using it.
vc = [[ActionsViewController alloc] initWithNibName:#"ActionViewController" bundle:nil];
// the NibName must be the exact name of XIB file without extension.
OR/AND
you should set the popoverContentSize:
[actionController setPopoverContentSize:vc.view.frame.size];
I hope it helps a bit for you.
UPDATE:
it seems it is not an UIPopoverController problem, just a simple UITableViewController delegate issue.
in that line:
actionsController.delegate = self;
you should set that class as delegate which implements the UITableViewDelegate. basically it is the UITableViewController itself like
actionsController.delegate = actionController;
therefore you should not replace this in that case if you haven't implemented the delegate callback methods in the self which the new delegate class is. you simple steal the chance from the class which was really delegated to answer the callbacks, and in you new delegate class you don't answer the callbacks.
this would be the reason why you are seeing the empty table, without the datas.
You need to load the table view via (last line of viewdidload :
[self.tableView reloadData];
that will trigger the table view methods to action. Put a breakpoint in the various tableview methods particularly in -
(NSInteger)numberOfRowsInSection:(NSInteger)section
{
return [self.actionList count];
}
If this does not get called your tableview is not loaded.
UITableViewController is implicit set datasource and delegate, there is no need to set explicitly datasource and delegate.
Remove UITableViewDataSource,UITableViewDelegate from .h file
#import <UIKit/UIKit.h>
#protocol KLActionsViewControllerDelegate
- (void)actionSelected:(NSInteger)index;
#end
#interface KLActionsViewController : UITableViewController
#property (nonatomic, retain) NSMutableArray* actionList;
#property (nonatomic, assign) id<KLActionsViewControllerDelegate> delegate;
#end
and also remove this line **actionsController.delegate = self;
vc = [[ActionsViewController alloc] init];
actionsController = [[UIPopoverController alloc] initWithContentViewController:vc];
[actionsController presentPopoverFromBarButtonItem:(UIBarButtonItem*)sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

How can I dismissPopover from the other view?

I have a problem like this:
I have a root view which has a UIPopoverController and a button, when I click on that button, it present a tableView. My app display OK but now when I click in any row, the UIPopoverController still display and I want it dismiss.
Any help? Thanks!
This is my code:
ViewController.h
#import <UIKit/UIKit.h>
#import "UIPopoverIphone.h"
#import "TableViewController.h"
#interface ViewController : UIViewController <UIPopoverControllerDelegate, TableViewPopoverDelegate> {
TableViewController *popoverView;
IBOutlet UIButton *popButton;
UIPopoverController *pop;
}
#property (strong, nonatomic) UIPopoverController *pop;
+(void)hidePop;
#end
ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize pop;
-(void)dealloc {
[pop release];
[super dealloc];
}
-(IBAction)showPop {
popoverView = [[TableViewController alloc] init];
popoverView.delegate = self;
pop = [[UIPopoverController alloc] initWithContentViewController:popoverView];
[pop setPopoverContentSize:CGSizeMake(100, 200)];
[pop setDelegate:self];
[pop presentPopoverFromRect:popButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
-(void)hidePop {
[pop dismissPopoverAnimated:YES];
}
....
#end
TableViewController.h
#import <UIKit/UIKit.h>
#protocol TableViewPopoverDelegate <NSObject>
-(void) dismissPopover;
#end
#interface TableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *itemsArray;
UITableView *tableView;
id<TableViewPopoverDelegate> delegate;
}
#property (nonatomic, retain) NSArray *itemsArray;
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, assign) id<TableViewPopoverDelegate> delegate;
#end
TableViewController.m
#import "TableViewController.h"
#implementation TableViewController
#synthesize itemsArray;
#synthesize tableView;
-(void) dealloc {
[itemsArray release];
[tableView release];
[super dealloc];
}
-(void)loadView {
UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 200)];
self.view = mainView;
[mainView release];
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 100, 200) style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
}
....
#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];
[detailViewController release];
*/
NSLog(#"%#",[self.itemsArray objectAtIndex:indexPath.row]);
[self.delegate dismissPopover];
}
#end
With your current work flow, the ViewController have no connection with TableViewController. It looks like you are presenting the UITableViewController from the UIPopoverIphone not from the ViewController. So the delegate callback method dismissPopover needed to be implemented within the UIPopoverIphone class not the ViewController class. If you still want to dismiss the UIPopoverIphone from the ViewController, there are two options:
Using NSNotificationCenter: In the TableViewController, you can post a notification when you are ready to dismiss the popover. Then in the ViewController, you can observer that notification and dismiss the popover. In this scenario, no delegate is involved.
Setup the delegate callback from your UIPopoverIphone class and the ViewController class. So when you tap the button in the popover, it makes a callback to ViewController, you then dismiss the popover and prepare your TableViewController and present it. Here your TableViewController and the ViewController have a connection.
It appears that your root view ViewController doesn't correctly implement your TableViewPopoverDelegate. You've declared a method in that delegate called dismissPopover, but you haven't implemented it in ViewController.m.
In ViewController.m, change the hidePop function to:
-(void)dismissPopover {
[pop dismissPopoverAnimated:YES];
}
Popovers by default dismiss themselves when a tap is detected outside of their bounds.

Resources