Objective-C: Change an image from a separate class - iphone

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];

Related

How can I call the one method in all the view controllers?

How can I call the one method in all the view controllers?
One method in viewcontroller1 like,
- (void)doSearch
{
NSLog(#"Search..!");
}
I want to call doSearch method from viewcontroller2, viewcontroller3, viewcontroller4, viewcontroller5, etc.
How to do this?
You can declare it in separate class and instantiate that class in all viewControllers, or you could define this method in your AppDelegate and call in all your viewController. you could access the AppDelegate in your ViewControllers by getting its instance like this
self.appDelegate=(AppDelegate*)[[UIApplication sharedApplication]delegate];
and finally call the method like this
[self.appDelegate doSearch];
Generally it is preferable to declare all your methods or data which is shared through the application in a separate class and use this class. I usually use singelton Object class in my application, define all the shared data in that and finally access in all classes
here is example of singelton class
MyData.h
#interface MyData : NSObject
+(MyData*)getInstance;
-(void)search;
#end
MyData.m
#import "MyData.h"
#implementation MyData
static MyData *instance =nil;
+(MyData *)getInstance
{
#synchronized(self)
{
if(instance==nil)
{
instance= [[MyData alloc]init];
}
}
return instance;
}
-(void)search {
NSLog(#"search");
}
#end
finally in your viewController
MyData *myData=[MyData getInstance];
[myData search];
You can declare this method in AppDelegate.h. like
- (void)doSearch;
And Implement it in AppDelegate.m like
- (void)doSearch
{
//Your Search Logic
}
Then, Create AppDelegate instance like
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
Make Your Project's .pch file look like following:
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
AppDelegate *appDelegate;
#endif
Now, From Any ViewController, You can call method like:
[appDelegate doSearch];
Happy Coding.
NOTE: Personally, I avoid this kind of implementation in AppDelegate Class.
I use Singleton Object Pattern for this kind of purpose. But, Given is the quickest way.
___________EDIT____________
Add a New Class file of NSObject type: Name it CommonMethod (or whatever you want)
in CommonMethod.h
#interface CommonMethods : NSObject
+ (CommonMethods *)sharedObject;
+ (void)doSearch;
in CommonMethod.m
#import "CommonMethods.h"
#implementation CommonMethods
+ (CommonMethods *)sharedObject
{
static dispatch_once_t once;
static CommonMethods *sharedObject;
dispatch_once(&once, ^ { sharedObject = [[CommonMethods alloc] init]; });
return sharedObject;
}
+ (BOOL)doSearch
{
// Your Search Logic.
}
Now, Add #import "CommonMethods.h" to your project's .pch file.
And You are all set to go...!!!
Method Call (in any of your viewController): [CommonMethods doSearch];
Put all controllers in an NSArray *, lets say it is called controllerArray.
Then you can make all controllers perform selector with:
[controllerArray makeObjectsPerformSelector:#selector(doSearch)];
Add your method to AppDelegate.m file
- (void)doSearch
{
NSLog(#"Search..!");
}
And Add #import "AppDelegate.h" In UIViewController that you want to call :
You can call method by,
AppDelegate *del = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[del performSelector:#selector(doSearch) withObject:nil afterDelay:0];
From Any UIViewController
You may like to read below tutorial
Global functions and variables in Objective C
or You can create methods in the appDelegate class that you can access through all your app. For example, in your AppDelegate.h you have declared this method as follow:
-(void)myMethod;
In your AppDelegate.m, you define it as:
-(void)myMethod
{
NSLog(#"myMethod is getting called");
}
From any other classes (Master or Detail, etc.), you access myMethod by:
#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate myMethod];
The best way to make AbstractViewController and inside it add all your common behaviors or methods. Any ViewController will inherits from the Abstract and can call any common Method
The best way is to make a separate header file make this method a class method and you can call this anywhere in the project by importing the class.And you can include this class into your pch file so that import can be avoided from all VCs
class.h
+ (void)doSearch
{
NSLog(#"Search..!");
}
in ViewControllers
#import "class.h"
-(void)someMethod
{
[class doSearch];
}

calling functions and passing information between views

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];

It's possible create a custom delegate in AppDelegate?

i want know if it's possible create a custom delegate in the AppDelegate class, like in this way for instance:
#protocol AppDelegateDelegate <NSObject>
- (void)finishSync:(BOOL)success;
#end
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
#property (nonatomic, weak) id <AppDelegateDelegate> delegate;
#end
it's possible create something like this? to notify the classes that are registered for this delegate?
EDIT
How i can use the Delegate? for example if i do this:
#import "AppDelegate.h"
#interface MasterViewController : UIViewController <AppDelegateDelegate>
#end
.m
#implementation MasterViewController
...
- (void)viewDidLoad {
AppDelegate *appController = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appController.customDelegate = self;
}
in i stay only in that view works, but for example if i switch in SecondViewController that have the same code to implement the delegate, the delegate don't works anymore neither in the MasterViewController...what i wrong?
Yes, That is fine. You can create delegates anywhere you want and use it anywhere by importing that class. There are no restrictions.

Passing data between ObjectClass and ViewController

I am trying to pass some data back to my view controller from an object class.
This is a basic over view of what classes and views are doing, and then I will show you my code.
So ViewController, loads its tableviewcells. Then inside this delegate method it calles a connection class I have created, inside that conection class is NSURLConnection methods connecting and downloading data from the database, in the connectionDidFinishLoading method of this connection class I set up a parsing class and pass all of the downloaded data over to that.
Then I parse that data, and at the end of that parser inside parserDidEndDocument, I am trying to send the data that is now in an array variable back to my view controller to display. However.. for some reason my protocols and delegates are not working.
I have set up protocols inside m parser class and set the delegates in my view controller but it never makes it to my protocol method.
I will show you my code below.
parserclass.h
#protocol PassParsedData <NSObject>
#required
- (void)sendManufactureArray:(NSArray *)array;
#end
//..
id <PassParsedData> delegate;
//..
#property (strong) id delegate;
//
parserclass.m
#import "VehicleSearchViewController.h"
//..
#synthesize delegate;
//..
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//.. array stuff is set up and i can log it so i know its working.. i just want to show you the protocol and delegate stuff to be clear
[[self delegate]sendManufactureArray:filteredArray];
}
Then moving onto my view controller where I am hoping to call the protocol and get the filteredArray data back.
ViewController.h
#import "EngineResponses.h" //delegates & protocols
//..
#interface SearchViewController : UITableViewController <PassParsedData> {
//..
Viewcontroller.h
#import "EngineResponses.h"
//..
- (void)viewDidLoad
{
[super viewDidLoad];
//..
parserClass *pc = [[parserClass alloc] init];
[pc setDelegate:self];
//..
}
- (void)sendManufactureArray:(NSArray *)array //Breakpoint here is never accessed
{
FilterArray = array;
[self.tableView reloadData];
}
As you can see in that last method which is the protocol I am calling, its never accessed by the thread. I have checked, This call
[[self delegate]sendManufactureArray:filteredArray];
gets accessed fine.. but it just never makes it back to the View Controller.. any ideas... am I missing anything? .. im at a complete loss, been working on this all day.
any help would be HUGELY appreciated! :)
UPDATE:
I have added this to my ViewController.h
//..
ParserClass *parserclass;
//..
#property (strong, nonatomic) ParserClass *parserclass;
//..
viewcontroller.m
#synthesize parserclass;
//..
//then I call this in viewdidload
[engineResponses setDelegate:self];
As others have said in the comments, your pc variable is being deallocated at the end of the viewDidLoad block, since the only reference it has goes out of scope there. If you want it to live on, you must enlarge its scope (i.e. make it an instance variable).

method not found

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?