How can I start a ViewController from within a Method? - ios

I want to use the TGCameraViewController from within a iOS Cordova Plugin method.
Here is the implementation of the method:
#import "BCamera.h"
#import "TGCameraViewController.h"
#implementation BCamera
// Cordova command method
-(void) openCamera:(CDVInvokedUrlCommand *)command {
// take a photo
}
From the documentation of the TGCameraViewController I have to use the following to take a photo:
#import "TGCameraViewController.h"
#interface TGViewController : UIViewController <TGCameraDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *photoView;
- (IBAction)takePhotoTapped;
#end
#implementation TGViewController
- (IBAction)takePhotoTapped
{
TGCameraNavigationController *navigationController =
[TGCameraNavigationController newWithCameraDelegate:self];
[self presentViewController:navigationController animated:YES completion:nil];
}
#pragma mark - TGCameraDelegate optional
- (void)cameraWillTakePhoto
{
NSLog(#"%s", __PRETTY_FUNCTION__);
}
- (void)cameraDidSavePhotoAtPath:(NSURL *)assetURL
{
// When this method is implemented, an image will be saved on the user's device
NSLog(#"%s album path: %#", __PRETTY_FUNCTION__, assetURL);
}
- (void)cameraDidSavePhotoWithError:(NSError *)error
{
NSLog(#"%s error: %#", __PRETTY_FUNCTION__, error);
}
#pragma mark - TGCameraDelegate required
- (void)cameraDidTakePhoto:(UIImage *)image
{
_photoView.image = image;
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)cameraDidCancel
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
How do I use this example to open the camera view from within my openCamera method?

You should present TGCameraNavigationController on rootViewController of your application, e.g.
#interface BCamera() <TGCameraDelegate>
#end
#implementation BCamera
- (void)openCamera:(CDVInvokedUrlCommand *) command
{
TGCameraNavigationController *navigationController = [TGCameraNavigationController newWithCameraDelegate:self];
UIViewController *rootVC = [[UIApplication sharedApplication] delegate] window] rootViewController];
[rootVC presentViewController:navigationController animated:YES completion:nil];
}
Also you must implement TGCameraDelegate protocol methods.
- (void)cameraDidTakePhoto:(UIImage *)image
{
//do something with image
[self dismissCameraVC];
}
- (void)cameraDidCancel
{
[self dismissCameraVC];
}
- (void)dismissCameraVC
{
UIViewController *rootVC = [[UIApplication sharedApplication] delegate] window] rootViewController];
[rootVC dismissViewControllerAnimated:YES completion:nil];
}

Related

Present View Controller not working with ios 9

