250

What I am trying to do is click a button (that was created in code) and have it call up a different view controller then have it run a function in the new view controller.

I know it could be done relatively easily in IB but that isn't an option.

An example of what I want to do would be if you had two view controllers one with a splash screen of house. The other view controller had a walk through of the house on it that you could go through all the rooms in a set order. The splash screen would have buttons for each room that would allow you to jump to any point on the walk through.

Mytheral
  • 3,865
  • 7
  • 32
  • 56

13 Answers13

539

You can access the delegate like this:

MainClass *appDelegate = (MainClass *)[[UIApplication sharedApplication] delegate];

Replace MainClass with the name of your application class.

Then, provided you have a property for the other view controller, you can call something like:

[appDelegate.viewController someMethod];
Cristian Radu
  • 8,346
  • 2
  • 17
  • 11
  • 12
    might also need to import the appDelegate.h file wherever it is used, or do @class appDelegate – Zaky German Feb 22 '11 at 20:00
  • 3
    appDelegate.h file is a good candidate to go in the target's prefix/precompiled header file IMO. – mharper Feb 22 '11 at 21:17
  • 48
    If you import your app delegate in your Prefix.pch like @mharper says you can also add this at the same time: #define AppDelegate ((MyAppDelegateClass *)[UIApplication sharedApplication].delegate) which then allows you to access your app delegate like '[AppDelegate.viewController someMethod]'. It simplifies it a bit, but it also makes it easier to abuse it. – Kenny Lövrin Dec 15 '11 at 08:18
  • after the @end of my app delegate.h file , I added #define AppDelegate ((MyAppDelegateClass *)[UIApplication sharedApplication].delegate) Now whichever class imports app delegate can directly use [AppDelegate.viewController someMethod] – harveyslash Jul 13 '16 at 07:16
44

And if anyone is wondering how to do this in swift:

if let myDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
   myDelegate.someMethod()
}
canhazbits
  • 1,609
  • 1
  • 13
  • 19
  • if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {} is a better approach in swift. – cbartel Aug 10 '16 at 20:15
  • @petrsyn What do you mean the delegate can be `nil`? Isn't that an app ALWAYS has an AppDelegate?! – Honey Dec 26 '16 at 13:56
  • In recent versions of Swift, `sharedApplication()` should be replace with `shared`. i.e., remove "Application" and the parentheses. So the full working code as of Swift 5.2 would be: `if let myDelegate = UIApplication.shared.delegate as? AppDelegate { myDelegate.someMethod() }` – sfarbota Apr 15 '20 at 06:17
41

Sounds like you just need a UINavigationController setup?

You can get the AppDelegate anywhere in the program via

YourAppDelegateName* blah = (YourAppDelegateName*)[[UIApplication sharedApplication]delegate];

In your app delegate you should have your navigation controller setup, either via IB or in code.

In code, assuming you've created your 'House overview' viewcontroller already it would be something like this in your AppDelegate didFinishLaunchingWithOptions...

self.m_window = [[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds] autorelease];
self.m_navigationController = [[[UINavigationController alloc]initWithRootViewController:homeViewController]autorelease];
[m_window addSubview:self.m_navigationController.view];

After this you just need a viewcontroller per 'room' and invoke the following when a button click event is picked up...

YourAppDelegateName* blah = (YourAppDelegateName*)[[UIApplication sharedApplication]delegate];
[blah.m_navigationController pushViewController:newRoomViewController animated:YES];

I've not tested the above code so forgive any syntax errors but hope the pseudo code is of help...

pablasso
  • 2,429
  • 2
  • 26
  • 32
sradforth
  • 2,078
  • 1
  • 22
  • 35
  • 8
    Your answer is correct as well, I ended up using a combination of Cristian's and your answer. I wish I could split the check mark. – Mytheral Feb 22 '11 at 20:18
16

This is how I do it.

[[[UIApplication sharedApplication] delegate] performSelector:@selector(nameofMethod)];

Dont forget to import.

#import "AppDelegate.h"
mikemike396
  • 2,371
  • 23
  • 40
13

Just Follow these steps

