AutoComplete for UITextfield in iOS

我只是一个虾纸丫 提交于 2019-11-28 06:26:58

问题


I am working on new iOS application. In that app, I have 5 UITextFields and those are 1. first interest, second interest upto 5 interests.

I need to add Autocomplete for those 5 UITextFields. I have searched google for one day. I got some forums and tutorial for that. But I even have tried with Github links also.

According to my requirement, I have an array of data which is getting from my server. In that array, I have data like, coffee, cricket, etc. That is Autocomplete data. I need to display that array whenever user entered text in UITextField, if its related to my array of data, need to display below of that UITextFields.

For that purpose i used following code.

**// String in Search textfield

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

NSString *substring = [NSString stringWithString:textField.text];
    substring = [substring stringByReplacingCharactersInRange:range withString:string];
    [self searchAutocompleteEntriesWithSubstring:substring];
    return YES;
}

**

// Take string from Search Textfield and compare it with autocomplete array

- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {

// Put anything that starts with this substring into the autoCompleteArray
// The items in this array is what will show up in the table view

[autoCompleteArray removeAllObjects];
NSLog(@"autoCompleteArray %@",autoCompleteArray);
for(NSString *curString in elementArray) {
    NSRange substringRangeLowerCase = [curString rangeOfString:[substring lowercaseString]];
    NSRange substringRangeUpperCase = [curString rangeOfString:[substring uppercaseString]];

    if (substringRangeLowerCase.length != 0 || substringRangeUpperCase.length != 0) {
        [autoCompleteArray addObject:curString];
    }
}

autoCompleteTableView.hidden = NO;
[autoCompleteTableView reloadData];
      }

And I created UITableView as AutocompleteTableview in ViewDidLoad method.

**Issue is, if I type text as suppose "c", from my array of data displaying whatever text contains as "c" letter in tableview. But, if i typed "coff" no data displaying in that UITableView. Also how to validate which UITextField user clicking in tableviewdidselectrowatindexpath delegate method. I tried with assigning tag for those UITextFields, but its working in UITextFields delegate methods only, not in other place. so, whenever i selected data from UITableView, first UITextField only taking data not other UITextField.

Please give your valuable suggestion, which is the best way to display the autocomplete for UITextfields in iOS for multiple UITextfields and how to handle UITableView for displaying data. If anything mistakes in my content forgive me and please provide your valuable suggestions to fix this issue.

Thanks****


回答1:


Take two Global Array

NSMutableArray *muary_Interest_Main;
NSMutableArray *muary_Interest_Sub;

IN viewDidLoad Method

muary_Interest_Main = [[NSMutableArray alloc]initWithObjects:@"Cricket",@"Dancing",@"Painting",@"Swiming",@"guitar",@"movie",@"boxing",@"drum",@"hockey",@"chessing",@"gamming", 
    @"hunting",@"killing",@"shoping",@"jamm"@"zooming", nil]; 
muary_Interest_Sub = [[NSMutableArray alloc]init]; 


tbl_Search = [[UITableView alloc] initWithFrame: 
CGRectMake(4, 200, 320, 120) style:UITableViewStylePlain]; 
tbl_Search.delegate = self; 
tbl_Search.dataSource = self; 
tbl_Search.scrollEnabled = YES; 

[self.tbl_Search registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CellIdentifier"]; 
[self.view addSubview:self.tbl_Search]; 


[tbl_Search setHidden:TRUE];

Now write a below code in textfield delegates.

- (void)textFieldDidBeginEditing:(UITextField *)textField 
{ 
NSLog(@"%d",textField.tag); 
int_TextFieldTag = textField.tag; 

[self searchText:textField replacementString:@"Begin"]; 
} 

- (BOOL)textFieldShouldReturn:(UITextField *)textField { 
[textField resignFirstResponder]; 
tbl_Search.hidden = TRUE; 
return YES; 
} 

- (void)textFieldDidEndEditing:(UITextField *)textField 
{ 
tbl_Search.hidden = TRUE; 
} 

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
[self searchText:textField replacementString:string]; 
return YES; 
}

