UITextField shouldChangeCharactersinRange as external function - ios

I want to validate UITextField input for multiple view controllers. The following works:
validate.h
#import <UIKit/UIKit.h>
#interface validate : UITextField <UITextFieldDelegate>
#end
validate.m
#import "validate.h"
#implementation validate
viewController.h
#import <UIKit/UIKit.h>
#include "limiteTextField.h"
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet limiteTextField *myTextField;
#end
viewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
//my code for validating
}
- (void)viewDidLoad {
[super viewDidLoad];
_myTextField.delegate=self;
I want to be able to use the shouldChangeCharactersInRange as an external function so don't have to rewrite all its code for each view controller.

I want to be able to use the shouldChangeCharactersInRange as an external function so don't have to rewrite all its code for each view controller.
Then do so. This is a delegate method. Anything can be the delegate. You are the one who is setting the text field's delegate to be different view controllers! If you don't want to do that, then don't. Have some single persistent object, or at least multiple instance of the same class, and make that the delegate of the text field. Now all text fields can use this same delegate which has just one implementation of shouldChangeCharactersInRange.

One approach is to create some kind of validator class with a singleton and assigning it as the textfields delegate:
TextFieldValidator.h
#import <UIKit/UIKit.h>
#interface TextFieldValidator : NSObject <UITextFieldDelegate>
+ (instancetype)sharedValidator;
#end
TextFieldValidator.m
#import "TextFieldValidator.h"
#implementation TextFieldValidator
+ (instancetype)sharedValidator {
static TextFieldValidator *sharedValidator = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedValidator = [[self alloc] init];
});
return sharedValidator;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *allowedCharacters = [NSCharacterSet decimalDigitCharacterSet];
return [[textField.text stringByReplacingCharactersInRange:range withString:string] rangeOfCharacterFromSet:allowedCharacters.invertedSet].location == NSNotFound;
}
#end
SomeViewController.m
// [...]
self.textField.delegate = [TextFieldValidator sharedValidator];
// [...]

Related

I need to pass a string from a NSObject class to a UIViewController with a delegate

I need to pass a string from a NSObject class to a UIViewController, I understand that the best way is delegation but the delegate method isn't being called. I'm trying to set the UILabel an DieFacesViewController as the selectedOption from TemporarySelection.
A tableview shows the value of CustomOptionStore, once it's tapped passes its value to TemporarySelection and opens the modal view DieFacesViewCountroller which should, at least in my mind, take the label value from TemporarySelection. The reason I created TemporarySelection is because the DieFacesViewController will be used by other classes, not only by CustomOptionStore, and it will need to load the label from all those classes when different tableViews are selected.
I tried to set the delegate as self in both viewDidLoad and viewWillAppear with no luck, I don't understand if the view loads before being able to call the delegate method or if there's something wrong the way I set the method up.
I've been stuck here for two days, this is the first time I post a question so please forgive me if it's a bit confused.
my delegator class TemporarySelection.h is
#import <Foundation/Foundation.h>
#import "CustomOptionsStore.h"
#class DieFacesViewController;
#protocol TemporarySelectionDelegate <NSObject>
-(void)sendSelection;
#end
#interface TemporarySelection : NSObject
#property (nonatomic, weak) id <TemporarySelectionDelegate> delegate;
#property (nonatomic, strong) NSString *selectedOption;
-(void)addSelection: (CustomOptionsStore *) selection;
#end
and my TemporarySelection.m is
#import "TemporarySelection.h"
#implementation TemporarySelection
-(void)addSelection: (CustomOptionsStore *) selection{
self.selectedOption = selection.description;
[self.delegate sendSelection];
}
#end
the delegate class DiewFacesViewController.h is
#import <UIKit/UIKit.h>
#import "SelectedStore.h"
#import "TemporarySelection.h"
#interface DieFacesViewController : UIViewController <TemporarySelectionDelegate>
#property (strong, nonatomic) IBOutlet UILabel *SelectionName;
#end
and the DieFacesViewController.m is
#import "DieFacesViewController.h"
#interface DieFacesViewController ()
#end
#implementation DieFacesViewController
- (void)viewDidLoad {
TemporarySelection *ts = [[TemporarySelection alloc]init];
ts.delegate = self;
[super viewDidLoad];
}
-(void)sendSelection{
TemporarySelection *ts = [[TemporarySelection alloc]init];
self.SelectionName.text = ts.selectedOption;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
}
You are not setting the delegate object properly.Check the above code
#import "DieFacesViewController.h"
#interface DieFacesViewController ()<TemporarySelectionDelegate>
{
//global object
TemporarySelection *ts;
}
#end
#implementation DieFacesViewController
- (void)viewDidLoad {
ts = [[TemporarySelection alloc]init];
ts.delegate = self;
[super viewDidLoad];
}
-(void)sendSelection{
//Use the object to extract
self.SelectionName.text = ts.selectedOption;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
}

Objective-C: Accessing variables from another class [duplicate]

