UIPicker with searchbar?

Discussion in 'iOS Programming' started by trey5498, Feb 11, 2014.

  1. trey5498, Feb 11, 2014
    Last edited: Feb 11, 2014

    trey5498 macrumors regular

    Joined:
    Jun 16, 2008
    #1
    I am trying to set up a UIPickerView with a UISearchBar that will help to find the info of states. I have the UIPickerView working beautifully. However, I can not get the searchbar to function with the picker. I have set the Searchbar delegate to the main controller.


    Here is the code that is supposed to do it, I know at the moment it is filtering and removing some (would like it to just jump to the correct name as I type it without filtering). This doesn't update. Can anyone direct me to how to finish this out and how to correctly jump to the state without filtering?

    This is for Xcode 5 IOS 7

    The Array ListOfStates is the filtered array

    and States is the main array


    Code:
    (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
        return 1;
    }
    
    -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
        
        if (searching) {
            return _ListOfStates.count;
        }else{
            return _States.count;
        }
        
    }
    
    #pragma mark Picker Delegate Methods
    
    -(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
        
        if (searching) {
           
            return [_ListOfStates objectAtIndex:row];
        } else {
            
            return [_States objectAtIndex:row];
            
        }
    }
    
    (void)searhBar:(UISearchBar *)SearchBar textDidChange:(NSString *) searchText {
        
        [_ListOfStates removeAllObjects];
            
            if (searchText.length == 0) {
                searching = NO;
            } else {
                searching = YES;
                
               
                
                for (NSString *StateName in _States) {
                    NSRange stateNameRange = [StateName rangeOfString:searchText options:NSCaseInsensitiveSearch];
                    
                    if (stateNameRange.location != NSNotFound) {
                        [_ListOfStates addObject:StateName];
                    }
                }
                
            }
            
            [_StatePickerView reloadAllComponents];
       
    }
    
     
  2. waterskier2007 macrumors 68000

    waterskier2007

    Joined:
    Jun 19, 2007
    Location:
    White Lake, MI
    #2
    Are you saying that the picker view doesn't update? or it doesn't just jump to the right one? Is this because there are multiple items that contain the search string?

    Edit: do you make sure to set up the pickerView DataSource and Delegate as your view controller?
     
  3. trey5498 thread starter macrumors regular

    Joined:
    Jun 16, 2008
    #3
    I did set up the data source and the delegate to the view controller. As far as just having the App function as a UIPickerView example, it works perfectly.

    The issue is solely with the UISearchBar. I know it can work with UITableView, and I have seen it in other Apps work with UIPickerViews. However, in my case, not only does the UIPickerView NOT update with the filtered array, I have no idea how to leave the original array alone and just simply jump to the one I am searching for.

    It shouldnt be that much extra coding to make it work, I just am at a loss.
     
  4. trey5498 thread starter macrumors regular

    Joined:
    Jun 16, 2008
    #4
    Update:

    I have gotten it to update with the filtered array correctly now. I corrected a typo and moved the reload call up. So when you type "N" only the states that begin with "N" will show up.

    Now I have to figure out how to keep the array untouched and just jump to the letters you begin to type. Any idea how to do that?

    Here is the updated code:

    Code:
    - (void)searchBar:(UISearchBar *)SearchBar textDidChange:(NSString *) searchText {
        
        [_ListOfStates removeAllObjects];
        if (searchText.length == 0) {
            searching = NO;
        } else {
            searching = YES;
            
            for (NSString *StateName in _States) {
                NSRange stateNameRange = [StateName rangeOfString:searchText options:NSCaseInsensitiveSearch];
                
                if (stateNameRange.location != NSNotFound) {
                    [_ListOfStates addObject:StateName];
                    [_StatePickerView reloadAllComponents];
                }
            }
                
        }
            
        [_StatePickerView reloadAllComponents];
    }
    
    
     
  5. waterskier2007 macrumors 68000

    waterskier2007

    Joined:
    Jun 19, 2007
    Location:
    White Lake, MI
    #5
    maybe something like this?

    Code:
    
    - (void)searchBar:(UISearchBar *)SearchBar textDidChange:(NSString *) searchText {
        
    
        if (searchText.length == 0) {
            searching = NO;
        } else {
            searching = YES;
            int i = 0;
            int locatedIndex = -1;
            for (NSString *StateName in _States) {
                NSRange stateNameRange = [StateName rangeOfString:searchText options:NSCaseInsensitiveSearch];
                
                if (stateNameRange.location != NSNotFound) {
                    locatedIndex = i;
                }
               i++;
            }
                
        }
    
        if (locatedIndex > -1) {
           [_StatePickerView selectRow:locatedIndex inComponent:0 animated:YES];
        }
            
    }
    
    
    edit: you probably want to setup the loop so that you break out after finding a matching string
     
  6. trey5498 thread starter macrumors regular

    Joined:
    Jun 16, 2008
    #6
    That did the trick. I have a few other things I need to make it work perfectly with what I want, but that is it ;)

    The other thing that just came up is I decided to use the PList to help keep track of all the information instead of large amounts of arrays.

    Here is what I got:

    Code:
    NSString *StatePath = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];
    
    NSDictionary *StateDictionary = [[NSDictionary alloc] initWithContentsOfFile:StatePath];
    
    _States = StateDictionary[@"States"];
    
    Now the array populates just fine, but I am not sure how to pull it out with the pickerview. I thought maybe:

    Code:
    return [_States objectAtIndex:row[@"StateName"];
    
    Here is an example of the plist:

    Code:
    <dict>
    	<key>States</key>
    	<array>
    		<dict>
    			<key>StateName</key>
    			<string>Alabama</string>
    			<key>Est</key>
    			<string>1819</string>
    			<key>Cap</key>
    			<string>Montgomery</string>
    			<key>Pop</key>
    			<string>4822023</string>
    			<key>Large</key>
    			<string>Birmingham</string>
    		</dict>
    .................
    
    and pushing to a label for the Capital would look like:

    Code:
    CapitalTextLabel.text = _States[indexPath.row][@"Cap"];
    
     

Share This Page