Resign keyboard immediately after button press - iphone

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;

Related

iOS: trouble sharing data between two view controllers

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;

How do I get my segment UISegmentedControl to respond?

In my ViewController I have added A UISegmentedControl to preform different task for a different selection of the Segmented Control. Its a cards matching game.
And everything seems to work just fine, except that the Segmented Control is not reacting to the selection.., I created a switch to do something in case of "twoCardGame" and in case of "threeCardGame".
From what I understand it would be good to define those variables with enum, which I did in the top part of the controller, but it seems like i'm missing something in it..
Sorry if its not so directed, but my controller is pretty short and simple, would appreciate if you can tell me what am I doing wrong in term of the UISegmentedControl.
Here it is:
#import "CardGameViewController.h"
#import "PlayingCardsDeck.h"
#import "CardMatchingGame.h"
enum CardGame {
twoCardGame,
threeCardGame
};
#interface CardGameViewController ()
#property (weak, nonatomic) IBOutlet UILabel *notificationLabel;
#property (weak, nonatomic) IBOutlet UILabel *scoreCounter;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
#property (strong, nonatomic) CardMatchingGame *game;
#property (weak, nonatomic) IBOutlet UISegmentedControl *numberOfCardsToPlayWith;
#end
#implementation CardGameViewController
//creating the getter method that creates a new card game.
- (CardMatchingGame *)game {
if (!_game) {
_game = [[CardMatchingGame alloc] initWithCardCount:self.cardButtons.count
usingDeck:[[PlayingCardsDeck alloc] init]];
_game.numberOfCardsToPlayWith = [self selectNumberOfCardsToPlayWith];
}
return _game;
}
//creating a setter for the IBOutletCollection cardButtons
-(void)setCardButtons:(NSArray *)cardButtons {
_cardButtons = cardButtons;
[self updateUI];
}
- (void)updateUI {
for (UIButton *cardButton in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];
[cardButton setTitle:card.contents forState:UIControlStateSelected];
[cardButton setTitle:card.contents
forState:UIControlStateSelected|UIControlStateDisabled];
cardButton.selected = card.isFaceUp;
cardButton.enabled = !card.isUnplayable;
cardButton.alpha = card.isUnplayable ? 0.3 : 1.0;
}
self.scoreCounter.text = [NSString stringWithFormat:#"Score: %d", self.game.score];
}
//Here I created a method to flipCards when the card is selected, and give the user a random card from the deck each time he flips the card. After each flip i'm incrementing the flipCount setter by one.
- (IBAction)flipCard:(UIButton *)sender {
[self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender]];;
[self updateUI];
}
//sending an alert if the user clicked on new game button
- (IBAction)newGame:(UIButton *)sender {
UIAlertView* mes=[[UIAlertView alloc] initWithTitle:#"Think about it for a sec..?" message:#"This will start a new game" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[mes show];
}
- (NSUInteger)selectNumberOfCardsToPlayWith {
switch (self.numberOfCardsToPlayWith.selectedSegmentIndex) {
case twoCardGame:
return 2;
case threeCardGame:
return 3;
default:
return 2;
}
[self updateUI];
}
//preforming an action according to the user choice for the alert yes/no to start a new game
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex]) {
self.game = nil;
for (UIButton *button in self.cardButtons) {
Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:button]];
card.isUnplayable = NO;
card.isFaceUp = NO;
button.alpha = 1;
}
self.notificationLabel.text = nil;
[self updateUI];
}
}
#end
Well, I don't see any addTarget: calls to segmented control. So you probably set them in Interface Builder. Check IB connections. If everything in IB seems ok -- try to addTarget: programmatically.
I think you'd be better off creating a selector and adding it to the segmented control target like so:
[segmentedControl addTarget:self
action:#selector(selectNumberOfCardsToPlayWith:)
forControlEvents:UIControlEventValueChanged];
- (NSUInteger)selectNumberOfCardsToPlayWith:(UISegmentedControl *)control {
switch (control.selectedSegmentIndex) {
case twoCardGame:
return 2;
case threeCardGame:
return 3;
default:
return 2;
}
[self updateUI];
}
This should work fine. Using similar code myself currently.

How to show a custom uialertview created in interface builder

I've created a custom uialertview in ib, with two button and a textfield.
Then i create a .h and a .m in this way:
#import <UIKit/UIKit.h>
#interface DialogWelcome : UIAlertView{
IBOutlet UITextField *text;
UIButton *ok;
UIButton *annulla;
}
#property(nonatomic,retain) UITextField *text;
- (IBAction)ok:(id)sender;
- (IBAction)annulla:(id)sender;
#end
and .m :
#import "DialogWelcome.h"
#implementation DialogWelcome
#synthesize text;
-(IBAction)ok:(id)sender{
}
-(IBAction)annulla:(id)sender{
}
#end
i've not implement methods cause in first i need to show it!
i call this in viewcontroller in this way:
- (void)viewDidLoad
{
[super viewDidLoad];
DialogWelcome *alert = [[DialogWelcome alloc] initWithTitle:#"Welcome"
message:nil
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:nil];
[alert show];
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*2.0);
dispatch_after(delay, dispatch_get_main_queue(), ^{
[alert dismissWithClickedButtonIndex:0 animated:YES];
});
[alert release];
}
This will show a normal uialertview empty with a title. why it doesn't show my custom uialertview?
From the UIAlertView Class Reference:
The UIAlertView class is intended to be used as-is and does not
support subclassing. The view hierarchy for this class is private and
must not be modified.
So, what you're trying to do is explicitly not allowed.