This question already has answers here:
Passing data between view controllers
(45 answers)
Access Variable from Another Class - Objective-C
(2 answers)
Closed 8 years ago.
I'm creating a project so that I have two view controllers, connected by a modal segue with an identifier "login_success".
In the primary view controller, I have a text field that takes the input of whatever the user types, and a button to perform the segue.
In the next controller, I have a label that is supposed to print out whatever the user typed.
My code:
DICViewController.h (First View Controller):
#import <UIKit/UIKit.h>
#interface DICViewController : UIViewController <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtUsername;
- (IBAction)sigininClicked:(id)sender;
- (IBAction)backgroundTap:(id)sender;
#end
DICViewController.m:
#import "NewViewController.h"
#interface DICViewController ()
#end
#implementation DICViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sigininClicked:(id)sender {
{
[self performSegueWithIdentifier:#"login_success" sender:self];
}
}
- (IBAction)backgroundTap:(id)sender {
[self.view endEditing:YES];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#end
NewsViewController.h (The other view controller):
#import <UIKit/UIKit.h>
#interface NewViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *steamId; //my label
#end
NewsViewController.m:
No code was added here.
Thanks in advance to anyone that can help.
Again, I would like to be able to set the text in the label equal to the text the user types in the text field.
When performing a segue the preferred way to pass data from one view controller to another is to make use of the method -prepareForSegue:sender:.
In your case the following lines of code should work:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NewsViewController *newsVC = segue.destinationViewController;
[newsVC view]; // this loads the view so that its subviews (the label) are not nil
newsVC.steamID.text = self.txtUsername.text;
}
(Place this method anywhere in your DICViewController.m.)
I think The better way is to set global variables. Just make normal class
variables.h
#import <Foundation/Foundation.h>
#interface variables : NSObject {
float VariableYouWant;
}
+ (_tuVariables *)sharedInstance;
#property (nonatomic, assign, readwrite) float VariableYouWant;
and
variables.m
#import "variables.h"
#implementation variables
#synthesize VariableYouWant = _VariableYouWant;
+ (_tuVariables *)sharedInstance {
static dispatch_once_t onceToken;
static variables *instance = nil;
dispatch_once(&onceToken, ^{
instance = [[variables alloc] init];
});
return instance;
}
- (id)init {
self = [super init];
if (self) {
}
return self;
}
#end
Way to use:
import header file of variables and
variables *globals = [variables sharedInstance];
and simply access variables with
globals.VariableYouWant =

Action when pressing return key on keyboard (iOS)

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self checkRun:nil];
return YES;
}
I'm trying to complete the IBAction checkRun when the return key is pressed, by using the above code, but it doesn't seem to be working. Where am I going wrong? I thought maybe it's because I'm not directly referencing the textfield that I'm typing in, but I can't work out where I'd need to put the name of that textfield.
Thanks in advance.
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextFieldDelegate>
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) UITextField *textField;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.textField.delegate = self;
}
This UITextfield subclass enables you to set a condition for the text and dynamically change the UIReturnKey:
https://github.com/codeinteractiveapps/OBReturnKeyTextField

UITextField isn't being set from a delegate method, but the same can be set from other methods

In FirstViewController.h I have declared a delegate
id _delegate;
#property (nonatomic,strong) id _delegate;
-(void)startSampleProcess:(NSString *) arguement1;
In FirstViewController.m I have implemented startSampleProcess
-(void)startSampleProcess:(NSString *)arguement1{
[textField1 setText:#"rajesh"];//Setting SOME text Field
}
In CustomCell.m I have declared and used the delegate object in one of the TextField delegate methods
-(void)textFieldDidEndEditing:(UITextField *)textField{
sampleProtocol = [[iOSFirstViewController alloc]init];
sampleProtocol._delegate = self;
[sampleProtocol startSampleProcess:#"MASTER COMPUTER"];
NSLog(#"textFieldDidEndEditing");
}
try like this Declaring protocol
#protocol SampleProcessDelegate <NSObject>
-(void)startSampleProcess:(NSString *) arguement1;
#end
#interface PocketBugzDropDownView : UIView<UITableViewDataSource,UITableViewDelegate>
{
id <SampleProcessDelegate> delegate;
}
#property(nonatomic)id<SampleProcessDelegate> delegate;
#end
in .m file
#synthesize delegate
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[self.delegate startSampleProcess:textFiled.text];
}
if access that delegate any filedecleare delegate in .h file
sampleProtocol = [[iOSFirstViewController alloc]init];
sampleProtocol._delegate = self;
-(void)startSampleProcess:(NSString *) arguement1
{
nslog(#"%#",arguement1);
}

I cannot set text of my Custom Text Field

I am trying to make a custom TextField (KSTextField). I inherited my text field from UITextField. As you can see my KSTextField.h file below.
#import <UIKit/UIKit.h>
#import <UIKit/UITextField.h>
#interface KSTextField : UITextField {}
#end
In my KSTextField.m i tried to set a dummy text attribute. But it doesn't work. Is super.text usage wrong?
My main purpose is, making a custom UITextField that only allows for upper case characters which is needed for my project.
#import "KSTextField.h"
#implementation KSTextField
- (id)init {
self = [super init];
super.text = #"help";
return self;
}
- (void)textFieldDidChangeForKS:(KSTextField *)textField {
self.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
NSString *textToUpper = [textField.text uppercaseString];
[self setText:textToUpper];
}
#end
And also mine ViewController.h is below
#import <UIKit/UIKit.h>
#import "KSTextField.h"
#interface ViewController : UIViewController
#property (nonatomic, copy) IBOutlet KSTextField *txtKsName;
#end
Here's my ViewController.m which i want to set my KSTextField.text
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.txtKsName = [[KSTextField alloc] init];
}
Delegate events do not solve my issue. Because i'll add much more features later. It will be my custom textfield thanks!
The answer is: you're doing it wrong! You don't have to subclass to allow uppercase characters only. Use a UITextFieldDelegate:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html
Using the textField:shouldChangeCharactersInRange:replacementString: method, you can say whether on not the character typed is allowed to be added to the box.
Try something like this:
- (BOOL)textField:(UITextField *)field shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)characters
{
NSCharacterSet *blockedCharacters = [[[NSCharacterSet uppercaseLetterCharacterSet] invertedSet] retain];
return ([characters rangeOfCharacterFromSet:blockedCharacters].location == NSNotFound);
}

Resources