iOS: Changing UIButton Title through Delegate - ios

I'm using delegation to change the title of a UIButton.
.h MainView
//MainViewController.h
#import <UIKit/UIKit.h>
#class SignUpDelegate;
#protocol SignUpDelegate <NSObject>
#required
-(void)loggedIn;
#end
#interface MainViewController : UITableViewController <NSFetchedResultsControllerDelegate>
{
id <SignUpDelegate> delegate;
}
#property (nonatomic, assign) id <SignUpDelegate> delegate;
-(void)loggedIn;
#end
.m
#interface MainViewController ()
//This button is connected to the UINavigationBar Button that needs its title changed.
//Via Interface Builder, the default value of the title is setup as "Login"
-#property (weak, nonatomic) IBOutlet UIBarButtonItem *logInOutButton;
#end
-(void)loggedIn
{
NSLog (#"This is Logged in inside MainView.m");
self.logInOutButton.title = #"Logout";
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destinationViewController = segue.destinationViewController;
Signup *signUp = [destinationViewController isKindOfClass:[Signup class]] ? (Signup*)destinationViewController : nil;
signUp.mainViewController = self.delegate;
}
.h SignUp
#import <UIKit/UIKit.h>
#import "MainViewController.h"
#interface SignUp : UIViewController <UITextFieldDelegate, UIActionSheetDelegate, SignUpDelegate>
#property (strong, nonatomic) MainViewController *mainViewController;
#end
.m
#synthesize mainViewController;
- (IBAction)createUser:(id)sender
{
[self loggedIn];
}
- (void) loggedIn
{
NSLog (#"This is Logged in inside SignUp");
[mainViewController loggedIn];
}
So, both NSLogs Print fine, which I think means the delegate is working, however, the title on the UIButton on the Navigation Bar never changes to "Logout"

That's because you recreate STMasterViewController (should this have been MainViewController instead?) every time in the loggedIn delegate method. (You can verify this by adding a breakpoint on -[MainViewController loggedIn] and checking if self.logInOutButton is non-nil). Instead you should get the reference to existing instance of MainViewController and operate on that.

Related

delegate become nil iOS

I created a custom UIView with the buttons above , this view opens as a pop- up to a viewcontroller . I want the view controller intercepts the pressure of the buttons so I created a protocol methods but delegates in the view controller is never called.
The protocol:
#protocol InsertDelegate <NSObject>
-(void)addNode:(double)x pointY:(double)y radius:(double)r forw:(int)forw;
-(void)cancelView:(UIView*)view;
#end
In the AddNewNode.h
#interface AddNewNode : UIView
#property (assign, nonatomic)id <InsertDelegate> delegate;
- (IBAction)actionCancel:(id)sender;
- (IBAction)actionAdd:(id)sender;
#end
In the AddNewNode.m
- (IBAction)actionCancel:(id)sender { //this action is connect with storyboard
NSLog(#"%#", self.delegate);
//(null)
[self.delegate cancelView:self];
}
- (IBAction)actionAdd:(id)sender { //this action is connect with storyboard
NSLog(#"%#", self.delegate);
//(null)
[self.delegate addNode:x pointY:y radius:r forw:f];
}
In ViewController.h:
#interface ViewController : UIViewController <InsertDelegate>
In ViewController.m
(IBAction)addNewNode:(id)sender {
AddNewNode * addRowView =[[AddNewNode alloc]init];
addRowView.delegate=self;
[self.view addSubview: addRowView];
}
//delegate methods never called
-(void)addNode:(double)x pointY:(double)y radius:(double)r forw:(int)forw{
}
-(void)cancelView:(UIView*)view{
}
In UIView custom self.delegate become null and I don't understand why
What about making an IBOutlet for your
ViewController.h
#interface ViewController : UIViewController <InsertDelegate>
#property (strong, nonatomic) AddNewNode * addNewNode;
//or connect IBOutlet of your `addNewNode`
#property (strong, nonatomic) IBOutlet (addNewNode);
#end
ViewController.m
- (IBAction)addNewNode:(id)sender
{
// you dont need to allocate anymore
self.addRowView.delegate=self;
// and you need to trigger the delegate from `- (IBAction)actionAdd:(id)sender;`
[self.addRowView actionAdd:sender];
}
try the following
Create a private property to hold the instance
#implement AddNewNode()
#propery (nonatomic, strong) AddNewNode * addNewNode;
#end
from inside the button handler
(IBAction)addNewNode:(id)sender {
self.addNewNode =[[AddNewNode alloc]init];
self.addRowView.delegate=self;
}

Pass value from controller to controller

I'm building my first iOS app to try and learn iOS coding. However, I need to pass a value xAuthToken from one controller to the other. I can't seem to get it working to. I init the value in the first controller ViewController, but then I need it in SettingsController. I keep getting errors and the one it throws now is: Property 'ViewController' not found on object of type 'ViewController'
What am I doing wrong?
ViewController.h
#import <UIKit/UIKit.h>
#import "SettingsController.h"
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtPassword;
- (IBAction)sigininClicked:(id)sender;
- (IBAction)backgroundTap:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) NSString *xAuthToken;
#end
#implementation ViewController
- (IBAction)sigininClicked:(id)sender {
NSString *xAuthToken = #"0";
self.viewController = [[SettingsController alloc] init];
self.viewController.xAuthToken = xAuthToken;
[self performSegueWithIdentifier:#"login_success" sender:self];
}
SettingsController.h
#import <Foundation/Foundation.h>
#interface SettingsController : UIViewController
#end
SettingsController.m
#interface SettingsController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextField;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation SettingsController
//THIS IS WHERE I NEED XAUTHTOKEN
If you have a segue that presents your SettingsController, pass the information it needs in prepareForSegue. Don't create a new local SettingsController.
You can do something like
viewController = [self.storyboard instantiateviewcontrollerwithidentifier:#"your vc name"];
viewController.Xauthtoken = data;
// Do something else with this.
Or another way ( I don't know if it's good or bad, use it while your vc is already active ):
Use NSNotificationCenter and pass values between it.
Third way is create delegate for first Viewcontroller.
Try this in your ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) NSString *xAuthToken;
#end
#implementation ViewController
- (IBAction)sigininClicked:(id)sender {
xAuthToken = #"Your Value Here";
[self performSegueWithIdentifier:#"login_success" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"login_success"]) {
SettingsController *destViewController = segue.destinationViewController;
destViewController.xAuthToken = xAuthToken;
}
}
And in your SettingsController.h
#import <Foundation/Foundation.h>
#interface SettingsController : UIViewController
#property (nonatomic,strong) NSString *xAuthToken;
#end
SettingsController.m
#interface SettingsController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextField;
#property (weak, nonatomic) IBOutlet UISwitch *mySwitch;
#end
#implementation SettingsController
-(void)viewDidLoad{
NSLog("%#",xAuthToken);
}

Storing info from UITextField back to detailTextLabel

I have a tableViewCell that says Nickname and when you click on it, a segue takes you to a view controller with a text field where you can type a nickname, once you push the back button it should appear in the detailTextLabel of the main table view controller. I just keep getting an error I posted the code below where I get an error as well.
nickname text field code:
#import "NicknameViewController.h"
#interface NicknameViewController ()
#end
#implementation NicknameViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.delegate updateCarNickname:self.nicknameField];
}
#end
Here is the header file for the nickname view controller:
#import <UIKit/UIKit.h>
#protocol CarNicknameDelegate <NSObject>
#optional
- (void)updateCarNickname:(UITextField *)updateNickname;
#end
#interface NicknameViewController : UIViewController
#property (nonatomic, weak) id <CarNicknameDelegate> delegate;
#property (strong, nonatomic) IBOutlet UITextField *nicknameField;
#end
In the main view controller I keep getting errors on this code and can't seem to figure it out:
-(void)updateCarNickname:(UITextField *)updateNickname {
self.nicknameCell.detailTextLabel.text = updateNickname;
}
Before the segue begins I used this code:
if ([segue.identifier isEqualToString:#"nicknameSegue"]) {
NicknameViewController *controller = segue.destinationViewController;
controller.delegate = self;
}
All views in a view controller gets deallocated once the view controller's dealloc is called.
You should change your CarNicknameDelegate's parameter UITextField to NSString.
#protocol CarNicknameDelegate <NSObject>
#optional
- (void)updateCarNickname:(UITextField *)updateNickname;
#end
and change your NicknameViewController to something like this.
#interface NicknameViewController ()
#end
#implementation NicknameViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.delegate updateCarNickname:self.nicknameField.text];
}
#end

Simple delegate example for iOS not working

I know there are tons of questions out there about passing messages between different view controllers. I've checked them all but I can't get it working.
I've followed this tutorial: http://www.youtube.com/watch?v=XZWT0IV8FrI replacing the storyboard with a navigation controller but I run across the following issue over and over again: 'Cannot find protocol declaration for...'
Here is the code:
FirstViewController.h
#import "SecondViewController.h"
#interface FirstViewController : UIViewController <SecondViewControllerDelegate>{
//In this line above is where I get the error 'Cannot find protocol declaration for SecondViewControllerDelegate'
IBOutlet UITextField *userNameTextField;
}
#property (nonatomic, strong) UITextField *userNameTextField;
-(IBAction)goNext:(id)sender;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize userNameTextField;
-(void)goNext:(id)sender{
SecondViewController *secondVC = [[SecondViewController alloc]init];
secondVC.delegate = self;
[self.navigationController pushViewController:secondVC animated:YES];
}
-(void)done:(NSString*)name{
NSLog(#"BACK in firstVC");
userNameTextField.text = name;
}
#end
SecondViewController.h
#import "FirstViewController.h"
#protocol SecondViewControllerDelegate <NSObject>
-(void)done:(NSString*)someText;
#end
#interface SecondViewController : UIViewController{
IBOutlet UITextField *someText;
IBOutlet UIButton *returnButton;
id delegate;
}
#property (assign, nonatomic) id <SecondViewControllerDelegate> delegate;
#property (strong, nonatomic) UITextField *someText;
-(IBAction)goBack:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize someText;
#synthesize delegate = _delegate;
-(void)goBack:(id)sender{
[self.delegate done:someText.text];
FirstViewController *firstVC = [[FirstViewController alloc]init];
[self.navigationController pushViewController:firstVC animated:YES];
}
#end
In your SecondViewController goBack implementation you are creating a new FirstViewController rather than popping your navigation controller, code should read...
-(void)goBack:(id)sender{
[self.delegate done:someText.text];
[self.navigationController popViewControllerAnimated:YES];
}
And also in your SecondViewController.h remover this #import "FirstViewController.h" as it is no longer needed and could be confusing the compiler
Your protocol name is EYSSecondViewControllerDelegate:
#protocol EYSSecondViewControllerDelegate <NSObject>
but you call it SecondViewControllerDelegate in two places:
#interface EYSFirstViewController : UIViewController <SecondViewControllerDelegate>{...
#property (assign, nonatomic) id <SecondViewControllerDelegate> delegate;...
Make sure that the name match and it should works fine.
In SecondViewController.h
remove line id delegate;
In SecondViewController.m
Update code -> [delegate done:someText.text];
'self.' remove
Try it

save method and delegate in detailTableViewController fail in Xcode

I have a bug when I save information passed by a user in a detailTableViewController. Though when I force the debugger by pressing lecture, it carries on performing the coredata job, etc.
Here is my structure:
A detailTableViewController which presents staticcells that the user fills and then passed to the coredata.
It implements a delegate for the MainTableViewController to pop over it.
PhraseDetailTableViewController.h:
#import <UIKit/UIKit.h>
#import "Phrase.h"
#class PhraseDetailTableViewController;
#protocol AddPhraseTVCDelegate
- (void) theSaveButtonOnThePhraseDetailWasTapped:(PhraseDetailTableViewController *) controller;
#end
#interface PhraseDetailTableViewController : UITableViewController
#property (strong,nonatomic) NSManagedObjectContext *managedObjectContext;
#property (nonatomic,weak) id <AddPhraseTVCDelegate> delegate;
#property (strong, nonatomic) IBOutlet UITextField *phraseMotivationTextField;
- (IBAction)save:(id)sender;
#end
PhraseDetailTableViewController.m :
- (void)save:(id)sender
{
NSLog(#"Telling the PhraseDetailTableViewController Delegate that Save was tapped on the PhraseDetailTableViewController");
Phrase *phrase = [NSEntityDescription insertNewObjectForEntityForName:#"Phrase" inManagedObjectContext:self.managedObjectContext];
phrase.motivation = phraseMotivationTextField.text;
NSLog(#"la phrase est %#", phrase.motivation);
[self.managedObjectContext save:nil];
[self.delegate theSaveButtonOnThePhraseDetailWasTapped:self];
NSLog(#"le message savebuttononethe.. a ete envoyé");
}
I delegated it to the main, here is the .H and .m
PhraseTableViewController.h :
#import <UIKit/UIKit.h>
#import "PhraseDetailTableViewController.h"
#import "CoreDataTableViewController.h"
#import "Phrase.h"
#interface PhraseTableViewController : CoreDataTableViewController <AddPhraseTVCDelegate>
#property (strong,nonatomic) NSFetchedResultsController *fetchedResultsController;
#property (strong,nonatomic) NSManagedObjectContext *managedObjectContext;
#end
PhraseTableViewController.m (extract where i pass the delegate and It receive the delegate method):
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"Add Phrase Segue"])
{
NSLog(#"Seeting PhraseTVC as a delegate of PhraseDetailTableViewController");
PhraseDetailTableViewController *phraseDetailTableViewController= segue.destinationViewController;
phraseDetailTableViewController.delegate=self;
phraseDetailTableViewController.managedObjectContext=self.managedObjectContext;
}
}
- (void)theSaveButtonOnThePhraseDetailWasTapped:(PhraseDetailTableViewController *)controller
{
[controller.navigationController popViewControllerAnimated:YES];
NSLog(#"c'est la methode en elle meme qui chie");
}
I think there is something to do with the subclassing of the Main/detail and its inherited delegate. But i can't figure out what exactly implies this bug :s
CHeers,
Louis

Resources