Present view controller is not working with ios 9,
when I press the button it not redirected to present view controller.
Why this happens ?
I had tried the below code
RegistrationViewController * viewController =[[UIStoryboard storyboardWithName:#"Registration" bundle:nil] instantiateViewControllerWithIdentifier:#"RegistrationViewController"];
[self presentViewController:viewController animated:YES completion:nil];
I had also tried the below code
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Registration"
bundle:nil];
RegistrationViewController *add =
[storyboard instantiateViewControllerWithIdentifier:#"RegistrationViewController"];
[self presentViewController:add animated:YES completion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:add
animated:YES
completion:nil];
});
}];
Edit
My complete code here. I am using Xcode 7 and running it with ios 9
#import "LoginViewController.h"
#import "RegistrationViewController.h"
#interface LoginViewController ()
#end
#implementation LoginViewController
- (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)actionRegistrationClicked:(id)sender
{
RegistrationViewController * viewController =[[UIStoryboard storyboardWithName:#"Registration" bundle:nil] instantiateViewControllerWithIdentifier:#"RegistrationViewController"];
[self presentViewController:viewController animated:YES completion:nil];
}
#end
Registration view controller
#import "RegistrationViewController.h"
#interface RegistrationViewController ()
#end
#implementation RegistrationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Make sure the presentedViewController is nil. If presentedViewController is not nil change the code to following.
RegistrationViewController * viewController =[[UIStoryboard storyboardWithName:#"Registration" bundle:nil] instantiateViewControllerWithIdentifier:#"RegistrationViewController"];
if ([self presentedViewController]) {
[[self presentedViewController] dismissViewControllerAnimated:NO completion:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:viewController animated:YES completion:nil];
});
}];
} else {
[self presentViewController:viewController animated:YES completion:nil];
}
try viewDidAppear in
-(void)viewDidAppear:(BOOL)animated{
[self presentViewController:viewController animated:YES completion:nil];
}
Try the below code:
RegistrationViewController * viewController = [[self.storyboard instantiateViewControllerWithIdentifier:#"RegistrationViewController"];
[self presentViewController:viewController animated:YES completion:nil];

Mail Composer won't dismiss iOS

I have ViewController with button, and action on button:
- (IBAction)clickMe:(id)sender {
MailHelper *helper = [[MailHelper alloc] init];
[helper setAllData:self];
}
Also, there is helper class for mail composing (MailHelper.h):
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface MailHelper : UIViewController<MFMailComposeViewControllerDelegate>
#property MFMailComposeViewController* mailView;
- (void)setAllData:(UIViewController *)ctrl;
#end
and implementation (MailHelper.m):
- (void)setAllData:(UIViewController *)ctrl {
mailView = [[MFMailComposeViewController alloc] init];
mailView.mailComposeDelegate = self;
mailView.toRecipients = #[#"mail#email.com"];
[mailView setSubject:#"Subject"];
[ctrl presentViewController:mailView animated:YES completion:nil];
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
I can open mail composer, but while sending mail, saving draft or deleting draft app crashes. Any ideas?
When the MFMailComposeViewController is request to be dismissed you are calling the dismiss method on self but self is presenting te MFMailComposeViewController.
Change:
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
to
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[controller dismissViewControllerAnimated:YES completion:nil];
}
To fix the deallocation issue add the following:
import the <objc/runtime.h> in you .m file and make self be associated with the controller passed:
static void * MailHelperKey = &MailHelperKey;
- (void)setAllData:(UIViewController *)ctrl {
mailView = [[MFMailComposeViewController alloc] init];
mailView.mailComposeDelegate = self;
objc_setAssociatedObject(mailView, MailHelperKey, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
....
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[controller dismissViewControllerAnimated:YES completion:nil];
objc_removeAssociatedObjects(controller);
}
This will make sure that as long a the presenting control is not deallocated your mail helper. Does not deserve on price fro beauty but should work.
Ok guys. Solution is to make instance of helper somewhere else, let's say:
#implementation ViewController
MailHelper *helper;
and:
- (IBAction)clickMe:(id)sender {
helper = [[MailHelper alloc] init];
[helper setAllData:self];
}

Dissmis NavigationViewController never dealloc the rootViewController

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 ?

how to work with a class instance inside the viewController in Appdelegate?

i have an class instance and it methods in my ViewController.
Is it possible to get access of this instance and methods in the appdelegate ?
its like:
#implementation FirstViewController
#synthesize myObject;
- (void)viewDidLoad
{
[super viewDidLoad];
myObject = [[myObject alloc] initWithFrame:........];
[self.view addSubview:myObject];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[myObject doSomething];
}
and I want to call the same method in AppDelegate
- (void)applicationWillResignActive:(UIApplication *)application
{
[myObject do Something];
}
Someone an idea ?
greetz
You can get the controller from rootViewConroller like this and call the fucntion of it
- (void)applicationWillResignActive:(UIApplication *)application{
UIViewController *controller = self.window.rootViewController;
if([controller isKindOfClass:[UINavigationController class]]){
FirstViewController *firstViewController;
for (id vc in [((UINavigationController*)controller) viewControllers])
{
if ([vc isKindOfClass:[FirstViewController class]])
{
[((FirstViewController *) vc) doSomething];
break;
}
}
}
else if([controller isKindOfClass:[FirstViewController class]]){
[((FirstViewController *) controller) doSomething];
}else{
//Not found
}
}

Launch Image Picker from button not working

I am using the standard tab bar application as a basis for a test app.
I am also trying to use the ELCAlbumPickerController class found at github.
The button to launch the photo picker and the uiscrollview are located in the Secondview.xib
The following is the code in the SecondViewController.h
#import <UIKit/UIKit.h>
#import "ELCImagePickerController.h"
#interface SecondViewController : UIViewController <ELCImagePickerControllerDelegate,UINavigationControllerDelegate, UIScrollViewDelegate>{
UIWindow *window;
SecondViewController *viewController;
IBOutlet UIScrollView *scrollview;
}
#property (nonatomic,retain) IBOutlet UIWindow *window;
#property (nonatomic,retain) IBOutlet SecondViewController *viewController;
#property (nonatomic,retain) IBOutlet UIScrollView *scrollview;
-(IBAction)launchController;
#end
And the following is in SecondViewController.m
#import "myappAppDelegate.h"
#import "SecondViewController.h"
#import "ELCImagePickerController.h"
#import "ELCAlbumPickerController.h"
#implementation SecondViewController
#synthesize window;
#synthesize viewController;
#synthesize scrollview;
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.*/
- (void)viewDidLoad
{
//[self launchController:self];
[super viewDidLoad];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(IBAction)launchController {
ELCAlbumPickerController *albumController = [[ELCAlbumPickerController alloc] initWithNibName:#"ELCAlbumPickerController" bundle:[NSBundle mainBundle]];
ELCImagePickerController *elcPicker = [[ELCImagePickerController alloc] initWithRootViewController:albumController];
[albumController setParent:elcPicker];
[elcPicker setDelegate:self];
//myappAppDelegate *app = (myappAppDelegate *)[[UIApplication sharedApplication] delegate];
SecondViewController *app = (SecondViewController *)[[UIApplication sharedApplication] delegate];
[app.viewController presentModalViewController:elcPicker animated:YES];
[elcPicker release];
[albumController release];
}
#pragma mark ELCImagePickerControllerDelegate Methods
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info {
[self dismissModalViewControllerAnimated:YES];
for (UIView *v in [scrollview subviews]) {
[v removeFromSuperview];
}
CGRect workingFrame = scrollview.frame;
workingFrame.origin.x = 0;
for(NSDictionary *dict in info) {
UIImageView *imageview = [[UIImageView alloc] initWithImage:[dict objectForKey:UIImagePickerControllerOriginalImage]];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
imageview.frame = workingFrame;
[scrollview addSubview:imageview];
[imageview release];
workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
}
[scrollview setPagingEnabled:YES];
[scrollview setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
}
- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker {
[self dismissModalViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[super dealloc];
}
#end
When you click the button you get a message "deallocing ELCImagePickerController" so it is calling the ELCImagePickerController class but it just does not show the image picker. Any ideas would be appreciated.
Thanks
In the launchController() method, you were casting an appDelegate into a viewController, which is logically wrong. You need to use an actual viewController to presentModalViewController. Try:
[self presentModalViewController:elcPicker animated:YES];

Resources