I have some dynamically allocated texfields and in which i am entering the text,
Now i have got two problems here
1) After 2-3 button clicks, i mean changing the views and coming back to the same view than the data is not being removed from the textfield the previous data in the textfield is being present.
the code i have tried with are
answerTextField.text = #"";
answerTextField.text = nil;
2) I am unable to delete the textfield data in which i am appending the data that is coming from the textfield.text
-(void) keyPressed: (NSNotification*) notification {
if ([[[notification object]text] isEqualToString:#" "])
{
UITextField *textField = (UITextField *)[self.view viewWithTag:nextTag];
textField.text = #"";
[textField becomeFirstResponder];
nextTag = textField.tag;
}
else
{
[[NSNotificationCenter defaultCenter] removeObserver: self name:UITextFieldTextDidChangeNotification object: nil];
NSLog(#"TextField tag value :%d",tagCount);
NSLog(#"TextField next tagg tag value :%d",nextTag);
if (tagCount == nextTag+1)
{
UITextField *textField = (UITextField *)[self.view viewWithTag:nextTag];
[textField resignFirstResponder];
NSLog(#"append string :%#",appendString);
}
else
{
NSLog(#"TextField nexttag value before :%d",nextTag);
nextTag = nextTag + 1;
NSLog(#"Letter is%#",[[notification object]text]);
str= [[NSString alloc]initWithFormat:#"%#",[[notification object]text]];
NSLog(#"TextField String :%#",str);
NSLog(#"TextField nexttag value after :%d",nextTag);
[appendString appendString:[NSString stringWithFormat:#"%#",str]];
NSLog(#"Content in MutableString: %#",appendString);
}
NSLog(#"The tags in keypressed:%d",nextTag);
UITextField *textField = (UITextField *)[self.view viewWithTag:nextTag];
[textField becomeFirstResponder];
}
// For inserting Spaces taken from array.
if(tagCount+300 == nextTag)
{
for (int m=0 ; m< [intArray count]; m++)
{
[appendString insertString:#" " atIndex:[[intArray objectAtIndex:m]intValue]];
NSLog(#"FinalString : %#",appendString);
}
}
}
Edited: The textfield data that i am storing is being made nil, but the on the textfield the data is being remained it is not being removed, for the textfield i have added a background image, do not know whether it makes any difference or not, i am attaching the code for it:
UIImageView *myView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"text_line.png"]];
myView.center = CGPointMake(5, 27);
[letterField insertSubview:myView atIndex:0];// mgViewTitleBackGround is image
[myView release];
To clear text field do this code in viewWillAppear:
NSArray *arraysubViews = [self.view subViews];
for(UIView *subView in arraysubViews){
if([subView isKindOfClass:[UITextField class]]){
// if(subView.tag == MY_TEXT_VIEW_TAG)
(UITextField *)subView.text = #"";
}
}
This will remove the text in every UITextField in your view. If you need to clear some textfields only, uncomment the code; which will check against tag value
EDIT
NSArray *arraysubViews = [self.view subviews];
for(UIView *subView in arraysubViews){
if([subView isKindOfClass:[UITextField class]]){
// if(subView.tag == MY_TEXT_VIEW_TAG)
UITextField *textField = (UITextField *)subView;
textField.text = #"";
}
}
UIView does not have a subViews method. It is subViews instead.
Related
How to remove the array of UITextField from Scroll Subview, initially when I call API I get some Array Value based on Count I have created Dynamic UITextFiled in My View, But I do know how to remove the Subview
here my sample Code:
// NSArray *strings;
// UIScrollView *scrollView;
// NSMutableArray *textFields;
self.textFields = [NSMutableArray array];
const CGFloat width = 320;
const CGFloat height = 31;
const CGFloat margin = 0;
CGFloat y = 0;
for(NSString *string in strings) {
UITextField *textField = [[UITextField alloc]
initWithFrame:CGRectMake(0, y, width, height)];
textField.delegate = self;
textField.text = string;
[scrollView addSubview:textField];
[textFields addObject:textField];
[textField release];
y += height + margin;
}
scrollView.contentSize = CGSizeMake(width, y - margin);
Firs of all when you are creating this dynamic textField set single tag like 101.
for(NSString *string in strings) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, y, width, height)];
textField.delegate = self;
textField.text = string;
//Set tag 101
textField.tag = 101;
[scrollView addSubview:textField];
[textFields addObject:textField];
[textField release];
y += height + margin;
}
Now make one method to remove all this dynamic textFields.
- (void)removeAllDynamicTextFields {
for(UIView *view in scrollView.subViews){
if([view isKindOfClass:[UITextField class]] && view.tag == 101){
[view removeFromSuperview];
}
}
}
}
If you want to remove that textfield from your view then you can simply removi that textfield from your superview.
[yourtextfield removeFromSuperView];
scrollView.subViews.forEach({textField in
if textField is UITextField , textField.tag == XX {
textField.removeFromSuperView()
}
})
Add tag and then remove whatever text view with loop
for (UITextView *i in scrollView){
if([i isKindOfClass:[UITextView class]]){
UITextView *tv = (UITextView *)i;
if(tv.tag == 1){ // Whatever textview want to remove add tag here
/// Write your code
[tv removeFromSuperview];
}
}
}
I have a single UIButton in the view of my UIViewController. I also have ten more that are in a subview in the main view. I want to find all these buttons. So far I have:
-(void)findAllButtons{
for(UIView *view in self.view.subviews) {
if ([view isKindOfClass:[myButton class]]){
NSLog(#"found a button!");
}
}
}
It is only finding the single button though and not the other ten. Why is that? Shouldn't it iterate every single subview and then find them?
for (UIView *subView in scroll.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
UIButton *btn = (UIButton*)subView;
if (btn.tag == selectedButton.tag) {
btn.layer.borderWidth = 1.0f;
btn.layer.borderColor = [UIColor darkGrayColor].CGColor;
}else{
btn.layer.borderWidth = 1.0f;
btn.layer.borderColor = [UIColor clearColor].CGColor;
}
}
}
Just a few lines of code
-(void)findAllButtons {
[self findButtonsInSubviews:self.view.subviews];
}
- (void)findButtonsInSubviews:(NSArray *)subviews {
for(UIView *view in subviews) {
if ([view isKindOfClass:[UIButton class]]){
NSLog(#"found a button!");
} else {
[self findButtonsInSubviews:view.subviews];
}
}
}
A recursive function using Objective-C blocks like this will find all views of a given subclass type as specified in the test block in the view hierarchy of the given view:
NSMutableArray *marrAllButtons = [NSMutableArray new];
BOOL (^viewTest)(UIView*) = ^BOOL(UIView* viewToTest) {
return [view isKindOfClass:[UIButton class]];
};
void(^viewEnumerator)(UIView*) = ^(UIView* outerView){
for (UIView *view in outerView.subviews)
{
if (viewTest(view))
{
[marrAllButtons addObject:view];
}
else
{
viewEnumerator(view);
}
}
};
viewEnumerator(self.view);
NSLog(#"All Buttons %#", marrAllButtons);
- (NSMutableArray *)buttonsInView:(UIView *)view
{
NSArray *subviews = view.subviews;
NSMutableArray *buttons = [NSMutableArray array];
for (UIView *subview in subviews)
{
if ([subview isKindOfClass:[UILabel class]])
{
[buttons addObject:subview];
}
else if(subview.subviews)
{
[buttons addObjectsFromArray:[self buttonsInView:subview]];
}
}
return buttons;
}
Your method is right if all your button already have in self.view (main view).
Just set tag for all button to check and also make sure that all button are on the main view. I hope this will work.
-(void)findAllButtons{
for(UIView *view in self.view.subviews) {
if ([view isKindOfClass:[myButton class]]){
UIButton *button = (UIButton*)view;
NSLog(#"found a button with tag:%d",button.tag);
}
}
}
for(UIView * subView in view.subviews) // here write Name of you ScrollView.
{
// NSLog(#"test %#", [subView class]);
if([subView isKindOfClass:[UIButton class]])
{
UIButton *button = (UIButton*)subView;
[button setSelected:NO] ;
NSString *s1;
s1 = #",";
s1 = [s1 stringByAppendingString:[NSString stringWithFormat:#"%#",button.titleLabel.text ]];
s1 = [s1 stringByAppendingString:[NSString stringWithFormat:#"%#",#"," ]];
NSRange range = [temp_Colors_Name_comma rangeOfString:s1 ];
if(range.location == NSNotFound)
{
}
else
{
[button setSelected:YES];
}
}
}
I'm currently adding 5 textviews onto the viewcontroller programatically inside the viewDidLoad method.
for (int i = 0; i < 5; i++) {
//Add 5 textviews
UITextView *reqTV = [[UITextView alloc] initWithFrame:CGRectMake(30,30,250,50)];
reqTV.text = #"This is a textview";
[self.view addSubview:reqTV];
}
If later, I want to delete (not hide) these 5 textviews with a button click, how would I do that?
I have thought of using this, but am not sure how to call all 5 textviews to delete them.
- (void)removeTextViewButton:(id)sender {
[reqTV removeFromSuperview]; //remove textview
}
Thank you.
I see two easy ways:
You can save your textViews inside array as ivar of your controller.
And later remove each textView in array.
for (int i = 0; i < 5; i++) {
...
[textViews addObject: reqTV];
...
}
- (void)removeTextViewButton:(UIButton *)sender {
[textViews makeObjectsPerformSelector:#selector(removeFromSuperview)];
}
2. Assign static tag for each textView:
for (int i = 0; i < 5; i++) {
...
reqTV.tag = 1001; // for example
}
- (void)removeTextViewButton:(UIButton *)sender {
NSArray *subs = [NSArray arrayWithArray: self.view.subviews];
for (UIView *sub in subs) {
if (sub.tag == 1001) {
[sub removeFromSuperview];
}
}
}
Used code below to remove UITextViews:
- (void)removeTextViewButton:(id)sender {
NSArray *reqTVViews = [NSArray arrayWithArray: self.view.subviews];
for (UIView *tvView in reqTVViews) {
if ([tvView isKindOfClass:[UITextView class]]) {
[tvView removeFromSuperview];
}
}
}
When you are adding UITextFields on viewController use tag value to uniquely identify each textField.
You can store each tag value in an array for further use, eg.
#property (nonatomic, strong) NSMutableArray *tagArray;
NSMutableArray *tagArray = [NSMutableArray array];
for (int i = 101; i <= 105; i++ ) {
UITextField *txt = [UITextField alloc] init]; //for eg.
...
...
txt.tag = i;
[arr addObject:[NSNumber numberWithInt:i]];
[self.view addSubView:txt];
}
When you want to delete any of the textField or all then...
UIView *view = [self.view viewWithTag:<tag value>];
[view removeFromSuperview];
eg.
for (int i = 0; i < tagArray.count; i++) {
NSInteger tag = [[arr objectAtIndex:i] intValue];
UITextField *txt = (UITextField *)[self.view viewWithTag:tag];
[txt removeFromSuperview];
}
You can remove all subview in one go
- (void)removeTextViewButton:(id)sender
{
for (UIView *subview in views.subviews)
{
[subview removeFromSuperview];
}
}
Happy Coding.. :)
I have aUISearchBar, I get theUITextfield in it and then I want to set selected Text range but it's always return nil. This is my code:
UITextField *searchField = [self.searchBar valueForKey:#"_searchField"];
[searchField becomeFirstResponder]; // focus to this searchfield
And I fill in the text:
self.searchBar.text = #"This is text";
And checked if theUITextField text is filled in and it is. Still, all the methods regardingUITextPosition andUITextRange return nil:
UITextRange *selectedRange = [searchField selectedTextRange]; //selectedRange = nil
UITextPosition *newPosition = [searchField positionFromPosition:selectedRange.start offset:addressToComplete.street.length]; //newPosition = nil
UITextRange *newRange = [searchField textRangeFromPosition:newPosition toPosition:newPosition]; //newRange = nil
My code is wrong something?
Have you tried Logging UITextField *searchField? its nil from the looks of it.. i think your code is supposed to be..
(UITextField *)[self.searchBar valueForKey:#"_searchField"]
([after trying your code] OooOoKayyy.. it works.. hahaha..) By the way this is how i get UITextField inside searchBar..
for (id object in [[[self.searchBar subviews] objectAtIndex:0] subviews])
{
if ([object isKindOfClass:[UITextField class]])
{
UITextField *searchField = (UITextField *)object;
break;
}
}
First i tried what you have which is:
UITextField *searchField = (UITextField *)[searchBar valueForKey:#"_searchField"];
searchBar.text = #"This is text";
// and logging your searchField.text here.. returns nil/empty..
and i tried rearranging it like this...
searchBar.text = #"This is text";
UITextField *searchField = (UITextField *)[searchBar valueForKey:#"_searchField"];
NSLog(#"searchFields.text :%#", searchField.text);
again i tried your code under -(void)viewDidLoad but no good, yeah it is always nil as you said.. now it looks like this..
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
searchBar.text = #"This is text"; // not important
UITextField *searchField = [searchBar valueForKey:#"_searchField"];
[searchField becomeFirstResponder];
UITextRange *selectedRange = [searchField selectedTextRange]; //selectedRange = not nil anymore
NSLog(#"searchField.text :%# -> selectedRange :%#\n\n" , searchField.text, selectedRange);
}
//i've also tried it inside uibutton's event and i worked .. >.<
i programmatically selectedTextRange(for example purposes) and probably it something to do with the xibs autolayout or something (weird i dont experience it) but there it is, try it.. :)
i hope i've helped you..
Happy coding.. Cheers!
My app has a registration view, I compare strings in password textfield and confirm password textfield , if they dont match I want user go back to password textfield
This question done it with using tags
UITextField jump to previous
Is there a way to accomplish this without using tags?
//call next textfield on each next button
- (BOOL) textFieldShouldReturn:(UITextField *) textField {
BOOL didResign = [textField resignFirstResponder];
if (!didResign) return NO;
if ([textField isKindOfClass:[SOTextField class]])
dispatch_async(dispatch_get_current_queue(),
^ { [[(SOTextField *)textField nextField] becomeFirstResponder]; });
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
if (textField==self.confirmPassword) {
if ([self.password.text isEqualToString:self.confirmPassword.text]) {
NSLog(#"password fields are equal");
}
else{
NSLog(#"password fields are not equal prompt user to enter correct values");
//[self.password becomeFirstResponder]; doesnt work
}
}
}
Without using tags, you could create an NSArray of textfield outlets the describes the desired ordering.
Declare and init like this ...
#property(nonatomic,strong) NSArray *textFields;
- (NSArray *)textFields {
if (!_textFields) {
// just made these outlets up, put your real outlets in here...
_textFields = [NSArray arrayWithObjects:self.username, self.password, nil];
}
return _textFields;
}
You'll need to fetch the text field that currently has focus, if there is one...
- (UITextField *)firstResponderTextField {
for (UITextField *textField in self.textFields) {
if ([textField isFirstResponder]) return textField;
}
return nil;
}
Then advance focus like this...
- (void)nextFocus {
UITextField *focusField = [self firstResponderTextField];
// what should we do if none of the fields have focus? nothing
if (!focusField) return;
NSInteger index = [self.textFields indexOfObject:textField];
// advance the index in a ring
index = (index == self.textFields.count-1)? 0 : index+1;
UITextField *newFocusField = [self.textFields objectAtIndex:index];
[newFocusField becomeFirstResponder];
}
And move focus backward like this...
- (void)previousFocus {
UITextField *focusField = [self firstResponderTextField];
// what should we do if none of the fields have focus? nothing
if (!focusField) return;
NSInteger index = [self.textFields indexOfObject:textField];
// backup the index in a ring
index = (index == 0)? self.textFields.count-1 : index-1;
UITextField *newFocusField = [self.textFields objectAtIndex:index];
[newFocusField becomeFirstResponder];
}