UITextField shouldChangeCharactersInRange Delegate not working - iphone

I am having trouble with a new view I have created, I have a registration view that has a single UITextField on it and a UIButton.
I call this view from another view like so
//otherview.m
- (void)viewDidLoad
{
[super viewDidLoad];
RegistrationAlertViewController *regreg = [[RegistrationAlertViewController alloc] init];
[self.view addSubview:regreg.view];
}
Then I create my regregview like this
//regregView.h
#import <UIKit/UIKit.h>
#interface RegistrationAlertViewController : UIViewController <UITextFieldDelegate> {
// textfields for registration
IBOutlet UITextField *registrationTextFieldA;
}
// textfields for registration
#property (strong, nonatomic) IBOutlet UITextField *registrationTextFieldA;
#end
//regregView.m
#import "RegistrationAlertViewController.h"
#interface RegistrationAlertViewController ()
#end
#implementation RegistrationAlertViewController
#synthesize registrationTextFieldA;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
registrationTextFieldA = [[UITextField alloc] init];
registrationTextFieldA.delegate = self;
[registrationTextFieldA becomeFirstResponder];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if([textField.text length] > 4)
{
//Get next TextField... A simple way to do this:
// UITextField *newTextField = [textField.superview viewWithTag:(textField.tag+1)];
// [newTextField becomeFirstResponder];
return NO;
//remember to set the tags in order
}
return YES; //you probably want to review this...
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if((textField.text.length + string.length) > 4)
{
//Get next TextField... A simple way to do this:
// UITextField *newTextField = [textField.superview viewWithTag:(textField.tag+1)];
// [newTextField becomeFirstResponder];
//remember to set the tags in order
}
return YES; //you probably want to review this...
}
#end
I have the two delegates in my regregView.m
textFieldShouldBeginEditing
shouldChangeCharactersInRange
for some bizarre reason textFieldShouldBeginEditing is entered when the view first loads but then when I start entering characters into registrationTextFieldA shouldChangeCharactersInRange is never being entered for some bizarre reason.
any help figuring out why my delegates are not working properly would be greatly appreciated.

Include UITextFielDelegate category in yourClass.h file and Try this code .
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int length = textField.text.length - range.length + string.length;
if(length > 4)
{
return NO;
}
return YES;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if([textField.text length] > 4)
{
return NO;
}
return YES; //you probably want to review this...
}
I hope it helps you.

Don't allocate UITextField instance in viewDidLoad method. Replace you code with this :
- (void)viewDidLoad
{
registrationTextFieldA.delegate = self;
[registrationTextFieldA becomeFirstResponder];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
Hope it helps you.

Add UItextField delegate from your xib outlet and declare delegate protocol <uitextfielddelegate> in your .h file.
Definitely it will work fine for You.
Good Luck !!!!

A wild guess here.
The problem is in your otherview.m
- (void)viewDidLoad
{
[super viewDidLoad];
RegistrationAlertViewController *regreg = [[RegistrationAlertViewController alloc] init];
[self.view addSubview:regreg.view];
}
Try making a strong property of RegistrationAlertViewController on top of your otherview.m
#property (nonatomic, strong) RegistrationAlertViewController *regreg;
Then in your view did load, you can do
- (void)viewDidLoad
{
[super viewDidLoad];
RegistrationAlertViewController *regreg = self.regreg;
if (regreg == nil)
{
self.regreg = [[RegistrationAlertViewController alloc] init];
}
[self.view addSubview:regreg.view];
}
Hope that works.. Just seems like a similar problem I ran into before.. Good luck

As you are initializing the view while implementing this file.So set delegate in init method not in viewDidLoad.
#synthesize registrationTextFieldA;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
registrationTextFieldA = [[UITextField alloc] init];
registrationTextFieldA.delegate = self;
[registrationTextFieldA becomeFirstResponder];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}

Related

collectionview with swipe in view controller