Passing of UITextField text from one view to another

I defined a UITextField on my firstViewController as follow
// firstViewController.h
IBOutlet UITextField *PickUpAddress
#property (nonatomic, retain) UITextField *PickUpAddress;
//firstViewController.m
#synthesize PickUpAddress;
// Push secondView when the 'Done' keyboard button is pressed
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if (textField == PickUpAddress) {
SecondViewController *secondViewController= [[SecondViewController alloc]
initWithNibName:#"SecondViewController"
bundle:nil];
secondViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
return NO;
}
Then I tried to retrive it in my secondViewController during viewWillAppear
- (void)viewWillAppear:(BOOL)animated {
BookingViewController *bookingViewController = [[BookingViewController alloc] init];
NSString *addressString = [[NSString alloc] init];
addressString = bookingViewController.PickUpAddress.text;
NSLog(#"addressString is %#", bookingViewController.PickUpAddress.text);
}
But it returns as NULL on my console. Why is that so?
Thanks in advance :)
in secondViewController.h add
NSString *text;
#property (nonatomic, retain) NSString *text;
-(void)setTextFromText:(NSString *)fromText;
in secondViewController.m add following
- (void)setTextFromText:(NSString *)fromText
{
[text release];
[fromText retain];
text = fromText;
}
in firstViewController.m
before
[self.navigationController pushViewController:secondViewController animated:YES];
add
[secondViewContoller setTextFromText:PickUpAddress.text];
Now let me explain the code.
You are adding an NSString to second view , where we will store the text from the UITextField. Then, we've written a method, which will set that NSString from some other NSString.
Before pushing secondViewController to navigationController, you're just calling that method to set our text from PickUpAddress.text.
Hope that helped.
Problem is in your code. You are creating new object, bookingViewController, to retrieve the textField value. So it will obviously provide NULL. Rather you should use one unique object application wide to access the value.

sending string between views

i have 2 views
i m sending text in a button on 1st view to label on second view....
//////textfieldtolabelViewController.h
#import <UIKit/UIKit.h>
#import "seconview.h"
#interface textfieldtolabelViewController : UIViewController {
IBOutlet seconview *sec;
//IBOutlet UITextField *t1;
}
//#property(nonatomic, retain)IBOutlet UITextField *t1;
-(void)buttonclick:(id)sender;
#end
and its .m file is this
#import "textfieldtolabelViewController.h"
#implementation textfieldtolabelViewController
-(void)buttonclick:(id)sender
{
NSString *s = [sender titleForState:UIControlStateNormal];
//sec.ss = s;
[sec settext:s];
[self presentModalViewController:sec animated:YES];
}
- (void)dealloc {
[super dealloc];
}
#end
now there is second view naming seconview
.h file
#import <UIKit/UIKit.h>
#interface seconview : UIViewController {
IBOutlet UILabel *l1;
}
#property(nonatomic, retain)IBOutlet UILabel *l1;
-(void)settext:(NSString *)ss;
#end
and its .m file is ....
#import "seconview.h"
#implementation seconview
#synthesize l1;
//#synthesize ss;
-(void)settext:(NSString *)ss
{
l1.text=ss;
}
- (void)dealloc {
[super dealloc];
}
#end
this program did not show any error and runs fine but problem is that the text of button in 1st view does not appear in label on second view
but i made all connection perfectly.......
Most probably you didn't connect l1 to the actual label in the Interface Builder. Verify with the debugger, that l1 is not nil in your settext method
You can include the view controller containing the label in the view controller where you want it to change, and access it by allocating a copy of it.
For example, use something like this in textfieldtolabelViewController.m
#import "seconview.h"
-(void)buttonclick:(id)sender
{
NSString *s = [sender titleForState:UIControlStateNormal];
seconview *viewcontroller = [[seconview alloc] initWithNibName:#"seconview" bundle:nil];
[[viewcontroller l1] setText:s];
[viewcontroller release];
[self presentModalViewController:sec animated:YES];
}
the [self presentModalViewController:sec animated:YES]; should be above the setText
try it
-(void)buttonclick:(id)sender
{
NSString *s = [sender titleForState:UIControlStateNormal];
//sec.ss = s;
[self presentModalViewController:sec animated:YES];
[sec settext:s];
}
hope it will work....