iOS: trouble sharing data between two view controllers - iphone

I have an app, which has a first view controller called MainViewController that's sorta like a stopwatch, and when I click finish, it displays a UIAlertView pushes another view controller, EndViewController, which shows how long the stopwatch was running and how long it was paused. I am getting the following errors:
My Point[851:c07] -[EndViewController topViewController]: unrecognized selector sent to instance 0x754db60
My Point[851:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[EndViewController topViewController]: unrecognized selector sent to instance 0x754db60'
Can anyone point ou to me what's wrong?
heres my code:
MainViewController.h:
#import "EndViewController.h"
#interface MainViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate, UIAlertViewDelegate>
#property (strong, nonatomic) IBOutlet UILabel *out;
#property (strong, nonatomic) IBOutlet UILabel *in;
#end
MainViewController.m:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"endtask"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
EndViewController *controller = (EndViewController *)navController.topViewController;
controller.timeIn.text=_in.text;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
_alert = [[UIAlertView alloc] initWithTitle:#"Are you sure?"
message:nil
delegate:self
cancelButtonTitle:#"NO"
otherButtonTitles:#"YES", nil];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
//do nothing
}
else if (buttonIndex == 1) {
[self performSegueWithIdentifier:#"endtask" sender:self];
}}
- (IBAction)endButton:(UIButton *)sender {
[_alert show];
}
- (IBAction)endButton:(UIButton *)sender {
[_alert show];
}
EndViewController.h:
#interface EndViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *timeIn;
#end

You're calling a method named topViewController on an object which doesn't have the method/property. It's this line here:
EndViewController *controller = (EndViewController *)navController.topViewController;
I would suspect its because the view controller you are assigning to navController isn't actually a navigation controller, but is something else. Check your storyboards/nibs for this.
Also, try logging navController, as one commentor said, and see what that gives you.
NSLog(#"%#", navController);

If you are passing a string with timeIn you should have #property of a NSString in the endViewController.h
#property (strong, nonatomic) NSString * timeIn ;
Then in you endViewController.m you put the timeIn into a labe for example.
myLabel.text = timeIn;

Related

Trying to dismiss a view controller by tap on cancel using delegation (Not working at all)

Having two view controller within a navigation controller:
PhoneNumbersTVC > holds a list of phone numbers added by NewPhoneNumberTVC
NewPhoneNumberTVC > a controller for adding phone numbers
When I tap on cancel on NewPhoneNumberTVC I like to get back to PhoneNumbersTVC with a delegation as follow.
PhoneNumbersTVC.h
#import <UIKit/UIKit.h>
#import "NewPhoneNumberTVC.h"
#interface PhoneNumbersTVC : UITableViewController <NewPhoneNumberTVCDelegate>
#end
PhoneNumbersTVC.m
- (void)saveBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC
{
NSLog(#"saveBtnWasTappedOnNewPhoneNumberTVC");
[newPhoneNumberTVC.navigationController popViewControllerAnimated:YES];
}
- (void)cancelBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC
{
NSLog(#"cancelBtnWasTappedOnNewPhoneNumberTVC");
[newPhoneNumberTVC.navigationController popViewControllerAnimated:YES];
}
NewPhoneNumberTVC.h
#import <UIKit/UIKit.h>
#class NewPhoneNumberTVC;
#protocol NewPhoneNumberTVCDelegate <NSObject>
- (void)saveBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC;
- (void)cancelBtnWasTappedOnNewPhoneNumberTVC:(NewPhoneNumberTVC *)newPhoneNumberTVC;
#end
#interface NewPhoneNumberTVC : UITableViewController
#property (weak, nonatomic) id <NewPhoneNumberTVCDelegate> delegate;
#property (strong, nonatomic) NSManagedObjectContext *managedOC;
#property (weak, nonatomic) IBOutlet UITextField *phoneNumberTextField;
- (IBAction)saveBtnTapped:(UIBarButtonItem *)sender;
- (IBAction)cancelBtnTapped:(UIBarButtonItem *)sender;
#end
NewPhoneNumberTVC.m
- (IBAction)cancelBtnTapped:(UIBarButtonItem *)sender
{
NSLog(#"cancelBtnTapped");
self.phoneNumberTextField.text = #"";
self.phoneKindTextField.text = #"";
[self.delegate cancelBtnWasTappedOnNewPhoneNumberTVC:self];
}
When I tap on cancel on NewPhoneNumberTVC I see that above method cancelBtnTapped fires but delegation does not work, no method executes in PhoneNumbersTVC. View doesn't go away and I don't see: cancelBtnWasTappedOnNewPhoneNumberTVC on console.
If you want this method cancelBtnWasTappedOnNewPhoneNumberTVC: get called, you definitely need to set the delegate of your NewPhoneNumberTVC object to a PhoneNumbersTVC object. For example, there should be existing some codes in PhoneNumbersTVC.m :
NewPhoneNumberTVC *myNewPhoneNumberTVC = [[NewPhoneNumberTVC alloc] init];
myNewPhoneNumberTVC.delegate = self;
You can log as following to verify that the delegate is set successfully or not"
NewPhoneNumberTVC.m
- (IBAction)cancelBtnTapped:(UIBarButtonItem *)sender
{
NSLog(#"cancelBtnTapped");
self.phoneNumberTextField.text = #"";
self.phoneKindTextField.text = #"";
NSLog(#"self.delegate :%#",self.delegate);
[self.delegate cancelBtnWasTappedOnNewPhoneNumberTVC:self];
}

Clicking a button in UIActionSheet causes my app to crash

I'm trying to implement a UIActionSheet which will have some sharing buttons on it for sharing to twitter, facebook, email and print.
Here is my share view controller.h
#interface ShareViewController : UITableViewController <UIActionSheetDelegate, MFMailComposeViewControllerDelegate>
#property (nonatomic, strong) NSMutableDictionary *services;
#property (strong, nonatomic) UIActionSheet *actionSheet;
#property (strong, nonatomic) id <ShareViewControllerDelegate> delegate;
#property (nonatomic, strong) UIPopoverController *popCon;
#property (nonatomic, strong) NSString *serviceTitle;
-(IBAction)loadActionSheet:(id)sender;
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
- (void)tweetThis;
- (void)printThis;
- (void)openMail;
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error;
#end
Here is my share view controller.m
-(IBAction)loadActionSheet:(id)sender{
if (self.actionSheet) {
// do nothing
}
else {
UIActionSheet *sharing = [[UIActionSheet alloc]
initWithTitle:nil
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:#"Twitter", #"Facebook", #"Email", #"Print", nil];
[sharing showFromBarButtonItem:sender animated:YES];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(#"Button index: %d",buttonIndex);
switch (buttonIndex) {
case 0:
[self tweetThis];
break;
case 1:
[self sendToFacebook];
break;
case 2:
NSLog(#"email");
[self openMail];
break;
case 3:
NSLog(#"Print");
[self printThis];
break;
default:
NSLog(#"Error");
break;
}
}
I ma initiaalising my share view controller in main view controller.m as follows:
- (IBAction)shareButtonTapped:(id)sender {
ShareViewController *svc = [[ShareViewController alloc] initWithStyle:UIActionSheetStyleDefault];
[svc loadActionSheet:(id)sender];
}
I can open the action sheet fine, but when I click on any of the buttons, it crashes the app. Any ideas as to why?
This is most likely a memory-management issue. It looks like you're using ARC, so after the shareButtonTapped method returns, ARC will automatically release svc, as it's no longer referenced anywhere. The delegate property of the action sheet is weak, so it's not retained by that either.
I don't really see why ShareViewController is a view controller in the first place, as you never seem to be loading its view, but you may have your reasons... In any case, you should make that controller a strong property or instance variable of your other (main) view controller, so that it's not automatically released before the action sheet finishes.
Yes. Go to your .xib file.
You should see all the buttons you have.
Click on a button and go to the "Connections Inspector"
Delete the referencing outlet.
Drag the referencing outlet to the button and set the button to the "ID" you want.
Let me know if that works.
Just a stupid answer - the methods like - (void) sendToFacebook; are implemented, right?

Delegate not getting set in iOS5 StoryBoard UISplitViewController

I have a Universal app with UISplitViewConroller. I am using storyboards.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *masterNavigationController = [splitViewController.viewControllers objectAtIndex:0];
LeftViewContrller *lcontroller = (LeftViewContrller *)masterNavigationController.topViewController;
id<SplitViewDelegate> rightController = (id<SplitViewDelegate>)[splitViewController.viewControllers objectAtIndex:1];
lcontroller.delegate = rightController;
}
I have a left and right controller for UISplitViewController app.
LeftViewController has a custom delegate, which is set as RightViewController.
//Custom delegate
#protocol SplitViewDelegate <NSObject>
- (void) matchSelectionChanged:(NSString *)curSelection;
#end
//LeftViewContoller
#interface LeftViewContrller : UITableViewController {
id<SplitViewDelegate> _delegate;
NSMutableArray *_matches;
}
#property (strong) id<SplitViewDelegate> delegate;
#property (strong) NSMutableArray *matches;
#end
RightViewController implements this delegate protocol. However, when cell inside row is clicked in LeftViewController the delegates failing.
//RightViewController
#interface RightViewController : UIViewController <SplitViewDelegate>
#property (weak,nonatomic) IBOutlet UILabel *matchLabel;
#end
//Implementation of RightViewController
- (void) matchSelectionChanged:(NSString *)curSelection {
self.matchLabel.text = curSelection;
//[self refresh];
}
//Did select row in LeftViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableString *s = [[NSMutableString alloc] initWithString:#"Row selected"];
if (_delegate != nil) {
[s appendFormat:#" %d ", indexPath.row];
[_delegate matchSelectionChanged:s];
}
}
//Get error
CustomViewTab[1200:11303] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController matchSelectionChanged:]: unrecognized selector sent to instance 0xda6a770'
* First throw call stack:
(0x1559052 0x1da8d0a 0x155aced 0x14bff00 0x14bfce2 0x1204e 0x62071d 0x620952 0x25986d 0x152d966 0x152d407 0x14907c0 0x148fdb4 0x148fccb 0x2500879 0x250093e 0x590a9b 0x1df8 0x1d55)
terminate called throwing an exception
I see didSelectRowAtIndex called but then RightViewController's matchSelectionChanged:(NSString *)curSelection never gets called.
Bit of an old question but I stumbled up on it and at a glance do you have the correct delegate?
#interface RightViewController : UIViewController <UISplitViewControllerDelegate>
I'm looking at iOS7 so maybe its changed since iOS5

Resign keyboard immediately after button press

I have a button, "getResponse", that makes a XMLRPC call to a server after you put in an IP address in a UITextField. Id like the "getResponse" button to first resign the keyboard if its up THEN make the call to the server.
As it is now, if the keyboard is up, it will make the call to the server, retrive the info or the error if no valid server found, THEN resign the keyboard.
I know its probably something very easy but I can't for the life of me figure it out. Any help would be great, thanks!
Code:
h.
#import <UIKit/UIKit.h>
#import "XMLRPCResponse.h"
#import "XMLRPCRequest.h"
#import "XMLRPCConnection.h"
#interface SecondViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate> {
IBOutlet UILabel *helloResponse;
IBOutlet UILabel *SumCountsResponse;
IBOutlet UITextField *serverInput;
IBOutlet UIPickerView *pickerView;
IBOutlet UILabel *pickerTrap;
IBOutlet UIAlertView *alert;
NSMutableArray * pickerViewArray;
int trapSelected;
}
#property(nonatomic,retain) IBOutlet UILabel *helloResponse;
#property(nonatomic,retain) IBOutlet UILabel *SumCountsResponse;
#property(nonatomic,retain) IBOutlet UITextField *serverInput;
#property(nonatomic,retain) IBOutlet UIPickerView *pickerView;
#property(nonatomic,retain) IBOutlet UILabel *pickerTrap;
#property(nonatomic,retain) IBOutlet UIAlertView *alert;
- (IBAction)getResponse:(id)sender;
- (IBAction)serverInputReturn:(id)sender;
- (IBAction)backgroundTouched:(id)sender;
#end
m.
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize helloResponse;
#synthesize SumCountsResponse;
#synthesize serverInput;
#synthesize pickerView;
#synthesize pickerTrap;
#synthesize alert;
-(IBAction)serverInputReturn:(id)sender { //resign keyboard on 'return' button
[sender resignFirstResponder];
}
-(IBAction)backgroundTouched:(id)sender { //resign keyboard on background touch
[serverInput resignFirstResponder];
}
-(IBAction)getResponse: (id) sender {
[self serverInputReturn:self]; //trying to call method to resign keyboard first
//setup IP call for XMLserver
NSString *server = serverInput.text;
NSString *http = #"http://";
server = [server stringByAppendingString:#":8080/RPC2"];
server = [http stringByAppendingString:server];
//Begin calls to XMLRPC server for data return
XMLRPCRequest *requestHello = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
[requestHello setMethod:#"hello" withObjects:[NSArray arrayWithObjects: nil]];
NSString *resultHello = [self executeXMLRPCRequest:requestHello];
[requestHello release];
XMLRPCRequest *requestSumCounts = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
[requestSumCounts setMethod:#"SumCountsString" withObjects:[NSArray arrayWithObjects: nil]];
NSString *resultSumCounts = [self executeXMLRPCRequest:requestSumCounts];
[requestSumCounts release];
XMLRPCRequest *requestTrapCountX = [[XMLRPCRequest alloc] initWithHost:[NSURL URLWithString:server]];
[requestTrapCountX setMethod:#"TrapCountString" withObjects:[NSArray arrayWithObjects: [NSNumber numberWithInt:trapSelected], nil]];
NSString *resultTrapCountX = [self executeXMLRPCRequest:requestTrapCountX];
[requestTrapCountX release];
if (![resultHello isKindOfClass:[NSString class]]){
alert = [[UIAlertView alloc] initWithTitle:#"Error: Invalid Server Address" message:#"Please Check Server Address and Try Again" delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
}
else{
helloResponse.text = resultHello;
SumCountsResponse.text = resultSumCounts;
pickerTrap.text = resultTrapCountX;
}
}
}
- (id)executeXMLRPCRequest:(XMLRPCRequest *)req {
XMLRPCResponse *userInfoResponse = [XMLRPCConnection sendSynchronousXMLRPCRequest:req];
if ([userInfoResponse isKindOfClass:[NSError class]]) {
return alert;
}
else{
return [userInfoResponse object];
}
}
Instead of
[self serverInputReturn:self];
Try
[self serverInputReturn:self.serverInput];
You need to pass the UITextField not the UIViewController.
Make sure that you are setting the UITextField's delegate to the UIViewController via
self.serverInput.delegate = self;

Iphone : unrecognized selector sent to instance & viewDidLoad isn't running

I'm developing an application.
I used a TabBar and every tab have its Class (FirstViewController, SecondViewController, ... )
There is one AppDelegate too.
When I launch the program, the first Class is running.
When i select the second tab, the Secondview.xib 's running but the "viewDidLoad" isn't working.
When I select the third Tab, that's the same.
I've put some buttons on the third tab, and when I push it, I have a
> -[UIViewController testAuthentication:]: unrecognized selector sent to instance 0x5f16920
2011-04-08 13:46:42.511 e-mars[19501:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController testAuthentication:]: unrecognized selector sent to instance 0x5f16920'
Here's the code of my classes
SecondViewController.h
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController {
}
#end
SecondViewController.m
#import "SecondViewController.h"
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"viewDidLoad de SecondViewController");
NSURL *url = [NSURL URLWithString: #"http://iosdevelopertips.com/images/logo-iphone-dev-tips.png"];
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
[self.view addSubview:[[UIImageView alloc] initWithImage:image]];
}
- (void)dealloc {
[super dealloc];
}
#end
ThirdViewController.h
#import <UIKit/UIKit.h>
#interface ThirdViewController : UIViewController {
IBOutlet UITextField *login;
IBOutlet UITextField *motdepasse;
NSMutableData *responseData;
}
#property (retain, nonatomic) UITextField *login;
#property (retain, nonatomic) UITextField *motdepasse;
#property (retain, nonatomic) NSMutableData *responseData;
- (IBAction) testAuthentication: (id)sender;
- (IBAction) saveAuthentication: (id)sender;
#end
ThirdViewController.m
#import "ThirdViewController.h"
#implementation ThirdViewController
#synthesize login;
#synthesize motdepasse;
#synthesize responseData;
- (id)initWithFrame:(CGRect)frame {
//if ((self = [super initWithFrame:frame])) {
// Initialization code
//}
return self;
}
-(IBAction) testAuthentication: (id)sender {
//NSLog(#"testAuthentication");
}
- (IBAction) saveAuthentication: (id)sender {
NSLog(#"saveAuthentication");
}
- (void)dealloc {
[login dealloc];
[motdepasse dealloc];
[responseData dealloc];
[super dealloc];
}
#end
Your third ViewController doesn't actually create an instance, so no instance methods can be called upon it. Fix your initWithFrame: method. Remember: instance methods start with the '-' sign, class methods start with the '+' sign.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithNibName:nil bundle:nil];
if (self)) {
// Initialization code
}
return self;
}
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
{
return [self initWithFrame:CGRectZero];
}
- (id)init
{
return [self initWithFrame:CGRectZero];
}
After you fixed this, at least the viewDidLoad method in the third ViewController should work.
With regards to the second ViewController, could you please show the code you use to instantiate the ViewController?
Edit: I've made some changed to make sure initWithFrame: is always called upon initialization, just in case you create the instance using another method (initWithNibName:bundle: or init), now initWithFrame: has become the designated initializer.
Set class in Viewcontroller.
and then try.
Check the Object On which your are calling testAuthentication
May be you are calling testAuthentication on secondViewController's object , Just check and let us know
First time alone the viewController will come from viewDidLoad after that it does not call viewDidLoad instead it calls viewWillAppear. so you can code whatever you want in viewWillAppear.