Write a method for search text

-(void) searchText:(UITextField *)textField replacementString:(NSString *)string
{

    if(int_TextFieldTag == 1)
    {
        tbl_Search.frame = CGRectMake(4, 200, 320, 120);

    }
    else if(int_TextFieldTag == 2)
    {
        tbl_Search.frame = CGRectMake(4, 248, 320, 120);
    }
    else if(int_TextFieldTag == 3)
    {
        tbl_Search.frame = CGRectMake(4, 268, 320, 120);
    }
    else if(int_TextFieldTag == 4)
    {
        tbl_Search.frame = CGRectMake(4, 268, 320, 120);
    }
    else
    {
        tbl_Search.frame = CGRectMake(4, 268, 320, 120);
    }



    NSString *str_Search_String=[NSString stringWithFormat:@"%@",textField.text];
    if([string isEqualToString:@"Begin"])
        str_Search_String=[NSString stringWithFormat:@"%@",textField.text];
    else if([string isEqualToString:@""])
        str_Search_String = [str_Search_String substringToIndex:[str_Search_String length] - 1];
    else
        str_Search_String=[str_Search_String stringByAppendingString:string];

    muary_Interest_Sub=[[NSMutableArray alloc] init];
    if(str_Search_String.length>0)
    {
        NSInteger counter = 0;
        for(NSString *name in muary_Interest_Main)
        {
            NSRange r = [name rangeOfString:str_Search_String options:NSCaseInsensitiveSearch];
            if(r.length>0)
            {
                [muary_Interest_Sub addObject:name];
            }

            counter++;

        }

        if (muary_Interest_Sub.count > 0)
        {
            NSLog(@"%@",muary_Interest_Sub);
            tbl_Search.hidden = FALSE;
            [self.tbl_Search reloadData];
        }
        else
        {
           tbl_Search.hidden = TRUE;
        }



    }
    else
    {
        [tbl_Search setHidden:TRUE];

    }

}

Tableview Delegates methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
return [muary_Interest_Sub count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"]; 
if (cell == nil) 
{ 
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"CellIdentifier"]; 
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
; 
} 
cell.textLabel.text = [muary_Interest_Sub objectAtIndex:indexPath.row]; 
return cell; 

} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
[self.view endEditing:YES]; 
if(int_TextFieldTag == 1) 
{ 
txt1.text=[muary_Interest_Sub objectAtIndex:indexPath.row]; 

} 
else if(int_TextFieldTag == 2) 
{ 
txt2.text=[muary_Interest_Sub objectAtIndex:indexPath.row]; 
} 
else if(int_TextFieldTag == 3) 
{ 
txt3.text=[muary_Interest_Sub objectAtIndex:indexPath.row]; 
} 
else if(int_TextFieldTag == 4) 
{ 
txt4.text=[muary_Interest_Sub objectAtIndex:indexPath.row]; 
} 
else 
{ 
txt5.text=[muary_Interest_Sub objectAtIndex:indexPath.row]; 
} 

} 

This also works on backspace of textfield. Try this. Hope this will suit your requirements.




回答2:


- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring{

    //Assume this array is the autocomplete array for which you get data from server

    NSMutableArray *autoCompleteArray = [[NSMutableArray alloc] initWithObjects:@"Coffee",@"Cricket",@"Volleyboll",nil];

    text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];

   // This is to create predicate filter for getting matched text 

   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@",text];

// store matched data for autocompletion in results array and reload data in your tableview based on this array's data

   NSArray *resultArray = [[NSArray alloc] initWithArray:[autoCompleteArray filteredArrayUsingPredicate:predicate]];
}



回答3:


Here is swift 3 inline autocomplete textfield example

  1. Image look like bellow

  2. create a project & add a textfield. Connect to viewcontroller named txtAutoComplete

  3. View controller code bellow

     import UIKit
    
       class ViewController: UIViewController ,UITextFieldDelegate{
    
    
        @IBOutlet weak var txtAutoComplete: UITextField!
    
         var autoCompletionPossibilities = ["01921687433", "01553377642", "0155776622"]
        var autoCompleteCharacterCount = 0
       var timer = Timer()
    
    
      override func viewDidLoad() {
         super.viewDidLoad()
    
    
          txtAutoComplete.delegate = self
     }
    
    
    
    
    
       func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { //1
           var subString = (textField.text!.capitalized as NSString).replacingCharacters(in: range, with: string) 
    subString = formatSubstring(subString: subString)
    
       if subString.characters.count == 0 { 
       // 3 when a user clears the textField
        resetValues()
           } else {
         searchAutocompleteEntriesWIthSubstring(substring: subString)   
        }
       return true
      }
    
     func formatSubstring(subString: String) -> String {
        let formatted = String(subString.characters.dropLast(autoCompleteCharacterCount)).lowercased().capitalized //5
        return formatted
     }
    
    func resetValues() {
       autoCompleteCharacterCount = 0
       txtAutoComplete.text = ""
      }
    
      func searchAutocompleteEntriesWIthSubstring(substring: String) {
      let userQuery = substring
      let suggestions = getAutocompleteSuggestions(userText: substring) 
    
        if suggestions.count > 0 {
          timer = .scheduledTimer(withTimeInterval: 0.01, repeats: false, block: { (timer) in //2
            let autocompleteResult =   self.formatAutocompleteResult(substring: substring, possibleMatches: suggestions)
               self.putColourFormattedTextInTextField(autocompleteResult: autocompleteResult, userQuery : userQuery) 
              self.moveCaretToEndOfUserQueryPosition(userQuery: userQuery) 
          })
    
         } else {
           timer = .scheduledTimer(withTimeInterval: 0.01, repeats: false, block: { (timer) in //7
              self.txtAutoComplete.text = substring
           })
           autoCompleteCharacterCount = 0
         }
    
    }
    
     func getAutocompleteSuggestions(userText: String) -> [String]{
       var possibleMatches: [String] = []
       for item in autoCompletionPossibilities { //2
          let myString:NSString! = item as NSString
          let substringRange :NSRange! = myString.range(of: userText)
    
          if (substringRange.location == 0)
           {
              possibleMatches.append(item)
          }
       }
       return possibleMatches
    }
    
     func putColourFormattedTextInTextField(autocompleteResult: String, userQuery : String) {
          let colouredString: NSMutableAttributedString = NSMutableAttributedString(string: userQuery + autocompleteResult)
    colouredString.addAttribute(NSForegroundColorAttributeName, value: UIColor.green, range: NSRange(location: userQuery.characters.count,length:autocompleteResult.characters.count))
    self.txtAutoComplete.attributedText = colouredString
    }
    
     func moveCaretToEndOfUserQueryPosition(userQuery : String) {
        if let newPosition = self.txtAutoComplete.position(from: self.txtAutoComplete.beginningOfDocument, offset: userQuery.characters.count) {
        self.txtAutoComplete.selectedTextRange = self.txtAutoComplete.textRange(from: newPosition, to: newPosition)
    }
          let selectedRange: UITextRange? = txtAutoComplete.selectedTextRange
    txtAutoComplete.offset(from: txtAutoComplete.beginningOfDocument, to: (selectedRange?.start)!)
       }
    
     func formatAutocompleteResult(substring: String, possibleMatches: [String]) -> String {
         var autoCompleteResult = possibleMatches[0]
    autoCompleteResult.removeSubrange(autoCompleteResult.startIndex..<autoCompleteResult.index(autoCompleteResult.startIndex, offsetBy: substring.characters.count))
    autoCompleteCharacterCount = autoCompleteResult.characters.count
    return autoCompleteResult
        }
      }
    
  4. Source code is given to GitHub.GitHub Link :https://github.com/enamul95/AutoCompleteTextField




回答4:


You can use the following links which describes how we can use autocompletion. I tried with the AutocompletionTableview (second link) and it worked perfectly.

https://github.com/EddyBorja/MLPAutoCompleteTextField

https://github.com/keyf/AutocompletionTableView



来源:https://stackoverflow.com/questions/26113380/autocomplete-for-uitextfield-in-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!