Some help would be appreciated.
I have this simple project for testing purposes:
http://dl.dropbox.com/u/10101053/testDelegate.zip
I would like to pass a NSString in a delegate method but with this code does not work.
testDelegateViewController.h
#protocol testDelegateViewControllerDelegate;
#interface testDelegateViewController : UIViewController {
id<testDelegateViewControllerDelegate> delegate;
IBOutlet UIButton *button;
}
#property (nonatomic, assign) id<testDelegateViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIButton *button;
- (void)pass;
#end
#protocol testDelegateViewControllerDelegate
- (void)passSomeToDelegate:(NSString *)some;
#end
testDelegateVewController.m
#import "testDelegateViewController.h"
#implementation testDelegateViewController
#synthesize delegate, button;
- (void)pass
{
NSLog(#"Button Pressed");
[self.delegate passSomeToDelegate:#"some"];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
[button addTarget:self action:#selector(pass) forControlEvents:UIControlEventTouchUpInside];
}
//rest of code
AppDelegate.h
#import "testDelegateViewController.h"
#interface AppDelegate : NSObject <UIApplicationDelegate, testDelegateViewControllerDelegate> {
}
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window=_window;
#synthesize viewController=_viewController;
#pragma mark Delegate Method
- (void)passSomeToDelegate:(NSString *)some
{
NSLog(#"%#", some);
}
//rest of code
But in my console nothing is printed when button is tapped.
Thanks
You forgot to set your delegate. You can set the delegate in the application:didFinishLaunchingWithOptions: method.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.viewController.delegate = self;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
I added self.viewController.delegate = self; to set the delegate.
Related
How do I access IBOutlets that have been created in another class?
here is my code...
Class one
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (retain, readwrite) IBOutlet UIView *myView;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myView;
- (void)viewDidLoad {
[super viewDidLoad];
}
#end
Class two
.h
#import <UIKit/UIKit.h>
#interface ViewController2 : UIViewController
- (IBAction)accion:(id)sender;
- (IBAction)btnBack:(id)sender;
#end
.m
#import "ViewController.h"
#import "ViewController2.h"
#interface ViewController2 ()
#end
#implementation ViewController2
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)accion:(id)sender {
ViewController *a = [ViewController new];
UIView *someView = [a myView];
[someView setBackgroundColor:[UIColor redColor]];
}
- (IBAction)btnBack:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
why not works? no change the backgroundColor when return on my view
I think you try to delegate pattern to set the values Viewcontroller2.h file
Add protocol like this...
#import <UIKit/UIKit.h>
#protocol tutorialDelegate <NSObject> //set protocol
-(void)delegatesDescribedWithDescription;
#end
#interface ViewController2 : UIViewController
#property (weak, nonatomic) id<tutorialDelegate> tutorialDelegate1;
- (IBAction)accion:(id)sender;
- (IBAction)btnBack:(id)sender;
#end
after the declaring protocol in viewcontroller2.m file first synthesize and call method like this..
#import "ViewController.h"
#interface ViewController2 ()
#end
#implementation ViewController2
#synthesize tutorialDelegate1; // synthesize here
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)accion:(id)sender {
ViewController *a = [ViewController new];
UIView *someView = [a myView];
[someView setBackgroundColor:[UIColor redColor]];
}
- (IBAction)btnBack:(id)sender {
// Here we tell delegate to invoke method in parent view.
[self.tutorialDelegate1 delegatesDescribedWithDescription
];
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
and finally we implement this method in view controller.m file but first set delegate in viewcotroller.h file like this...
#import <UIKit/UIKit.h>
#import "ViewController2.h" //import here
#interface ViewController : UIViewController <tutorialDelegate> //set delegate
#property (retain, readwrite) IBOutlet UIView *myView;
#end
and viewcontroller.m file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myView;
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"yourIdentifier"]) {
ViewController2 *detailViewController =
segue.destinationViewController;
// here we set the ViewController to be delegate in
// detailViewController
detailViewController.tutorialDelegate1 = self;
}
}
// ViewController must implement tutorialDelegate's methods
// because we specified that ViewController will conform to
// tutorialDelegate protocol
-(void)delegatesDescribedWithDescription
{ // here your code please
viewTemp.backgroundColor =[UIColor redColor];
}
#end
Sorry about the confusion.
What I want to do:
enter a string in a textfield in a view(EnterCommandViewController) and click save button, which will dismiss current view and go back to another view(DetectionViewController) and show the string in the UILabel in current view(DetectionViewController). So I have put define the delegate protocol in EnterCommandViewController, my question is that why the respondToSelector, which is used to check whether someone is listening does not work.
I am really a beginner in iOS, I am right now writing a delegate to send text got form UITextField to a UILabel, But I found that the respondToSelector cannot be called by using NSLog for testing.
Below is my code for reference:
EnterCommandViewController.h
#import <UIKit/UIKit.h>
#import "RscMgr.h"
#protocol EnterCommandDelegate <NSObject>
-(void) commandEntered:(NSString*)command;
#end
#interface EnterCommandViewController : UIViewController <RscMgrDelegate>
{
RscMgr* rscMgr;
__weak IBOutlet UITextField *inputTextField;
__unsafe_unretained id<EnterCommandDelegate> delegate;
}
-(void)sendMessage:(NSString*)message;
- (IBAction)cancelPressed;
- (IBAction)savePressed;
#property (nonatomic,assign)id delegate;
#end
EnterCommandViewController.m
#import "EnterCommandViewController.h"
#interface EnterCommandViewController () <UITextFieldDelegate>
{
#private
BOOL connected;
}
#end
#implementation EnterCommandViewController
#synthesize delegate;
- (void)viewDidLoad {
[super viewDidLoad];
rscMgr = [[RscMgr alloc] init];
[rscMgr setDelegate:self];
// Do any additional setup after loading the view, typically from a nib.
inputTextField.text=#"";
[inputTextField becomeFirstResponder];
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
inputTextField.delegate = self;
}
-(void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
inputTextField.delegate = nil;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)cancelPressed {
[self dismissViewControllerAnimated:YES completion:^{}];
}
- (IBAction)savePressed {
//is anyone listening
NSLog(#"the command is %#",inputTextField.text);
NSLog(#"Checking -- SomeMethod is listening");
if([delegate respondsToSelector:#selector(commandEntered:)]){
NSLog(#"SomeMethod is listening");
//send delegate function with the command entered by the user
[delegate commandEntered:inputTextField.text];
}
[self dismissViewControllerAnimated:YES completion:^{}];
}
DetectionViewController.h
#import <UIKit/UIKit.h>
#import "EnterCommandViewController.h"
#interface DetectionViewController : UIViewController <EnterCommandDelegate>{
__weak IBOutlet UILabel *showCommand;
}
- (IBAction)showSettings:(UIBarButtonItem *)sender;
#end
DetectionViewController.m
#import <Foundation/Foundation.h>
#import "DetectionViewController.h"
#implementation DetectionViewController
- (IBAction)showSettings:(UIBarButtonItem *)sender {
}
-(void) viewDidLoad{
[super viewDidLoad];
showCommand.text=#"";
EnterCommandViewController* enterCVC = [[EnterCommandViewController alloc] init];
enterCVC.delegate = self;
}
#pragma mark - EnterCommandDelegate function(s)
-(void) commandEntered:(NSString *)command{
// showCommand.text = command;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"command: %#",command);
[self->showCommand setText:command];
});
}
#end
AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
You are not setting the delegate properly.
EnterCommandViewController* enterCVC = [[EnterCommandViewController alloc] init];
enterCVC.delegate = self;
This is not the way of setting the delegate in your case, since you are not using the created instance of enterCVC, instead a new instance is created from the storyboard when you are transitioning toEnterCommandViewController `(From your comment its clear that you are using the storyboard for this).
So what you can do is you should the delegate from prepareForSegue in DetectionViewController like
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get reference to the destination view controller
EnterCommandViewController* enterCVC = [segue destinationViewController];
enterCVC.delegate = self;
}
I've searched all over google, and stack overflow for a solution, but I wasn't able to find an answer that solved my problem. Sorry for the long post, as I'm trying to give as much information as I can. I'm new to iOS and Objective- c, but not programming in general due to being asked to switch over from Android by my company, so any help is appreciated.
I'm trying to assign a value to an NSString in one class from a TextField in another, but I get the error:
**-[ViewController name:]: unrecognized selector sent to instance 0x78712fe0**
when I run the app in the simulator.
Relevant code:
//UserInfo.h
#import <Foundation/Foundation.h>
#interface UserInfo : NSObject <NSCoding>
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *age;
#property (nonatomic, strong) NSString *address;
#end
//UserInfo.m
#import "UserInfo.h"
static NSString *nameKey = #"userName";
static NSString *ageKey = #"userAge";
static NSString *addressKey = #"userAddress";
static NSString *userInfoKey = #"userInfoKey";
#implementation UserInfo
#synthesize name;
#synthesize age;
#synthesize address;
- (id) initWithCoder:(NSCoder *)coder
{
self = [super init];
self.name = [coder decodeObjectForKey:nameKey];
self.age = [coder decodeObjectForKey:ageKey];
self.address = [coder decodeObjectForKey:addressKey];
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.name forKey:nameKey];
[coder encodeObject:self.age forKey:ageKey];
[coder encodeObject:self.address forKey:addressKey];
}
#end
//ViewController.h
#import <UIKit/UIKit.h>
#import "UserInfo.h"
#interface ViewController : UIViewController <UITextFieldDelegate, UITextViewDelegate, NSCoding>
#property (nonatomic, strong) UserInfo *userInfoObject;
#property (nonatomic, weak) IBOutlet UILabel *titleLabel;
#property (nonatomic, weak) IBOutlet UILabel *nameLabel;
#property (nonatomic, weak) IBOutlet UILabel *ageLabel;
#property (nonatomic, weak) IBOutlet UILabel *addressLabel;
#property (nonatomic, weak) IBOutlet UITextField *nameText;
#property (nonatomic, weak) IBOutlet UITextField *ageText;
#property (nonatomic, weak) IBOutlet UITextField *addressText;
#property (nonatomic, weak) IBOutlet UIButton *saveBtn;
- (IBAction)saveBtnTouched:(id)sender;
- (void) saveUserInfo;
- (void) loadUserInfo;
- (void) setUserInterfaceValues;
- (IBAction)nameText:(id)sender;
- (IBAction)ageText:(id)sender;
- (IBAction)addressText:(id)sender;
#end
//ViewController.m
#import "ViewController.h"
#import "UserInfo.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize titleLabel;
#synthesize nameLabel;
#synthesize ageLabel;
#synthesize addressLabel;
#synthesize nameText;
#synthesize ageText;
#synthesize addressText;
#synthesize saveBtn;
static NSString *userInfoKey = #"userInfoKey";
- (void)viewDidLoad {
[super viewDidLoad];
[self loadUserInfo];
if(!self.userInfoObject)
{
self.userInfoObject = [[UserInfo alloc] init];
}
[self setUserInterfaceValues];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
self.saveBtn.enabled = YES;
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
return YES;
}
- (BOOL) textFieldShouldEndEditing:(UITextField *)textField
{
[self.nameText resignFirstResponder];
[self.ageText resignFirstResponder];
[self.addressText resignFirstResponder];
return YES;
}
- (IBAction)saveBtnTouched:(id)sender
{
NSLog(#"%# was entered into the name field", self.nameText.text);
NSLog(#"%# was entered into the age field", self.ageText.text);
NSLog(#"%# was entered into the address field", self.addressText.text);
[self textFieldShouldEndEditing:self.nameText];
[self textFieldShouldEndEditing:self.ageText];
[self textFieldShouldEndEditing:self.addressText];
self.userInfoObject.name = self.nameText.text;
self.userInfoObject.age = self.ageText.text;
self.userInfoObject.address = self.addressText.text;
[self saveUserInfo];
self.saveBtn.enabled = NO;
}
- (void)saveUserInfo
{
NSData *userInfoData = [NSKeyedArchiver archivedDataWithRootObject:self.userInfoObject];
[[NSUserDefaults standardUserDefaults] setObject:userInfoData forKey:userInfoKey];
}
- (void)loadUserInfo
{
NSData *userInfoData = [[NSUserDefaults standardUserDefaults] objectForKey:userInfoKey];
if(userInfoData)
{
self.userInfoObject = [NSKeyedUnarchiver unarchiveObjectWithData:userInfoData];
}
}
- (void) setUserInterfaceValues
{
self.nameText.text = self.userInfoObject.name;
self.ageText.text = self.userInfoObject.age;
self.addressText.text = self.userInfoObject.address;
}
- (IBAction)nameText:(id)sender {
}
- (IBAction)ageText:(id)sender {
}
- (IBAction)addressText:(id)sender {
}
#end
//AppDelegate.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "UserInfo.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#end
//AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
#import "UserInfo.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
//all the other generated methods. Taken out due to space.
#end
Three breakpoints are set that are supposidly the source of the problem:
From the ViewController.m, in - (void)setUserInterfaceValues
self.nameText.text = self.userInfoObject.name;
(I assume that this applies to the other two lines below it also)
Also from the ViewController.m, in - (void)viewDidLoad
[self setUserInterfaceValues];
And finally from the AppDelegate.m, in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window.rootViewController = self.viewController;
From what I understand, and have learned from searching this issue, the app is trying to send data to something that doesn't exist, the NSString name being the culprit. Others have suggested to make sure that my .xib file is connected to the ViewController, and I have verified that it is.
As another bit of information, I'm not using a storyboard for this app, and instead am using the interface builder. I'm aware that there are advantages to storyboards, and I would like to be using them, but my company uses the interface builder and does a lot of things programmatically, so I'm learning to develop without.
[EDIT]: Issue solved thanks to Ian.
I'm new to iOS and I'm following this tutorial.
Here is a screenshot of me trying to connect an IBAction to my view.
I want to execute the method releaseKeyboard whenever I touch the view (ie. close the keyboard).
I'm not using storyboard.
My files:
challAppDelegate.h
challAppDelegate.m
challViewController.h
challViewController.m
challViewController.xib
challAppDelegate.h
#import <UIKit/UIKit.h>
#interface challAppDelegate : UIResponder <UIApplicationDelegate>
{
UINavigationController *navigationController;
}
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UINavigationController *navigationController;
#end
challAppDelegate.m
#import "challAppDelegate.h"
#import "challViewController.h"
#implementation challAppDelegate
#synthesize window = _window;
#synthesize navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *rootController =
[[challViewController alloc]
initWithNibName:#"challViewController" bundle:nil];
navigationController = [[UINavigationController alloc]
initWithRootViewController:rootController];
self.window = [[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
...
...
challViewController.h
#import <UIKit/UIKit.h>
#interface challViewController : UIViewController
#property(nonatomic, retain) IBOutlet UITextField *signInEmailAddress;
#property(nonatomic, retain) IBOutlet UITextField *signInPassword;
#property(nonatomic, retain) IBOutlet UIButton *signInSignInButton;
#property(nonatomic, retain) IBOutlet UIButton *signInRegisterButton;
-(void) releaseKeyboardAction;
-(IBAction) signInAction:(int)sender;
-(IBAction) registerAction:(int)sender;
-(IBAction) releaseKeyboard:(id)sender;
#end
challViewController.m
#import "challViewController.h"
#interface challViewController ()
#end
#implementation challViewController
#synthesize signInEmailAddress; // cria os getters e setters
#synthesize signInPassword; // cria os getters e setters
#synthesize signInSignInButton; // cria os getters e setters
#synthesize signInRegisterButton; // cria os getters e setters
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = #"Sign In";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)releaseKeyboardAction
{
[signInEmailAddress resignFirstResponder];
[signInPassword resignFirstResponder];
}
- (IBAction)releaseKeyboard:(id)sender
{
[self releaseKeyboardAction];
}
- (IBAction)registerAction:(int)sender
{
//
}
- (IBAction)signInAction:(int)sender
{
//
}
#end
What am I doing wrong?
Thanks
You can add a UITapGestureRecognizer to self.view.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = #"Sign In";
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(releaseKeyboardAction)];
[self.view addGestureRecognizer:gesture];
}
The target of the gesture recogniser points to your releaseKeyboardAction method.
Just change the view's class from UIView to UIControl in the identity inspector and then you can connect IBActions.
How to show an UIIimage by clicking on an UIButton inside another UIViewController? I would like to add to the same UIButton the command to add an image to the SecondViewController. Excused my poor question.
myProtocol.h
#import <Foundation/Foundation.h>
#protocol myProtocol <NSObject>
-(UIImage *)transferImage;
#end
ViewController.h
#import "SecondClass.h"
#interface ViewController : UIViewController<myProtocol, UINavigationControllerDelegate>{
UIView *view;
}
#property (nonatomic,retain) UIImageView *imageView;
- (IBAction)sendImage:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "SecondViewController.h"
#import "myProtocol.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
_imageView = [[UIImageView alloc]initWithImage:
[UIImage imageNamed:#"VoodooVibe#2x.png"]];
[view addSubview:_imageView];
NSLog(#"I am in VC.m");
}
-(UIImage *)transferImage{
NSLog(#"I am in transferImage");
return _imageView.image;
}
- (IBAction)sendImage:(id)sender {
SecondViewController *secClass = [[SecondViewController alloc]init];
secClass.delegate=self;
[secClass callTransfer];
NSLog(#"I am in sender");
[self.navigationController pushViewController:secClass animated:YES];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
SecondViewController.h
#import <UIKit/UIKit.h>
#import "myProtocol.h"
#import "ViewController.h"
#interface SecondViewController :UIViewController
<myProtocol,UINavigationControllerDelegate> {
UIView *secondView;
IBOutlet UIImageView *myImage;
id <myProtocol> myDelegate;
}
#property (nonatomic,retain) UIImageView *myImage;
#property(nonatomic,assign) id delegate;
-(void)callTransfer;
#end
SecondViewController.m
#import "SecondViewController.h"
#import "ViewController.h"
#import "myProtocol.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize delegate,myImage;
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view.
[secondView addSubview:myImage];
}
-(void)callTransfer{
myImage.image=[delegate performSelector:#selector(transferImage)];
myImage.image=[UIImage imageNamed:#"VoodooVibe#2x.png"];
NSLog(#"%#",myImage.image);
NSLog(#"I am in call transfer");
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Delegates should normally be used, if you you have a class included inside your UIViewController which will do something and notify you with the delegate method when the specific process has finished. But in this case you would set an UIImage two times. Once by your delegate and a second time by setting an UIImage programmatically.
You shouldn't do anything like calling a method for initializing the UIImage of the second UIViewController from outside. Just call everything inside viewDidLoad and you don't have to care about it, because the UIViewController handles it itself.
You just have to insert an UIImageView inside your SecondViewController and connect it to your header file. then you can access it inside the m. file. I had the problem that I first used a jpg instead of a png, but after changing the suffix everything worked fine.
ViewController.m
- (IBAction)sendImage:(id)sender {
SecondViewController *secClass = [[SecondViewController alloc] init];
[secClass setImageName:#"pic.png"];
[self.navigationController pushViewController:secClass
animated:YES];
}
SecondViewController.h
#interface SecondViewController : UIViewController
#property (strong, nonatomic)NSString *imageName;
#property (weak, nonatomic) IBOutlet UIImageView *myImage;
#end
SecondViewController.m (There are just these two lines)
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[_myImage setImage:[UIImage imageNamed:_imageName]];
}