iOS - Implementing a Class for UITextField - ios

I have a UIView, with lots of UITexfields,
UITextField *field1 = [[UITextField alloc] initWithFrame:CGRectMake(135, 292, 50, 20)];
field1.backgroundColor = [UIColor clearColor];
field1.borderStyle = UITextBorderStyleNone;
field1.returnKeyType = UIReturnKeyNext;
field1.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
field1.font = [UIFont fontWithName:inputFont size:fontSize];
field1.placeholder = #"size";
[self addSubview:field1];
Can I create a UITextField Class and create an instance of this class with these parameters preset? -so as to reduce the code: (If I have lots of fields the code gets very long and repetitive? -
Can i get some help on how about to set up this class! -thank you

Yes You Can do this by making a BaseUITextFeild .h and .m file as shown in the following image.
And then Just add the following code regarding your design in BaseUITextFeild.m file
- (void)awakeFromNib {
[self setupUI];
[self setKeyboardAppearance:UIKeyboardAppearanceAlert];
}
// Function to setup the common UI throught the app.
- (void)setupUI {
[self setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
[self setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
[self setTextAlignment:NSTextAlignmentCenter];
[self setValue:[UIColor colorWithRed:120.0/225.0 green:120.0/225.0 blue:120.0/225.0 alpha:1.0] forKeyPath:#"_placeholderLabel.textColor"];
[self setFont:[UIFont boldSystemFontOfSize:15.0f]];
}
Generating a custom UITextField programmatically
And then just import "BaseUITextFeild.h" in the ViewController Where you want to use it.
BaseUITextFeild *field1 = [[BaseUITextFeild alloc] initWithFrame:CGRectMake(135, 292, 50, 20)];
[self addSubview:field1];
Generating a custom UITextField From Interface Builder(Storyboard/.XIB)
Add a UITextfield and then just Change the Class to your Custom TextView Class.
By Applying Following technique you can use this same UITextFeild through out the Application, Just need to import BaseUITextFeild.h.
You can also use this UITextFieldCategory
Follow this Two Example UITextField+withFrame.h and UITextField+ColoredPlaceholder.h.
You can also customize you UITextField as per your need.

Create a method
-(UITextField*)createTextFieldWithFrame:(CGRect)frame{
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.backgroundColor = [UIColor clearColor];
textField.borderStyle = UITextBorderStyleNone;
textField.returnKeyType = UIReturnKeyNext;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentBottom;
textField.placeholder = #"size";
[self.view addSubview:textField];
return textField;
}
for creating multiple textfields call this method
UITextField *text1 = [self createTextFieldWithFrame:CGRectZero];
UITextField *text2 = [self createTextFieldWithFrame:CGRectZero];

You can create a custom xib with the UITextField created as you want and reuse that every time you need.
Or you can subclass UITextField and do the additional setup inside.

Related

How do i disable the editing of a UITextView based on a UISwitch?

I have a UITextView and i want to disable it's 'editable' property if the state of the UISwitch is set to ON.
myTextView = [[UITextView alloc]initWithFrame:CGRectMake(20, 180, 200, 30)];
myTextView.backgroundColor = [UIColor whiteColor];
myTextView.text = #"This is a textView";
[self.view addSubview:myTextView];
mySwitch = [[UISwitch alloc]initWithFrame:CGRectMake(230, 125, 200, 30)];
[self.view addSubview:mySwitch];
I know that i can check the state of a switch using:
if ([mySwitch isOn]) {
myTextView.editable = NO;
} else {
myTextView.editable = YES;
}
The problem is when i run my project the text is not editable, but when i slide the switch the text cannot be edited (which is obvious with above code). I want to know what do i have to do to change the editable property of the UITextView, if i toggle the switch.
UISwitch is a subclass of the UIControl class, which among other things, provides a target-action-based model for receiving updates about the state of the control.
This means that you can use the -[UIControl addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents] method to have your method called when the switch changes its boolean value:
[yourSwitch addTarget:self action:#selector(switchToggled:) forControlEvents:UIControlEventValueChanged]
You can also do this from Interface Builder, by right-clicking on your UISwitch and assigning its action to the appropriate IBAction method:
- (IBAction) switchToggled:(UISwitch*)switchControl {
yourTextView.editable = switchControl.on;
}
You need to add an IBAction and hook it up to the switch method Value Changed
-(IBAction)toggleSwitch:(UISwitch*)sw {
myTextView.editable = sw.on;
NSLog(#"Value Changed");
}
Edit: Code for doing it programmatically rather than via Interface Builder
myTextView = [[UITextView alloc]initWithFrame:CGRectMake(20, 180, 200, 30)];
myTextView.backgroundColor = [UIColor whiteColor];
myTextView.editable = NO;
myTextView.text = #"This is a textView";
[self.view addSubview:myTextView];
mySwitch = [[UISwitch alloc]initWithFrame:CGRectMake(230, 125, 200, 30)];
mySwitch.on = NO;
[mySwitch addTarget:self action:#selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:mySwitch];
-(void)toggleSwitch:(UISwitch*)sw {
myTextView.editable = sw.on;
}
You have to create an action for the switch which fires when the switch's state has changed. If you are using storyboard, right-drag from the switch to the code (like to create an outlet) and choose action. Inside that function you check whether your switch is now on or off and according to that you make your TextView editable or not
if ([mySwitch isOn]) {
myTextView.editable = NO;
[myTextView resignFirstResponder];
} else {
myTextView.editable = YES;
[myTextView becomeFirstResponder];
}

Button won't log textfield values

So for my iOS app, if I delete the textfields and the code which grabs the text field values, the button works--in that it presents the indicated view controller..
But when I add these textfields and try to get the button to also Log their values, the button no longer works in that I push the button and nothing happens.
It's also worth mentioning that the code which creates these textfields is littered with "local declaration of "X" hides instance variable" warnings.. but i hear that's not too important (?)
Here's what's in the .h file:
#interface RootViewController : UIViewController
#property (nonatomic, retain) IBOutlet UITextField *usernameTextfield;
#property (nonatomic, retain) IBOutlet UITextField *passwordTextfield;
- (IBAction)buttonClicked: (id)sender;
#end
And in the .m file:
#import "RootViewController.h"
#import "chooseFeedItemViewController.h"
#interface RootViewController ()
#end
#implementation RootViewController
#synthesize passwordTextfield;
#synthesize usernameTextfield;
- (void)viewDidLoad {
[super viewDidLoad];
UIView* v = self.view;
v.backgroundColor = [UIColor whiteColor];
//load Feed View button
CGRect buttonFrame = CGRectMake(177, 250, 100, 100);
UIButton *button = [[UIButton alloc] initWithFrame: buttonFrame];
[button setTitle: #"submit" forState: UIControlStateNormal];
[button setTitleColor: [UIColor blueColor] forState: UIControlStateNormal];
[button addTarget: self
action: #selector(buttonClicked:)
forControlEvents: UIControlEventTouchDown];
[v addSubview: button];
//username textfield
IBOutlet UITextField *usernameTextfield = [[UITextField alloc] initWithFrame:CGRectMake(45, 30, 200, 40)];
usernameTextfield.textColor = [UIColor colorWithRed:0/256.0 green:84/256.0 blue:129/256.0 alpha:1.0];
usernameTextfield.font = [UIFont fontWithName:#"Helvetica-Bold" size:25];
usernameTextfield.backgroundColor=[UIColor whiteColor];
usernameTextfield.placeholder=#"create username";
//password textfield
IBOutlet UITextField *passwordTextfield = [[UITextField alloc] initWithFrame:CGRectMake(45, usernameTextfield.frame.origin.y+75, 200, 40)];
passwordTextfield.textColor = [UIColor colorWithRed:0/256.0 green:84/256.0 blue:129/256.0 alpha:1.0];
passwordTextfield.font = [UIFont fontWithName:#"Helvetica-Bold" size:25];
passwordTextfield.backgroundColor=[UIColor clearColor];
passwordTextfield.placeholder=#"create password";
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(15, 80, 400, 400)];
[view addSubview:usernameTextfield];
[view addSubview:passwordTextfield];
[v addSubview:view];
}
-(IBAction) buttonClicked:(id)sender {
NSString *password = [passwordTextfield text];
NSString *username = [usernameTextfield text];
NSLog(#"username = %# and password = %#", username, password);
[self presentViewController:[ChooseFeedItemViewController new]
animated:YES completion:nil];
}
There's more to the .m file but it's irrelevant, i think
alloc init give you brand spanking new objects, NOT references to your existing ones. Use self.usernameTextField to access your existing object.
You are in completely over your head.
Do not create new text fields. Set up your text fields in Interface Builder (IB), and control-drag from your IB fields into the header of your program to create IBOutlets. Then use those IBOutlets in your code.
It does matter, and matter a great deal, that you are getting "local declaration of "X" hides instance variable" warnings.
The problem is that you have instance variables for your text fields, and then you have code that creates an unrelated set of text fields and installs them in your form. If you also created text fields in IB, then you've got duplicates of each text field, but only one is connected to your IBOutlet instance variables. If you never created the text fields in IB, then your outlets point to nil.
You should stop, find a good book or set of video tutorials on Objective C and/or iOS development, and go through the exercises to learn the basics. Your lack of understanding is more than a few forum questions is going to fix.

textFieldShouldReturn does not get called (textField loaded programmatically)

I'm currently loading a -UITextField programmatically and trying to make the keyboard go down once I click on 'Search'.
I declare the -UITextFeild inside the .m file as
UITextField *searchTextField;
Inside the .h file I do indeed declare the -UITextField's delegate
#interface firstChannel : UIViewController<LBYouTubePlayerControllerDelegate, UITableViewDelegate,UITableViewDataSource, NSXMLParserDelegate, UITextFieldDelegate, AVPlayerItemOutputPullDelegate>{
This is how I add the UITextField programmatically.
searchTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, -26, 300, 30)];
searchTextField.borderStyle = UITextBorderStyleRoundedRect;
searchTextField.font = [UIFont fontWithName:#"Heiti TC" size:13];
searchTextField.autocorrectionType = UITextAutocorrectionTypeNo;
searchTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
searchTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
searchTextField.placeholder = #"Search on the Channel";
searchTextField.borderStyle = UITextBorderStyleNone;;
searchTextField.textAlignment = UITextAlignmentCenter;
searchTextField.center = CGPointMake(160, 43);
searchTextField.textColor = [UIColor colorWithRed:(232.0/255.0) green:(232.0/255.0) blue:(232.0/255.0) alpha:(100.0/100.0)];
searchTextField.clearButtonMode = UITextFieldViewModeNever;
searchTextField.returnKeyType = UIReturnKeySearch;
[searchTextField setKeyboardAppearance:UIKeyboardAppearanceAlert];
[self.view.window addSubview:searchTextField];
[searchTextField becomeFirstResponder];
I added the delegate inside -viewDidLoad
searchTextField.delegate = self;
However when I click on "Search" on the keyboard nothing happens. I'm unsure why that's happening I've even debugged it by logging something once you hit returns but nothing happens.
Call the searchTExtField.delegate after you create and setup the text field.
Try moving all the code in viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad]; searchTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, -26, 300, 30)];
searchTextField.borderStyle = UITextBorderStyleRoundedRect;
searchTextField.font = [UIFont fontWithName:#"Heiti TC" size:13];
searchTextField.autocorrectionType = UITextAutocorrectionTypeNo;
searchTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
searchTextField.delegate = self;
searchTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
searchTextField.placeholder = #"Search on the Channel";
searchTextField.borderStyle = UITextBorderStyleNone;;
searchTextField.textAlignment = UITextAlignmentCenter;
searchTextField.center = CGPointMake(160, 43);
searchTextField.textColor = [UIColor colorWithRed:(232.0/255.0) green:(232.0/255.0) blue:(232.0/255.0) alpha:(100.0/100.0)];
searchTextField.clearButtonMode = UITextFieldViewModeNever;
searchTextField.returnKeyType = UIReturnKeySearch;
[searchTextField setKeyboardAppearance:UIKeyboardAppearanceAlert];
[self.view.window addSubview:searchTextField];
[searchTextField becomeFirstResponder];
}
Also, if you are using search bar then you need to use search bar delegate. If you are just using UITextfield, then you should be okay.
Have you implemented the delegate method (this method gets called when the user taps the return key):
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
//Perform search with text:
[self performSearch:[textField text]];
return NO;
}
This will resign the responder. Here you can also call your search method.

Drawing a line between two UIlabels when tapped or pressed together

I want to draw a line between two UILabels when i tap or hold both of them at the same time with code, i have no idea how to do this, it will be most appreciated if anyone has an advice , it will be most appreciated
This is how I would do it. My answer is tested btw...
To manage the tappable labels I would create my own label called LabelControl that extends UIControl. This custom control is going to have a UILabel (read-only for simplicity) as a subview. By doing this we will be able to add the Target-Action events UIControlEventTouchDown and UIControlEventTouchUpInside.
Here is the custom label:
The .h file:
#interface LabelControl : UIControl
#property (nonatomic, retain, readonly) UILabel *theLabel;
#end
The .m file:
#implementation LabelControl
#synthesize theLabel = _theLabel;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_theLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
_theLabel.backgroundColor = [UIColor clearColor];
_theLabel.userInteractionEnabled = NO;
[self addSubview:_theLabel];
}
return self;
}
-(void)dealloc {
[_theLabel release];
[super dealloc];
}
Then for the "line" that you want to draw, I would use a UIView because that way you could just use it's hidden property to hide/show the line. Add this code inside your ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.label1 = [[[LabelControl alloc] initWithFrame:CGRectMake(60, 50, 200, 40)] autorelease];
self.label1.theLabel.text = #"Hello";
self.label1.userInteractionEnabled = YES;
self.label1.backgroundColor = [UIColor blueColor];
[self.label1 addTarget:self action:#selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[self.label1 addTarget:self action:#selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.label1];
self.label2 = [[[LabelControl alloc] initWithFrame:CGRectMake(60, 150, 200, 40)] autorelease];
self.label2.theLabel.text = #"World";
self.label2.userInteractionEnabled = YES;
self.label2.backgroundColor = [UIColor purpleColor];
[self.label2 addTarget:self action:#selector(touchDown:) forControlEvents:UIControlEventTouchDown];
[self.label2 addTarget:self action:#selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.label2];
//the position of the line is hard-coded. You will have to modify this yourself
self.theLine = [[UIView alloc] initWithFrame:CGRectMake(60, 120, 200, 3)];
self.theLine.backgroundColor = [UIColor blueColor];
self.theLine.hidden = YES;
[self.view addSubview:self.theLine];
}
-(void)showOrHideLine {
if (self.label1.selected && self.label2.selected) {
NSLog(#"Both are selected");
self.theLine.hidden = NO;
} else {
self.theLine.hidden = YES;
}
}
-(void)touchDown:(id)sender {
//When any of the custom label gets the touch down event set the `selected` property
//to YES. (This property is inherited form `UIControl`
NSLog(#"Touch down");
LabelControl *labelControl = (LabelControl*)sender;
labelControl.selected = YES;
[self showOrHideLine];
}
-(void)touchUp:(id)sender {
//When any of the custom label gets the touch up event set the `selected` property
//to NO. (This property is inherited form `UIControl`
NSLog(#"Touch Up");
LabelControl *labelControl = (LabelControl*)sender;
labelControl.selected = NO;
[self showOrHideLine];
}
Let me know if you have any questions. Hope this helps!
I am going to outline it and give you some code (untested) but you have some work to make the full effect work.
Programtically, you could subclass UIButton. Inside your new subclass, put your touch recognition methods. Call it something like "customUIButton".
From your main view controller, create two instances of your UIButton and add them as subviews
customUIButton *Label1 = [[customUIButton alloc] init];
[Label1 setTitle:#"Your First Label" forState:UIControlStateNormal];
[Label1 addTarget:self action:#selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Label1];
customUIButton *Label2 = [[customUIButton alloc] init];
[Label2 setTitle:#"Your Second Label" forState:UIControlStateNormal];
[Label2 addTarget:self action:#selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:Label1];
When you push the buttons, it will try to call the method "itemClicked". Make that method and receive (id)sender... - (void)itemClicked: (id)sender { Put some logic in there to indicate that the button is being pushed. You know which button by referring to the sender that was sent.
Also in your view controller, go to the DrawRect method and put in the drawing logic.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 3.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextMoveToPoint(context, Label1.center.x, Label1.center.y);
CGContextAddLineToPoint(context, Label2.center.x, Label2.center.y);
CGContextStrokePath(context);
CGContextRestoreGState(context);
Put this in an "if statement" so that if both buttons have focus, it will be drawn (else skip the drawing code).
How about placing a line in IB using an Image View. Hide the Image View in your viewDidLoad method. Then, whenever the user taps one of the the UILabels, unhide the Image View holding your line. It may be tricky depending on your experience with Objective-C to detect touches on a UILabel. If it is, you can place invisible buttons over each label and that should do the trick for you. For more info about detecting touches on UILabels, check this link:
Handling Touch Event in UILabel and hooking it up to an IBAction

Custom UITextField created programmatically doesnt bring up keyboard on tap

I have a custom look designed for my textfields on iphone. I decided to create a class
MYTextField : UIView <UITextFieldDelegate>
I have a method
- (id)initWithPlaceholder:(NSString*)placeholder position:(CGPoint) position
that creates a UITextField with the desired view and look.
The sourcecode is as follows:
- (id)initWithPlaceholder:(NSString*)placeholder position:(CGPoint) position {
if (self = [super initWithFrame:CGRectMake(position.x, position.y, TEXTFIELD_WIDTH, TEXTFIELD_HEIGHT)]) {
UITextField *textField = [[[UITextField alloc] initWithFrame:CGRectMake(10, 200, 300, 40)] autorelease];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.font = [UIFont systemFontOfSize:15];
textField.placeholder = #"enter text";
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.keyboardType = UIKeyboardTypeDefault;
textField.returnKeyType = UIReturnKeyDone;
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[textField setUserInteractionEnabled:YES];
textField.delegate = self;
[self addSubview:textField];
}
return self;
}
The problem is that, on invoking the method, the UITextField is visible but on tapping on the textfield, the keyboard doesnt show up.
Is there anything I am missing?
PS: I found a couple of similar problems on Stackoverflow, but none of the solutions seem to work for me. :(
The issue here could be that the textfields frame doesn't lie within the frame of the UIView. Why use TEXTFIELD_WIDTH for the self.frame but not for textfield.frame?
Also, why subclass UIView rather that UITextField?

Resources