I am trying to show a modal view controller(view1) inside another viewController(view2)
View1
#interface View1 : UIViewController
#property (weak) id delegate;
- (IBAction)closeButtonTapped:(id)sender ;
#end
#protocol View1Delegates <NSObject>
#optional
- (void)viewControllerDidFinish: (View1 *) viewController;
#end
#implementation View1
-(void)dealloc
{
}
- (void)viewDidLoad {
}
- (IBAction)closeButtonTapped:(id)sender {
[self.delegate viewControllerDidFinish:self];
}
#end
And I use the following code inside view2
#implementation View2
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)onOpenView1Tapped:(id)sender
{
View1 *view1 = [self.storyboard instantiateViewControllerWithIdentifier:#"view1"];
NavViewController *nav = [[NavViewController alloc] initWithRootViewController:view1];
view1.delegate = self;
[self presentViewController:nav animated:NO completion:NULL];
}
- (void) viewControllerDidFinish: (View1 *) viewController
{
[self dismissViewControllerAnimated:NO completion:NULL];
}
The problem is that the NavViewController calls its dealloc method but view1 never calls it at all after dismiss. This means that view1 will remains in memory .
How can I free the memory of view1 ?
Related
I have two VC. I need to call the delegate function when the 2nd VC is dismissed.
In my 1st VC or main VC I have given the following code in .h file.
#interface FirstVC : ....<SecondVCDelegate>
-(void)didDismissViewController:(UIViewController*)vc;
But for some reason SecondVCDelegate in this is not detected.
while presenting 2nd VC from first I have given this .m file of 1st VC.
SecondVC *optionsVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondVC"];
optionsVC.delegate = self;
optionsVC.view.backgroundColor = [UIColor blackColor];
optionsVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:optionsVC animated:YES completion:^{}];
in 2nd VC .h file
#protocol SecondVCDelegate <NSObject>
- (void)didDismissViewController:(UIViewController*)vc;
#end
#interface SecondVC : ...
#property (nonatomic) id<SecondVCDelegate> delegate;
#end
in 2nd VC .m file I have dismissed using the below code
[self dismissViewControllerAnimated:YES completion:nil];
Could you point out what I did wrong with possible explanation. Thanks in advance.
This is the working code on xcode 9 :
ViewController.m :
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController () <SecondVCDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)action:(id)sender {
SecondViewController *optionsVC = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
optionsVC.delegate = self;
optionsVC.view.backgroundColor = [UIColor blackColor];
optionsVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:optionsVC animated:YES completion:nil];
}
-(void) didDismissViewController:(UIViewController *)vc{
NSLog(#"working controller : %#", vc);
}
#end
SecondViewController.h :
#import <UIKit/UIKit.h>
#protocol SecondVCDelegate <NSObject>
- (void)didDismissViewController:(UIViewController*)vc;
#end
#interface SecondViewController : UIViewController
#property (weak, nonatomic) id<SecondVCDelegate> delegate;
#end
SecondViewController.m :
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)didmissAction:(id)sender {
[self dismissViewControllerAnimated:true completion:^{
[_delegate didDismissViewController:self];
}];
}
#end
On your 2nd VC .m do like this
First synthesize delegate below implementation
#synthesize delegate;
after that use it on viewController dismiss:
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate didDismissViewController: self];
}];
ContainerViewController delegate the method -delegateMethod to ChildViewController.
But in the following code, -delegateMethod is not called.
I think it's because _childViewController has been released.
How do I fix it to make run -delegateMethod?
ContainerViewController.h
#protocol ContainerViewDelegate <NSObject>
- (void)delegateMethod;
#end
#interface ContainerViewController : UIViewController
#property (nonatomic, assign) id<ContainerViewDelegate> delegate;
#end
ContainerViewController.m
#interface ContainerViewController () {
ChildViewController *_childViewController;
}
//...
- (void)viewDidLoad
{
_childViewController = [[WeeklyViewController alloc]init];
[self addChildViewController:_childViewController];
[self.view addSubview:_childViewController.view];
[_childViewController didMoveToParentViewController:self];
}
- (void)buttonAction {
[self.delegate delegateMethod];
}
ChildViewController.m
#interface ChildViewController () <ContainerViewDelegate>
//...
- (void)delegateMethod {
NSLog(#"succeed!");
}
You never set the delegate, so self.delegate will be nil. You should do this,
- (void)viewDidLoad
{
_childViewController = [[WeeklyViewController alloc]init];
self.delegate = _childViewController;
[self addChildViewController:_childViewController];
[self.view addSubview:_childViewController.view];
[_childViewController didMoveToParentViewController:self];
}
I have a view controller which is my HomeViewController, and I have a modal segue between them.
This is the HomeViewController:
import "HomePageViewController.h"
#import "CreatePageViewController.h"
#import "StackTableViewController.h"
#import "PopUpView.h"
#interface HomePageViewController ()
#property (nonatomic, strong) IBOutlet UIButton *toggleButton;
#property (nonatomic, strong) CreatePageViewController *modalTest;
#property (nonatomic, strong) PopUpView *popup;
#end
#implementation HomePageViewController
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
-(void)viewDidLoad {
[super viewDidLoad];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:Nil];
_modalTest = [storyboard instantiateViewControllerWithIdentifier:#"ModalTest"];
[_toggleButton addTarget:self action:#selector(go) forControlEvents:UIControlEventTouchUpInside];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(hide) name:#"HideAFPopup" object:nil];
}
-(void)go {
_popup = [PopUpView popupWithView:_modalTest.view];
[_popup show];
}
-(void)hide {
[_popup hide];
}
- (IBAction)pushToNextViewController:(id)sender {
StackTableViewController *vc = [[StackTableViewController alloc]init];
[self presentModalViewController:vc animated:YES];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
I want to add a navigation controller to StackTableViewController...its just a table view and I want it to have a navigation controller, how should I do this?
Also, why xcode tells me my modal method presentModalViewController is deprecated?
tnx
Create a new instance of UINavigationController, with your StackTableViewController as its rootViewController. Then present the navigation controller:
- (IBAction)pushToNextViewController:(id)sender {
StackTableViewController *vc = [[StackTableViewController alloc]init];
UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentViewController:navCtrl animated:YES completion:nil];
}
Note that presentModalViewController:animated: is deprecated because it has been replaced by presentViewController:animated:completion:.
First of all, apologize for my english.
I'm a beginner in iOS development, I'm doing an App which have 3 viewControllers (MainViewController, CenterViewController and ActionViewController).
In a first VC (MainVC) I have a button, this button takes you to the CenterVC using UIModalTransitionStylePartialCurl.
In a second VC (CenterVC) I have and other button that takes you to the ActionVC, but here is a problem. I can see the ActionVC but this VC is presented bellow MainVC with the Curl effect.
I have tried to solve using this code inside of the IBAction in a CenterVC:
- (IBAction)actionReveal:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
ActionViewController *actionVC = [[ActionViewController alloc]initWithNibName:#"ActionViewController" bundle:nil];
[self presentViewController:actionVC animated:YES completion:^{}];
}];
}
Please, anyone can help me with the problem?
Try using this using navigation controller :
[UIView beginAnimations:#"animation" context:nil];
//put this instance to navigation controller
[self.navigationController pushViewController: detailController animated:NO];
// Animate the navigation controller
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.navigationController.view cache:NO];
// Set animation time
[UIView setAnimationDelay:0.01];
[UIView setAnimationDuration:0.3];
// Commit animation
[UIView commitAnimations];
I have solved the problem. Write the solution here in case anyone has had the same problem.
mainVC.h:
#import <UIKit/UIKit.h>
#import "OXDcurlViewController.h"
#interface OXDmainViewController : UIViewController <OXDcurlViewControllerDelegate>
#property (strong, nonatomic) IBOutlet UIButton *curlButton;
- (IBAction)curlReveal:(id)sender;
#end
mainVC.m:
#import "OXDmainViewController.h"
#import "OXDcurlViewController.h"
#import "OXDsecondViewController.h"
#interface OXDmainViewController ()
#end
#implementation OXDmainViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)curlReveal:(id)sender {
OXDcurlViewController *curlVC = [[OXDcurlViewController alloc]initWithNibName:#"OXDcurlViewController" bundle:nil];
curlVC.modalTransitionStyle = UIModalTransitionStylePartialCurl;
curlVC.delegate = self;
[self presentViewController:curlVC animated:YES completion:^{}];
}
-(void)presentSecondVC{
OXDsecondViewController *secondVC = [[OXDsecondViewController alloc]initWithNibName:#"OXDsecondViewController" bundle:nil];
secondVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:secondVC animated:YES completion:^{}];
}
#end
curlVC.h:
#import <UIKit/UIKit.h>
#protocol OXDcurlViewControllerDelegate <NSObject>
#optional
-(void)presentSecondVC;
#end
#interface OXDcurlViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *actionButton;
#property (nonatomic, weak) id<OXDcurlViewControllerDelegate> delegate;
- (IBAction)actionReveal:(id)sender;
#end
curlVC.m:
#import "OXDcurlViewController.h"
#import "OXDsecondViewController.h"
#interface OXDcurlViewController ()
#end
#implementation OXDcurlViewController
#synthesize delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionReveal:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate presentSecondVC];
}];
}
#end
Thanks to all who have helped me.
David Álvarez Medina
NavigationController.h
#import <UIKit/UIKit.h>
#protocol NavigationControllerDelegate;
#interface NavigationController : UINavigationController<UINavigationControllerDelegate>
#property (nonatomic , assign)id<NavigationControllerDelegate , UINavigationControllerDelegate> delegate;
-(void)cancelImagePicker:(id)sender;
#end
#protocol NavigationControllerDelegate <NSObject>
- (void)mediaPickerController:(NavigationController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
- (void)mediaPickerControllerDidCancel:(NavigationController *)picker;
#end
NavigationController.m
#import "NavigationController.h"
#import "DataViewController.h"
#interface NavigationController ()
#end
#implementation NavigationController
#synthesize delegate;
-(id)init{
UIViewController *controller = [[DataViewController alloc]initWithNibName:#"DataViewController" bundle:nil];
self = [super initWithRootViewController:controller];
if (self) {
self.navigationBar.topItem.title = #"Data Table";
self.navigationBar.tintColor = [UIColor clearColor];
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Cancel"
style:UIBarButtonSystemItemCancel target:self action:#selector(cancelImagePicker:)];
self.navigationBar.topItem.rightBarButtonItem = rightButton;
}
return self;
}
-(void)cancelImagePicker:(id)sender{
[delegate mediaPickerControllerDidCancel:self];
}
#end
DataViewController.m
.....
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
secondViewController *secondController = [[secondViewController alloc]initWithNibName:#"secondViewController" bundle:nil ];
[self.navigationController pushViewController: secondController animated:YES];
}
.......
I want to add a "cancel" button on secondViewController's navigation bar which performs the action -(void)cancelImagePicker:(id)sender; from NavigationController.m. And the same for pushed third, fourth and fifthViewController. How can this be achieved? Do i have to write code in each viewController or Can i write in common?
I have presented the NavigationController from MainViewController on buttonClick as
- (IBAction)navView:(id)sender {
NavigationController * controller = [[NavigationController alloc]init];
controller.delegate = self;
[self presentViewController:controller animated:YES completion:nil];
}
and implemented the delegation methods there.
You can use notification center instead of delegates, the idea is,
[NSNotificationCenter DefaultCenter] addObserver]