Adding textfield below another textfield programmatically in iOS - ios

In my app I want to programmatically add textfield below another if required on click of a button. I already had provided two textFields. if a user want to add another textfield he can do so by clicking a button. I have already written code to obtain the textfield but the problem is that it overlaps the already designed textFields. How can I do it?
Is there any way through which I can get the x and Y co-ordinates of already designed textfield so that I can place new textField relative to those co-ordinates.

This code add textField to view dynamically when every click action on button
ExampleViewController.h
#import <UIKit/UIKit.h>
#interface ExampleViewController :UIViewController<UITextFieldDelegate>
#property int positionY;
#property int fieldCount;
#property (strong,nonatomic) UIScrollView *scroll;
#end
ExampleViewController.m
#import "ExampleViewController.h"
#interface ExampleViewController ()
#end
#implementation ExampleViewController
#synthesize positionY;
#synthesize fieldCount;
#synthesize scroll;
- (void)viewDidLoad {
[super viewDidLoad];
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scroll.backgroundColor = [UIColor whiteColor];
[self.view addSubview:scroll];
UIButton *clickToCreateTextField = [[UIButton alloc] initWithFrame:CGRectMake(40, 80, self.view.frame.size.width-80, 75)];
[clickToCreateTextField setTitle:#"Create Text Field" forState:UIControlStateNormal];
[clickToCreateTextField addTarget:self action:#selector(clickedButton) forControlEvents:UIControlEventTouchUpInside];
[clickToCreateTextField setBackgroundColor:[UIColor blackColor]];
[scroll addSubview:clickToCreateTextField];
positionY = clickToCreateTextField.center.y;
fieldCount = 0;
// Do any additional setup after loading the view.
}
-(void) clickedButton{
//add text field programmitacally
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(40, positionY, self.view.frame.size.width-80, 75)];
textField.delegate = self;
//give a tag to determine the which textField tapped
textField.tag = fieldCount;
textField.placeholder = [NSString stringWithFormat:#"Your dynamically created textField: %d", fieldCount ];
[scroll addSubview:textField];
//check if the textFields bigger than view size set scroll size and offset
if (positionY>= self.view.frame.size.height) {
scroll.contentOffset = CGPointMake(0, positionY);
scroll.contentSize = CGSizeMake(scroll.frame.size.width, scroll.frame.size.height+positionY);
}
fieldCount++;
//increase the position with a blank place
positionY = positionY+textField.frame.size.height+20;
}
#pragma mark TextField Delegate Methods
-(void) textFieldDidBeginEditing:(UITextField *)textField{
//Do what ever you want
}
-(void) textFieldDidEndEditing:(UITextField *)textField{
[textField resignFirstResponder];
//do anything
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
You can do any additional changes on this code.
I think this example explain your answer.
Hope it helps.

Use a counter and calculate y like this counter*texfield.frame.size.height.

Related

Button change position when alert view is showed

I am showing an alert on my UITableView.
This is the code
-(void)showAlertMaintenance{
AppDelegate * appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
[RMUniversalAlert showAlertInViewController:self withTitle:nil message:appDelegate.maintenanceStr cancelButtonTitle:#"OK" destructiveButtonTitle:nil otherButtonTitles:nil tapBlock:^(RMUniversalAlert * _Nonnull alert, NSInteger buttonIndex) {
if(buttonIndex == alert.cancelButtonIndex){
}
}];
}
The button is a subviews of one section header in my UITableview
UIButton *sendInviteCodeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sendInviteCodeButton addTarget:self
action:#selector(shareInvitationCode)
forControlEvents:UIControlEventTouchUpInside];
[sendInviteCodeButton setTitle:#"招待コードをシェアする" forState:UIControlStateNormal];
[sendInviteCodeButton sizeToFit];
[sendInviteCodeButton setTitleColor:[UIColor colorWithRed:215.0f/255.0f green:116.0f/255.0f blue:52.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
sendInviteCodeButton.translatesAutoresizingMaskIntoConstraints = NO;
sendInviteCodeButton.frame = CGRectMake(20, 155.0f, SCREEN_BOUNDS_SIZE_PORTRAIT_WIDTH - 40, 30.0f);
[sendInviteCodeButton.layer setMasksToBounds:YES];
[sendInviteCodeButton.layer setCornerRadius:5.0f];
[sendInviteCodeButton.layer setBackgroundColor:[UIColor whiteColor].CGColor];
[sendInviteCodeButton setBackgroundColor:[UIColor whiteColor]];
[sendInviteCodeButton.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];
[invitationView insertSubview:sendInviteCodeButton atIndex:0];
Before
After
When the alert is showed, the button is being pushed to top left corner of the screen.
Please help!
If you already calculate specific frame for your button, you should remove [sendInviteCodeButton sizeToFit];.
Just remove [sendInviteCodeButton sizeToFit];
Hope it help. :)
Since you are relying on frames to setup the layout you should have a dedicated UIView subclass for your tableview header.You need to override layoutSubviews method because at this point the header view will have it's own frame correctly set so your relative calculations for subviews (including the button) will make sense. Here's a quick sample code:
#import <UIKit/UIKit.h>
#interface MyTableViewHeader : UIView
#end
#implementation MyTableViewHeader
-(instancetype)init
{
self = [super init];
if (self) {
//setup button here (omit setting frames)
}
return self;
}
-(void)layoutSubviews
{
//set the button frame here
[super layoutSubviews];
}
#end
#interface ViewController : UIViewController<UITableViewDelegate>
#property (nonatomic, strong) MyTableViewHeader *header;
#end
#implementation ViewController
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//You will probably want some logic here
//to decide if you want to display the header
if (!self.header) {
self.header = [MyTableViewHeader new];
}
return self.header;
}
#end
As an alternative you could also setup autolayout for your table header view.
I found out the problem caused by this
[sendInviteCodeButton.layer setMasksToBounds:YES];
setMasksToBounds - is a Boolean indicating whether sublayers are clipped to the layer’s bounds

Sliding the keyboard to the left in iOS

I'm wondering if there is a way to slide the first-responder keyboard to the left or to the right when the user press a button.
http://cl.ly/image/143K3t403d1m/1.png
I make the button as a keyboard-accessory view. When it's tapped the keyboard should slide to the left displaying another custom inputs panel.
Any ideas?
If you want a keyboard that can be selected from the system (using the globe key), you'll need to read this article about creating a Custom Keyboard App Extension for iOS 8.
If you just want to be able to switch between inputView objects, the following code will get you there:
// ViewController.m
#import "ViewController.h"
#interface ViewController () {
}
#pragma mark -
#pragma mark - UI Controls
#property (strong, nonatomic) UIInputView *inputView;
#property (strong, nonatomic) UITextField *textField;
#end
#implementation ViewController
#pragma mark -
#pragma mark - View Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUserInterface];
}
#pragma mark -
#pragma mark - Keyboard switching
- (void)switchKeyboard {
// Simply toggle the "inputView" for self.textField
if (self.textField.inputView == nil) {
self.textField.inputView = self.inputView;
} else {
self.textField.inputView = nil;
}
[self.textField resignFirstResponder];
[self.textField becomeFirstResponder];
}
#pragma mark -
#pragma mark - UI Setup
// All of the code below here
// is for pure, in-code AutoLayout
- (void)setupUserInterface {
[self createControls];
[self setupControls];
[self layoutControls];
}
- (void)createControls {
self.textField = [[UITextField alloc] init];
self.textField.borderStyle = UITextBorderStyleRoundedRect;
self.inputView = [[UIInputView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 216.0f)];
self.inputView.backgroundColor = [UIColor lightGrayColor];
}
- (void)setupControls {
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44.0f)];
toolbar.backgroundColor = [UIColor lightGrayColor];
// When the button is tapped, it'll execute "switchKeyboard" above
UIBarButtonItem *switchButton = [[UIBarButtonItem alloc] initWithTitle:#"Switch" style:UIBarButtonItemStyleDone target:self action:#selector(switchKeyboard)];
toolbar.items = #[switchButton];
self.textField.inputAccessoryView = toolbar;
[self.textField setTranslatesAutoresizingMaskIntoConstraints:NO];
}
- (void)layoutControls {
[self.view addSubview:self.textField];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[textfield]-|"
options:0
metrics:nil
views:#{#"textfield": self.textField}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-(height)-[textfield(==height)]"
options:0
metrics:#{#"height" : #(40)}
views:#{#"textfield": self.textField}]];
}
#end
Caveat: You will need to do a lot of tweaking to make sure the user experience is good. In my testing, on the simulator (iPhone 4S), this works ok, but isn't the smoothest user experience.

