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];
}
Related
I am developing iOS App.
In NavigationController, MainViewController has custom ContainerViewController(*YSLContainerViewController) which is composed of several UIViewController like the following code.
*YSLContainerViewController:https://github.com/y-hryk/YSLContainerViewController
MainViewController.m
#property (nonatomic) YSLContainerViewController *containerVC;
-(void)viewDidLoad
{
[super viewDidLoad];
CategoryViewController *categoryViewController[5];
categoryViewController[0] = [self.storyboard instantiateViewControllerWithIdentifier:#"EachCategoryView"];
categoryViewController[0].category = 0;
categoryViewController[0].title = #"apple";
categoryViewController[1] = [self.storyboard instantiateViewControllerWithIdentifier:#"EachCategoryView"];
categoryViewController[1].category = 1;
categoryViewController[1].title = #"orange";
categoryViewController[2] = [self.storyboard instantiateViewControllerWithIdentifier:#"EachCategoryView"];
categoryViewController[2].category = 2;
categoryViewController[2].title = #"strawberry";
categoryViewController[3] = [self.storyboard instantiateViewControllerWithIdentifier:#"EachCategoryView"];
categoryViewController[3].category = 3;
categoryViewController[3].title = #"cherry";
categoryViewController[4] = [self.storyboard instantiateViewControllerWithIdentifier:#"EachCategoryView"];
categoryViewController[4].category = 4;
categoryViewController[4].title = #"watermelon";
NSMutableArray *tabArray =
[NSMutableArray arrayWithObjects:categoryViewController[0], categoryViewController[1], categoryViewController[2], categoryViewController[3], categoryViewController[4], nil];
float navigationBarHeight = self.navigationController.navigationBar.frame.size.height;
_containerVC = [[YSLContainerViewController alloc]initWithControllers:tabArray
topBarHeight:navigationbarHeight
parentViewController:self];
_containerVC.delegate = self;
[self.view addSubview:_containerVC.view];
}
Each categoryViewController has TableView. When a cell in TableView is tapped, goes to detailViewController.
CategoryViewController.m
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
DetailViewController *vc = [storyBoard instantiateViewControllerWithIdentifier:#"DetailView"];
[self.navigationController pushViewController:vc animated:YES];
}
Each time I repeat the above transition like
"(tap tableViewCell in) categoryViewController in MainViewController → detailViewController → (go back to) MainViewController → (tap tableViewCell in) categoryViewController in MainViewController → detailViewController → (go back to) MainViewController..."
,my app are rapidly consuming the memory , it will not be reduced.
I guess in each of transition categoryViewControllers are not released from memory.
I tried the following method, but it does not work well.
DetailViewController.m
- (void)viewDidDisappear:(BOOL)animated
{
[self.navigationController popViewControllerAnimated:YES];
([self.navigationController popToRootViewControllerAnimated:YES];)
}
Could you tell me how to solve this problem?
I'm presenting a modal view controller using following code,
[[mInfo objectForKey: kNavigationController] presentViewController:(UIViewController*)modalViewControlr animated:YES completion:nil];
UITableView. On selecting a table view cell I want to navigate it to another UIView called navigatedView.
Is this can be done by embedding self (i.e,modalViewControlr) in navigation Controller and add view (i.e, navigatedView) to a view controller and present it?
for example,
// in modalViewControlr
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:self];
UIViewController *vc = [[UIViewController alloc]init];
[vc.view addSubview:self.navigatedView];
self.navigatedView.frame=vc.view.frame;
[passcodeNavigationController pushViewController: vc animated:YES];
//
}
Please help....
I prefer do it in this way which is easier to understand.
1.Embed the navigationController in AppDelegate:
ModalViewControlr *vc = [[ModalViewControlr alloc]init];
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = passcodeNavigationController;
2.Create a new class NavigatedViewControllerand custom the controller in viewDidLoad
Create an UIView call navigatedView
#property (nonatomic, strong) UIView *navigatedView;
-(void)viewDidLoad
{
[super viewDidLoad];
_navigatedView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.navigatedView.backgroundColor = [UIColor redColor];
[self.view addSubView:self.navigatedView];
}
3.Then return to modalViewControlr where you want to push from.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NavigatedViewController *vc = [[NavigatedViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
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);
}
First of all, sorry for my English.
I'm trying to do an app for iPad with a navigation controller which pushes view controllers when a button "Next" is selected. But I also want to have a popover, called from a button in the nav bar, that allows the user to "jump" from one view controller to another, pushing it with the tableView:didSelectRowAtIndexPath: and the pushViewController:animated: methods, but it's not working.
Summary:
Tab bar -> switches between FirstViewController and SecondViewController (works just fine)
Nav bar (button Next) -> switches between SecondViewController, FirstSlideController and SecondSlideController (it's also good)
Popover -> user selects SecondViewController, FirstSlideController or SecondSlideController (here's the problem!)
Codes:
AppDelegate
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *navigationController2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[navigationController1, navigationController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
TableViewController(popover)'s didSelectRowAtIndexPath method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0){
FirstSlideController *detailViewController = [[FirstSlideController alloc] initWithNibName:#"FirstSlideController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
else if(indexPath.row == 1){
SecondSlideController *detailViewController = [[SecondSlideController alloc] initWithNibName:#"SecondSlideController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
else{
SecondViewController *detailViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
}
SecondViewController (with delegate suggested by maros)
-(void) showPopover:(id) sender
{
TableViewController *PopoverView = [[TableViewController alloc] initWithNibName:#"TableViewController" bundle:nil];
self.popOver = [[UIPopoverController alloc] initWithContentViewController:PopoverView];
self.popOver.delegate = self;
[self.popOver presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItem permittedArrowDirections: UIPopoverArrowDirectionUp animated: YES];
}
I tried to print self.navigationController and it says it's null. I'd appreciate any help.
Thank you.
Presnented UIPopoverController is not pushed on the navigation stack in the view controller from which it was presented. It is a separate view controller.
Therefore the navigationController inside the popover is nil.
What I would recommend you is to create a delegate MyNavigationPopoverDelegate (the class that creates a popover (PopoverController). Pass it's instance as an delegate to the TableViewController.
After users clicks on some button inside popover, call delegate's method to processes button clicks (myNavigationPopover:(UIPopoverController*)popover clickedButtonAtIndex:(NSInteger)buttonIndex).
Then maybe dismiss delegate?
and finally change navigation however you want! :)
#protocol MyNavigationPopoverDelegate
- (void) myNavigationPopover:(UIPopoverController*)popover clickedButtonAtIndex:(NSInteger)buttonIndex;
#end
#interface TableViewController : UITableVieController // your viewController in popover
... // your code
#property (nonatomic, weak) NSObject <MyNavigationPopoverDelegate> * delegate;
... // your code
#end
#implementation TableViewController
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate myNavigationPopover:self clickedButtonAtIndex:indexPath.row];
}
...
#end
// defines that SecondViewController implements the delegate's method
#interface SecondViewController <MyNavigationPopoverDelegate> : UIViewController
// your code
#end
// code where you presenting popover
#implementation SecondViewController
// This is the method that is executed after your button press and it is responsible for presenting a popover
- (void) presentPopover{
...
myPopover.delegate = self; // setting the delegate
[myPopover presentPopoverFromXXX ...]; // however you present it
...
}
- (void) myNavigationPopover:(UIPopoverController*)popover clickedButtonAtIndex:(NSInteger)buttonIndex
{
UINavigationController *currentNavigationController = ; // get the navigation controller from the tab bar
if(buttonIndex == 0){
FirstSlideController *detailViewController = [[FirstSlideController alloc] initWithNibName:#"FirstSlideController" bundle:nil];
[currentNavigationController pushViewController:detailViewController animated:YES];
}
else if(buttonIndex == 1){
SecondSlideController *detailViewController = [[SecondSlideController alloc] initWithNibName:#"SecondSlideController" bundle:nil];
[currentNavigationController pushViewController:detailViewController animated:YES];
}
else{
SecondViewController *detailViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[currentNavigationController pushViewController:detailViewController animated:YES];
}
}
#end;
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.