I'm doing a simple image gallery with a collectionview listing my images. Images names are stocked into an array. When I press on an image, it display the picture in a view controller with an imageview.
Now I would like to be able to switch from one image to the next and previous image with a swipe instead of going back to the collection view to change picture. Did I choose a wrong way to achieve my project or is there an easy way to do this?
Thank you already for your help!
Nicolas.
Here's my actual code :
PhotosCollectionViewController.h
import
#interface PhotosCollectionViewController : UICollectionViewController
{
NSArray *photosArray;
}
#end
PhotosCollectionViewController.m
#import "PhotosCollectionViewController.h"
#import "PhotoDetailViewController.h"
#interface PhotosCollectionViewController ()
#end
#implementation PhotosCollectionViewController
- (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.
photosArray = [NSArray arrayWithObjects:#"angry_birds_cake.jpg", #"creme_brelee.jpg", #"egg_benedict.jpg", #"full_breakfast.jpg", #"green_tea.jpg", #"ham_and_cheese_panini.jpg", #"ham_and_egg_sandwich.jpg", #"hamburger.jpg", #"instant_noodle_with_egg.jpg", #"japanese_noodle_with_pork.jpg", #"mushroom_risotto.jpg", #"noodle_with_bbq_pork.jpg", #"starbucks_coffee.jpg", #"thai_shrimp_cake.jpg", #"vegetable_curry.jpg", #"white_chocolate_donut.jpg", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return photosArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *photosImageView = (UIImageView *)[cell viewWithTag:100];
photosImageView.image = [UIImage imageNamed:[photosArray objectAtIndex:indexPath.row]];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"pushPhoto"]) {
NSArray *indexPaths = [self.collectionView indexPathsForSelectedItems];
PhotoDetailViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [indexPaths objectAtIndex:0];
destViewController.photoName = [photosArray objectAtIndex:indexPath.row];
}
}
#end
PhotoDetailViewController.h
#import <UIKit/UIKit.h>
#interface PhotoDetailViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *photoImageView;
#property (weak, nonatomic) NSString *photoName;
#end
PhotoDetailViewController.m
#import "PhotoDetailViewController.h"
#interface PhotoDetailViewController ()
#end
#implementation PhotoDetailViewController
#synthesize photoImageView;
- (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.
self.photoImageView.image = [UIImage imageNamed:self.photoName];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Just enable user interaction for your UIImageView, attach a UISwipeGestureRecognizer with the direction configured to how you want, and change the image in the UIImageView in the selector you've set in the gesture recogniser.
You are doing it right.Pass the array of images(or urls) and on the next and previous button action(or gesture recogonizer) , load the images from the array and show in the viewcontroller.
Create an array instance "imageArray" in the DetailsedImageVC class
stackedImages be the array in which the images are available
DetailedImageVC *vc=[[DetailedImageVC alloc]initWithNibName:#"DetailedImageVC" bundle:[NSBundle mainBundle]];
vc.imageArray=self.stackedImages ;
[self.navigationController pushViewController:vc animated:YES];
Now you have the array in DetailedImageVC and now on,when the next image needed action just get the image from the array nd load

i am not able to pass value from one view controller to another view controller

hi i have problem that i am not able to pass value from one view controller to another view controller through button i implement when i click on button other view appear on iphone screen but the value which i have set not dispay this is the button code
-(IBAction)save:(id)sender
{
nextview *admin = [[nextview alloc]init];
[self presentModalViewController:admin animated:YES];
if (admin.view)
{
admin.fetchname = name.text;
}
[admin release];
}
and this is the nextview.h file
#import <UIKit/UIKit.h>
#interface nextview : UIViewController
{
UILabel *getname;
NSString *fetchname;
}
#property (nonatomic,retain) IBOutlet NSString *fetchname;
#property (nonatomic,retain) IBOutlet UILabel *getname;
#end
and this is the nextview.m file
#import "nextview.h"
#import "ViewController.h"
#implementation nextview
#synthesize getname,fetchname;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
getname.text = self.fetchname;
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
The viewDidLoad method is called before you had a chance to assign your NSString value.
That's why you dont see the text in your UIButton.
Try this :
-(IBAction)save:(id)sender
{
nextview *admin = [[nextview alloc] init];
admin.fetchname = name.text;
[self presentModalViewController:admin animated:YES];
[admin release];
}
-(IBAction)save:(id)sender
{
nextview *admin = [[nextview alloc]init];
[self presentModalViewController:admin animated:YES];
if (admin.view)
{
admin.fetchname = name.text;
}
[admin release];
}
You release the instance of nextview right after you assign the name. That can't even work.
By the way, getname and fetchname are really bad chosen names for properties.
You can do something like this.
You can implement the below code in nextView.h
NSString *fetchData;
also property and synthesize this
#property(nonatomic, retain) NSString *fetchData;
implement this on button pressed code
-(IBAction)save:(id)sender
{
nextview *admin = [[nextview alloc] init];
admin.fetchData = name.text;
[self presentModalViewController:admin animated:YES];
[admin release];
}

UITextView.text lags when loading text

I want to display text with an UITextView, which is part of an UITabBarView and do so in the following Class:
.h - File:
#import <UIKit/UIKit.h>
#interface DescriptionViewController : UIViewController{
IBOutlet UITextView *descriptionText;
}
#end
.m - File:
#import "DescriptionViewController.h"
#import "Globals.h"
#interface DescriptionViewController ()
#end
#implementation DescriptionViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void) viewWillAppear:(BOOL)animated{
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}
#end
When the TextView is displayed the first time it is empty, when i switch to another tab and switch back to the "TextView - Tab" it is displayed properly. But I obviously want it to be displayed correctly the first time..
I already tried to move the relevant code to the -viewDidLoad function, but nothing changed. Also, I tried the -setNeedsDisplay function without success (maybe I used it wrong? - [descriptionText setNeedsDisplay].
I appreciate any help and further code will be posted on request.
Please set breakpoint on ViewWillAppear Method of your class then check that in first time what you are getting from NSLog("%#", [myGlobals.currentLine objectAtIndex:5]);
and you are missing [super viewWillAppear:animated];
try this,
- (void)viewDidLoad
{
[super viewDidLoad];
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
Globals* myGlobals = [Globals sharedGlobals];
descriptionText.text = [myGlobals.currentLine objectAtIndex:5];
}

Give out a NSMutableArray on a texView on another Viewcontroller in objective-C?

I try to save numbers from a textfield on one viewController in a NSMutableArray when I press a button on this viewContoller. (this is working now)
Then i want the numbers give out on a textview which is on a secondViewController but this dont work. When i want to give out the array on the first Viewcontroller it work fine.
Also i cant erase the NSMutableArray with a button on the SecondviewController.
The SecondviewController have the same class like the viewController.
Can someone show me how i can give out an array on a seconviewcontroller?
Hallo,
at the moment i have this:
//ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
NSMutableArray *textViewArray;
}
#property (strong, nonatomic) IBOutlet UITextField *textLable2;
#property (strong, nonatomic) IBOutlet UITextField *textLable1;
- (IBAction)setArrayWithCurrentNumber:(id)sender;
- (IBAction)returnToTextfield:(id)sender;
#end
//this the .m file:
#import "ViewController.h"
#implementation ViewController
#synthesize textLable2;
#synthesize textLable1;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
textViewArray = [[NSMutableArray alloc]init];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setTextLable2:nil];
[self setTextLable1:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)setArrayWithCurrentNumber:(id)sender
{
NSString *string1 = self.textLable1.text;
[textViewArray addObject:string1];
NSMutableArray *array = [NSMutableArray arrayWithArray:textViewArray];
NSString *string2 = [array componentsJoinedByString:#" "];
self.textLable2.text = [NSString stringWithString:string2];
NSLog(#"%#",textViewArray);
}
- (IBAction)returnToTextfield:(id)sender
{
[textLable1 resignFirstResponder];
[textLable2 resignFirstResponder];
}
#end
If you're calling the second view controller from the first one you could set a property on the second one to hold the NSMutableArray or just send it on the initializer.
something like:
- (id)initWithArray:(NSMutableArray *)array {
if (self = [super init]) {
myArray = [array copy];
}
return self;
}
assuming your second view controller has declared NSMutableArray * myArray;
Edit: Adding some more code in here...
// I'll assume you use some kind of UINavigationController to show your content
- (void)showSecondViewController {
SecondViewController * vc = [[[SecondViewController alloc] initWithArray:yourMutableArray] autorelease];
[self.navigationController pushViewController:vc];
}

iphone app text field doesn't work correctly

I'm currently working on an Iphone application that has 3 text fields. If I connect the delegate of the first two text fields to the class then run the simulator and try to click on them nothing happens, they don't allow me to edit them and the keyboard doesn't pop up. If I don't connect their delegates then the keyboard appears but textFieldShouldReturn is never called when I click the done button on the keyboard. The third text field brings up a UIPickerView when clicked on and that shows up as expected.
LoginViewController.h
#import <UIKit/UIKit.h>
#interface LoginViewController : UIViewController <UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource>
{
IBOutlet UITextField *usernameField;
IBOutlet UITextField *passwordField;
IBOutlet UITextField *conferenceField;
IBOutlet UIButton *loginButton;
//IBOutlet UIPickerView *picker;
ConnectHandler *cHandle;
NSMutableArray *conferences;
}
#property (nonatomic, retain) UITextField *usernameField;
#property (nonatomic, retain) UITextField *passwordField;
#property (nonatomic, retain) UITextField *conferenceField;
#property (nonatomic, retain) UIButton *loginButton;
- (IBAction) login: (id) sender;
#end
LoginViewController.m
#import "LoginViewController.h"
#implementation LoginViewController
#synthesize usernameField;
#synthesize passwordField;
#synthesize conferenceField;
#synthesize loginButton;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
cHandle = [ConnectHandler new];
NSArray *confs = [cHandle conference_list];
//conferences = confs;
// temporary to test if it's working
conferences = [NSArray arrayWithObjects:#"Germany", #"Austria", #"Swiss", #"Luxembourg",
#"Spain", #"Netherlands", #"USA", #"Canada", #"Denmark", #"Great Britain",
#"Finland", #"France", #"Greece", #"Ireland", #"Italy", #"Norway", #"Portugal",
#"Poland", #"Slovenia", #"Sweden", nil];
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectZero];
picker.delegate = self;
picker.dataSource = self;
[picker setShowsSelectionIndicator:YES];
[conferenceField setInputView:picker];
[picker release];
[picker selectRow:1 inComponent:0 animated:NO];
}
-(BOOL)textFieldShouldReturn:(UITextField*)textField {
NSLog(#"TextFieldShouldReturn");
[textField resignFirstResponder];
return YES;
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
[conferences release];
}
- (IBAction) login: (id) sender
{
loginButton.enabled = FALSE;
NSLog(#"user: %# pass: %#", usernameField.text, passwordField.text);
//checks to see if user provided information is valid
NSString *db = #"sdfsdf";
BOOL auth = [cHandle check_auth:db :usernameField.text :[cHandle hashPass:passwordField.text]];
NSLog(#"AUTH: %#", auth?#"YES":#"NO");
// login successful if check_auth returns YES
if (auth == YES) {
// store the user's login info
// switch to full app
[self dismissModalViewControllerAnimated:YES];
}
else {
// display error message and stay on login screen
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Invalid"
message:[NSString stringWithFormat:#"The login or password you have entered is invalid"]
delegate:nil
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
[alert release];
loginButton.enabled = TRUE;
}
//NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
//[pickerView setHidden:NO];
}
//#pragma mark -
//#pragma mark UIPickerViewDelegate
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSLog(#"titleForRow");
return #"TEST"; //[conferences objectAtIndex:row];
}
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
NSLog(#"didSelectRow");
[self textFieldShouldReturn:conferenceField];
// [pickerView resignFirstResponder];
//conferenceField.text = (NSString *)[conferences objectAtIndex:row];
}
//#pragma mark -
//#pragma mark UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
NSLog(#"numberOfComponentsInPickerView");
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSLog(#"numberOfRowsInComponent");
return 4; //[conferences count];
}
#end
Add this to your viewDidLoad:
usernameField.delegate = self;
passwordField.delegate = self;
conferenceField.delegate = self;
You're not settings the delegate for the text fields. Also remove the resignFirstResponder code from your textFieldDidBeginEditing as mentioned in the other answers.
You have [textField resignFirstResponder] in the delegate method - (void)textFieldDidBeginEditing: which would make the keyboard go away prematurely.
This is your problem:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
//[pickerView setHidden:NO];
}
With the delegate hooked up, it’s receiving the -textFieldDidBeginEditing: message when the user touches the text field and immediately forcing the text field to resign first-responder status (i.e. lose its keyboard). Keep the delegate connected, remove the -resignFirstResponder call, and it’ll work.