Intercept UITextField touch

I would like to intercept a touch on a UITextField, for instance when I first load it I give it a #selector() to load a different method instead of the delegate stuff?
This is my attempt:
descriptionText = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 25.0, infoView.frame.size.width - 20, 100.0)];
descriptionText.backgroundColor = [UIColor whiteColor];
descriptionText.textColor = [UIColor blackColor];
descriptionText.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
descriptionText.userInteractionEnabled = YES;
[descriptionText addTarget:self action:#selector(loadInfoView:) forControlEvents:UIControlEventTouchUpInside];
descriptionText.font = [UIFont fontWithName:#"Helvetica" size:15];
// show view
[infoView addSubview:descriptionText];
However when I debug the method:
- (void)loadInfoView
{
NSLog(#"load other view here");
}
Your problem is in the forControlEvents:: try UIControlEventEditingDidBegin
[descriptionText addTarget:self action:#selector(loadInfoView:) UIControlEventEditingDidBegin];
Your #selector(loadInfoView:) is also wrong if you have - (void)loadInfoView
or #selector(loadInfoView:) and - (void)loadInfoView: (id) sender
or #selector(loadInfoView) and - (void)loadInfoView
However, why you don't use the UITextFieldDelegate?
.m
#interface ViewController () <UITextFieldDelegate>
#property (strong, nonatomic) UITextField *descriptionText;
#end
Remember to:
self.descriptionText.delegate = self;
Then:
-(void) textFieldDidBeginEditing:(UITextField *)textField
{
if (textField == self.descriptionText)
{
[self loadInfoView];
}
}
Keyboard:
If you don't want to show the keyboard you need to add a [descriptionText resignFirstResponder];
I'm not sure you can get actions to be called on a text field on touch like you want.
If that doesn't work, why don't you attach a tap gesture recognizer to your text field?

UIKeyboard behind Picker View

I have Two text field in my View. i am using picker view as input. when ever picker is enabled the keyboard is visible behind the picker.The other issue is when i use Resign First responder for the text field in the Action the first time it shows picker without the keyboard at behind.But the second time when i click the text field the KeyBoard appears instead of picker. Here is my code.
- (IBAction)selectService:(id)sender
{
[self createActionSheet];
//[selectServiceTextBox resignFirstResponder];
pickerType = #"servicePickerType";
servicePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
pickerArray = [[NSArray alloc]initWithObjects:#"Money Transfer",#"Bill Payment", nil];
servicePicker.dataSource = self;
servicePicker.delegate = self;
servicePicker.showsSelectionIndicator = YES;
[actionSheet addSubview:servicePicker];
// rowIndex = [stateTextField.text intValue];
//[servicePicker selectRow:rowIndex inComponent:0 animated:NO];
}
- (IBAction)wayOfTransfer:(id)sender
{
if ([selectedItem isEqualToString:#""])
{
NSLog(#"empty selection");
}
else if ([selectServiceTextBox.text isEqualToString:#"Money Transfer"])
{
[self createActionSheet];
// [secondTextBox resignFirstResponder];
//[selectServiceTextBox resignFirstResponder];
pickerType = #"MoneyTransferMethod";
servicePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
pickerArrayTwo = [[NSArray alloc]initWithObjects:#"Cash Pick-up",#"Bank Account",#"Zym Card", nil];
servicePicker.dataSource = self;
servicePicker.delegate = self;
servicePicker.showsSelectionIndicator = YES;
[actionSheet addSubview:servicePicker];
}
}
You have to make the picker and keyboard appear exclusive of each other so that both can gracefully be switched between each other.. One way to do it is make the picker hidden by default and then bring it on screen when the first textview is on focus using an animation... Similarly hide it while bringing keyboard on using the second textview.
I have made a sample project that does this and have tested it... I hope this is what you intend to do...
//ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextViewDelegate,UIPickerViewDataSource,UIPickerViewDelegate>
#property (weak, nonatomic) IBOutlet UITextView *firstTextView;
#property (weak, nonatomic) IBOutlet UITextView *secondTextView;
#property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
#end
//ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController{
NSMutableArray *pickerDataSource;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
pickerDataSource = [[NSMutableArray alloc] initWithObjects:#"data1",#"data2", nil];
self.pickerView.frame = CGRectMake(0, self.view.frame.size.height, 320, 162);
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
}
// Textview delegates
-(void)textViewDidBeginEditing:(UITextView *)textView{
if ([textView isEqual:self.firstTextView]) {
[textView resignFirstResponder];
if (self.pickerView.frame.origin.y >= self.view.frame.size.height) {
[self showPicker];
}else{
[self hidePicker];
}
}else{
[self hidePicker];
[self.secondTextView becomeFirstResponder];
}
}
-(void)showPicker{
[UIView animateWithDuration:0.2 animations:^{
self.pickerView.frame = CGRectMake(self.pickerView.frame.origin.x, self.pickerView.frame.origin.y - self.pickerView.frame.size.height, self.pickerView.frame.size.width, self.pickerView.frame.size.height);
}];
}
-(void)hidePicker{
[UIView animateWithDuration:0.2 animations:^{
self.pickerView.frame = CGRectMake(self.pickerView.frame.origin.x, self.pickerView.frame.origin.y + self.pickerView.frame.size.height, self.pickerView.frame.size.width, self.pickerView.frame.size.height);
}];
}
// Picker Delegates
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return pickerDataSource.count;
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
self.firstTextView.text = pickerDataSource[row];
}
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [pickerDataSource objectAtIndex:row];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Please let me know if there is anything unclear.
i think you need hide keyboard behind picker view ... simple you put this code in your text click action method
UItextfield delegate method.....
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[text_box_variable resignFirstResponder];
}

inputaccessoryview not showing (StoryBoard)

I have been trying to incorporate a UIView/Toolbar above my keyboard but have had no luck. When I added a toolbar it was scrambled so thus I need to put it into a UIView but the UIView does not want to appear above the keyboard. Code Below:
My Header:
#property (nonatomic, Strong) IBOutlet UITextView *textView;
#property (nonatomic, strong) IBOutlet UIToolbar *TitleBar;
#property (nonatomic, weak) IBOutlet UIView *AddView;
The ViewDidLoad:
- (void)viewDidLoad
{
// observe keyboard hide and show notifications to resize the text view appropriately
/*[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
*/
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]) {
// iOS 7
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
} else {
// iOS 6
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
self.attributionTitle.delegate = self;
self.attribution.delegate = self;
textView.scrollEnabled = YES;
// quoteText.layer.borderColor = [UIColor blackColor].CGColor;
// quoteText.layer.borderWidth = 1.0f;
// textView.delegate = self; // code or in IB
[textView becomeFirstResponder];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
The textViewDidBeginEditing:
-(void)textViewDidBeginEditing:(UITextView *)textView
{
self.textView.inputAccessoryView = self.AddView;
}
Here is to show the UIView is connected:
I added the textView.inputAccessoryView = AddView;to the ViewDidLoadthen deleted the view from my storyboard and remade it. Lastly I added the UIView to the bottom black bar.
Adding the inputAccessoryView in textViewDidBeginEditing is probably too late. The input accessory view should be set before that, e.g., in the viewDidLoad method.
Try something like:
-(void)viewDidLoad{
[super viewDidLoad];
UIView
myTextField.inputAccessoryView = [self accessoryViewWithPreviousEnabled:NO nextEnabled:YES];
// more stuff as required...
}
And a method for creating a previous/next button (you'll need to provide your own images for the buttons and implements the previousAccessoryViewButtonTapped: and previousAccessoryViewButtonTapped: methods). It takes two BOOL parameters to indicate if the previous and/or next buttons should be enabled.
#pragma mark - Accessory view methods
-(UIView *)accessoryViewWithPreviousEnabled:(BOOL)previousEnabled nextEnabled:(BOOL)nextEnabled{
previousButton = [UIButton buttonWithType:UIButtonTypeCustom];
previousButton.frame = CGRectMake(10, 2, 60, 30);
[previousButton setImage:[UIImage imageNamed:PREVIOUS_BUTTON] forState:UIControlStateNormal];
previousButton.enabled = previousEnabled;
[previousButton addTarget:self action:#selector(previousAccessoryViewButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
nextButton.frame = CGRectMake(80, 2, 60, 30);
[nextButton setImage:[UIImage imageNamed:NEXT_BUTTON] forState:UIControlStateNormal];
nextButton.enabled = nextEnabled;
[nextButton addTarget:self action:#selector(nextAccessoryViewButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
UIView *transparentBlackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 34)];
transparentBlackView.backgroundColor = [UIColor colorWithRed:0.f green:0.f blue:0.f alpha:0.6f];
UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 34)];
[accessoryView addSubview:transparentBlackView];
[accessoryView addSubview:previousButton];
[accessoryView addSubview:nextButton];
return accessoryView;
}
Note this method is hard coded for an iPad in landscape orientation. You need to change it for an iPhone.
The problem is that your self.AddView is already in your interface (because you put it there, in the storyboard). It can't be in two places at once.

Resources