I'm working on an application with three tabs plus a small view in which I created a sort of TopBar that contains some info and some buttons.
In the main application delegate I define:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
...
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
//here we add the topBar:
topBarViewController = [TopBarViewController instance];
topBarViewController.appDelegate = self;
[window addSubview:topBarViewController.view];
...
}
- (void)showReplyView
{
self.tabBarController.selectedViewController =
[self.tabBarController.viewControllers objectAtIndex:2];
}
as you can see I set the .appDelegate in the topBar to make some call back in the code of the topBar (ie: when I want to change the tab currently visualized)
Now in my TopBarViewController.h I have:
#interface TopBarViewController : UIViewController {
MyAppDelegate *appDelegate;
...
}
#property (nonatomic,retain) MyAppDelegate *appDelegate;
-(void)testMethod;
and in the .m file:
#implementation TopBarViewController
#synthesize appDelegate;
...
-(void)testMethod{
[appDelegate showReplyView];
}
...
When I build the project the compiler tell me that the showReplyView method doesn't exist.
I tried everything and I'm sure that there are no typo errors...
Is it possible that I can't reference to the delegate?
Thanks to anyone would help me...
I found the problem:
in the TopBarViewController.h I was declaring #class MyAppDelegate; since I couldn't make an import (avoid the loop).
So the compiler was not able to find out which methods were declared.
To solve it I import the #import MyAppDelegate.h directly in the TopBarViewController.m!
Thanks anyway for the help!
Have you defined showReplyView in the #interface for MyAppDelegate?
Related
I have looked around for an answer to this with no avail, so I hope I am not asking an answered question.
I have two classes (ClassA and ClassB), both connected to UIViewControllers that are linked via a segue. ClassA contains a UIImage named backgroundImage. My goal is to change ClassA's background image from within ClassB.
In ClassB.h I have tried:
#property (nonatomic, retain) ClassA *mainView;
And in ClassB.m I tried changing the background image via:
#synthesize mainView;
//Then inside button click I tried:
[mainView.backgroundImage setImage:[UIImage imageNamed:#"newImage.jpg"]];
Obviously this did not work since I am not setting the image to the same ClassA that is being used in the app.
I know I'm missing something obvious, thanks in advance!
Please use the Protocol mechanism to satisfy your requirements
Implementation is as bellow
In AppDelegate.h file of project
#protocol ImageChangeDelegate <NSObject>
#optional
-(void)ChangeImage;
#end
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
}
#property (nonatomic,strong) id<ImageChangeDelegate> delegateImageChange;
In AppDelegate.m file of project
#synthesize delegateImageChange;
Now In .h file of Class B
#import "AppDelegate.h"
#interface EventGuestListViewController : UIViewController
{
AppDelegate* appDelegate;
}
-(void)ChangeBackgroundOfClassA;
Now In .m file of Class B
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
Now in method of changing BGs
-(void)ChangeBackgroundOfClassA
{
[appDelegate.delegateImageChange ChangeImage];
}
Now Implements the Protocol in Class A to change the Background.
Now In .h file of Class A
#import "AppDelegate.h"
#interface EventGuestListViewController : UIViewController <ImageChangeDelegate>
{
IBOutlet UIImageView* imageBGClassA;
AppDelegate* appDelegate;
}
Now In .m file of Class A
- (void)viewDidLoad
{
[super viewDidLoad];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.delegateImageChange = self; //Here you need to set the delegate to 'self' to call then Custom Protocol method
}
-(void)ChangeImage
{
imageBGClassA.image = [UIImage imageNamed:#"newImage.jpg"];
}
In Class B once -(void)ChangeBackgroundOfClassA call the delegate method call which is implement on Class A and the background Image will surly change
This is work with me
It may help you !!!
Use the same "mainView" instance of ClassA to navigate to ClassA View Controller.
Should try out delegate mechanism.It will allow you to call a method in classA from classB.
In that method change the background image of classA from classB's call to delegate
You can try any of two ways:
1) Using the delegation. Passing the delegate while loading ClassB.
2) Using the NotificationCenter and change the mainView Image by calling the notification from Class B.
Harry.
You can do this task easily using Custom Delegates or Notifications . I will explain it to you using Notification . Let there be two classes - Class-A & Class-B
In the Class-A add a Notification like this
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(changeImage)
name:#"ImageChangeNotification"
object:nil];
also create the selector in the Class-A
-(void)changeImage
{
[yourImageView setImage:[UIImage imageNamed:#"YouImageName.png"]];
}
What left is just to post this Notification from anywhere within the whole project . In our case let it be Class-B
[[NSNotificationCenter defaultCenter] postNotificationName:#"ImageChangeNotification" object:nil];
Thanks in advance for your help!
In the main ViewController.m of my project I am adding a customized tableView like so:
messageController = [[MyMessagesController alloc] initWithStyle:UITableViewStylePlain];
[self addChildViewController:messageController];
[self.view addSubview:messageController.view];
Then, in the MyMessagesController.m section tableView didSelectRowAtIndexPath: I'd like to write code that would take effect in the ViewController.m where it was created and added as a childViewController.
How can I access the functions of the ViewController.m from MyMessagesController.m?
Can I make it a delegate somehow so I could call [delegate functionName];?
Could I pass information back to the ViewController.m? About which of the rows in table was selected by sending through an NSString or NSArray or anything?
Yes, use a delegate, if you are unsure how best to accomplish this, here is a good reference from Apple about delegate programming
Got it figured out, here's how you turn one viewController into a delegate for another:
In the .h of the parent controller -
#interface ViewController : UIViewController <NameOfDelegate> {
In the .m of the parent controller, once you create the new view -
newViewController.delegate = self;
and also:
- (void)functionToCall:(id)sender {
NSLog(#"Function Called!!!");
}
In the .h of the newViewController you're adding -
#protocol NameOfDelegate;
#interface newViewController : UIViewController/OR/TableViewController {
id <NameOfDelegate> delegate;
}
#property (nonatomic, strong) id <NameOfDelegate> delegate;
#end
#protocol NameOfDelegate
- (void)functionToCall:(id)sender;
#end
in the .m of the newViewController -
#implementation newViewController
#synthesize delegate;
and when you're ready to call the function in your delegate -
[delegate functionToCall:self];
I have been given a project to edit. I think this is a simple question but want to explain it in detail.I usually set up iPhone projects with interface builder and then have a view controller h and m file.
However this has been set up in a different way I am new to, the view has been coded.
The h file is a simple viewcontroller class like this:
#interface MainViewController : UIViewController
{
}
- (id)init;
#end
And then the m file has this:
#interface MainView : UIView
{
NSUinterger firstinterger;
}
- (id)initWithImages:(NSArray *)inImages;
#end
And then it has the #implementation MainView just after that with lots more code.
Further down however is where I need to add my code just after
#end
#implementation MainViewController
But I need to access the NSUinterger named first integer and I am unable to. I have tried a few ways of synthesizing etc. but I think I am doing it wrong. How I would get the value of it? I can access it in the code before the #implementation MainViewController but not after which is where I need it.
Synthesize the variable in MainView. Have an instance of the MainView in MainViewController and then you can access it by
MainView *mv = [[MainView alloc] init];
mv.firstInteger // gives you the variable.
NSUinterger firstinterger in your code shows no ';' at the end of that line, do you get compilation errors or is it just a typo in your question?
I'm new to iOS development and am running into an issue with my header files. I'm running into a circular dependency issue with my header files. My application delegate class contains a pointer to my view controller, since I have to set one of the view controller's properties in my didFinishLaunchingWithOptions method...
//appDelegate.h //DISCLAIMER: THIS IS UNTESTED CODE AND WRITTEN ON THE FLY TO ILLUSTRATE MY POINT
#import <UIKit/UIKit.h>
#import "MyViewController.h"
#interface appDelegate
NSManagedObjectContext *managedObjectContext;
MyViewController *viewController;
BOOL myFlag;
#end
//appDelegate.m
#implementation appDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
viewController.managedObjectContext = self.managedObjectContext;
.
.
.
}
#end
And in my view controller, I reference the "myFlag" property, that's in my app delegate...
//MyViewController.h
#import "appDelegate.h" //<---circular dependency, causing "Expected specifier-qualifier-list before MyViewController" errors in my appDelegate header file
#interface MyViewController: UIViewController
{
NSManagedObjectContext *managedObjectContext;
}
#end
//MyViewController.m
#import "MyViewController.h"
#implementation MyViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
((appDelegate*)[[UIApplication sharedApplication] delegate]).myFlag = NO;
}
#end
But in order to access the "myFlag" property in my app delegate, I need to import the app delegate's header file. This is what's causing the circular dependency. Not sure how to resolve this, has anyone run into this?
Thanks in advance for your help!
Don't #import "MyViewController.h" in appDelegate.h. Instead, forward-declare the class.
#class MyViewController;
#interface appDelegate
NSManagedObjectContext *managedObjectContext;
MyViewController *viewController;
BOOL myFlag;
#end
Also, you don't need to #import "appDelegate.h" in MyViewController.h if all you need is to reference the myFlag property in the implementation. Instead, import it in the MyViewController.m file.
#class is the syntactic approach you're looking for.
Many coders look to avoid this circularity (which couples your classes in two directions, meaning your view controller can only be used in circumstances where the app delegate has that BOOL). There are a few ways you can do this:
Move the state variable to a singleton
Have the view controller fetch the value through an interface that the delegate implements
Key-Value Observing (which your app delegate would configure on your view controller)
For small projects this kind of dependency is probably not really a problem, but as project size grows and the desirability of code reuse grows, clean functional separation becomes more and more valuable.
Did not read everything, but you can do forward declarations with #class. Usually how I solve circular dependencies.
I've been banging my head with this one this evening and am sure it's something very simple that I've missed
I've created a new project with the appdelegate and a view controller class as below. The view controller synthesises the property in the .m, and the app delegate header imports the view controller .h file. Code below:
View controller header:
#interface untitled : UIViewController {
NSString *string;
}
#property (nonatomic, retain) NSString *string;
App delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
testViewController = [[untitled alloc] initWithNibName:#"untitled" bundle:nil];
testViewController.string = #"Testing String";
[window addSubview:testViewController.view];
[window makeKeyAndVisible];
}
Can someone please help and point out the obvious mistake as to why setting the string property fails here with the error mentioned? Is it because of being inside this method? I've never had issues setting properties in other methods before after initing a view controller.
Thanks.
The error is saying it does not understand that the class has that property. It means you have either the wrong class or that it knows nothing about the class.
So, you need to add:
#import "untitled.h"
in your application delegate - also, you need to have the variable be of type "untitled" (I am pretty sure you declared the type as UIViewController and not untitled):
untitled * testViewController = (untitled *)[[untitled alloc] initWithNibName:#"untitled" bundle:nil];
By the way, by convention you should always start class names in uppercase.