1.import your app delegate in your class where you want app delegate object.

#import "YourAppDelegate.h"

2.inside your class create an instance of your app delegate object(Its basically a singleton).

YourAppDelegate *appDelegate=( YourAppDelegate* )[UIApplication sharedApplication].delegate;

3.Now invoke method using selector

if([appDelegate respondsToSelector:@selector(yourMethod)]){

        [appDelegate yourMethod];
    }

or directly by

[appDelegate yourMethod];

for swift

let appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate

i will recommend the first one. Run and Go.

Tunvir Rahman Tusher
  • 5,542
  • 2
  • 33
  • 29
  • this is specifically NOT a new instance of the delegate, but rather retrieves the singleton delegate of the singleton application – Ammo Goettsch Jan 28 '17 at 23:13
11
NSObject <UIApplicationDelegate> * universalAppDelegate = 
    ( NSObject <UIApplicationDelegate> * ) [ [ UIApplication sharedApplication ] delegate ];

It avoid having to include your AppDelegate.h everywhere. It's a simple cast that goes a long way, allowing to develop independent Controller and reuse them elsewhere without to worry about class name and so on...

Enjoy

  • Thank you for sharing, it makes me happy for a couple of minutes, probobly it'll work some way, but what if I want to use a method like visibleViewController from it? It'll give error like this: Property 'visibleViewController' not found on object of type 'NSObject *. any solution for this? – mgyky Nov 20 '18 at 10:42
8

A lot of good answers are already added. Though I want to add something which suits me most of the time.

#define kAppDelegate ((YourAppDelegate *)[[UIApplication sharedApplication] delegate]);

and thats it. Use it throughout the application just like a constant.

e.g.

[kAppDelegate methodName];

Don't forget to import yourAppDelegate.h in corresponding .pch or macros file.

ZaEeM ZaFaR
  • 1,438
  • 17
  • 21
7

If someone need the same in Xamarin (Xamarin.ios / Monotouch), this worked for me:

var myDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;

(Require using UIKit;)

Daniele D.
  • 2,416
  • 3
  • 34
  • 42
  • The correct statement in Swift is let appdel : AppDelegate = UIApplication.shared.delegate as! AppDelegate – Phil Nov 19 '19 at 04:22
6

Update for Swift 3.0 and higher

//
// Step 1:- Create a method in AppDelegate.swift
//
func someMethodInAppDelegate() {

    print("someMethodInAppDelegate called")
}

calling above method from your controller by followings

//
// Step 2:- Getting a reference to the AppDelegate & calling the require method...
//
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {

    appDelegate.someMethodInAppDelegate()
}

Output:

enter image description here

iAj
  • 3,467
  • 1
  • 28
  • 33
5

And in case you need access to your WatchKit extension delegate from a view controller on watchOS:

extDelegate = WKExtension.sharedExtension().delegate as WKExtensionDelegate?
Marco Miltenburg
  • 5,893
  • 1
  • 26
  • 26
3

You can add #define uAppDelegate (AppDelegate *)[[UIApplication sharedApplication] delegate] in your project's Prefix.pch file and then call any method of your AppDelegate in any UIViewController with the below code.

[uAppDelegate showLoginView];
Pratik Shah
  • 567
  • 4
  • 14
Ada
  • 466
  • 8
  • 13
1

In 2020, iOS13, xCode 11.3. What is working for Objective-C is:

#import "AppDelegate.h"

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

It's working for me, i hope the same to you! :D

0

Even if technically feasible, is NOT a good approach. When You say: "The splash screen would have buttons for each room that would allow you to jump to any point on the walk through." So you want to pass through appdelegate to call these controllers via tohc events on buttons?

This approach does not follow Apple guidelines and has a lot of drawbacks.

ingconti
  • 9,213
  • 2
  • 51
  • 39
  • Look at the date on the question... It's from back when Interface Builder was a separate application and development was a very different beast. I haven't touched iOS development in years so I can't evaluate more modern answers. – Mytheral Feb 08 '18 at 17:55
  • it ca be.. but my considerations are still valid – ingconti Feb 09 '18 at 18:44