EddyBorja / MLPAutoCompleteTextField

UITextfield subclass with autocomplete menu. For iOS.
Other
1.21k stars 222 forks source link

Cannot connect the autoCompleteDataSource to the IBOutlet #34

Closed trobrock closed 10 years ago

trobrock commented 10 years ago

I am fairly new to IOS, and am sure I am missing something. I am unable to connect the autoCompleteDataSource to my IBOutlet in my view, but I can manually connect it by calling setAutoCompleteDataSource. Relevant code is below.

GBProductAutocomplete.h

#import <Foundation/Foundation.h>
#import "MLPAutoCompleteTextFieldDataSource.h"

@interface GBProductAutocomplete : NSObject <MLPAutoCompleteTextFieldDataSource>

@end

GBProductAutocomplete.m

#import "GBProductAutocomplete.h"

@implementation GBProductAutocomplete

- (void)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
 possibleCompletionsForString:(NSString *)string
            completionHandler:(void (^)(NSArray *))handler
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(queue, ^{
        NSArray *completions;
        completions = [NSArray arrayWithObjects:@"hello", @"world", nil];

        handler(completions);
    });
}

@end

GBViewController.h

#import <UIKit/UIKit.h>
#import "MLPAutoCompleteTextFieldDelegate.h"

@class GBProductAutocomplete;
@interface GBManualAddViewController : UIViewController <UITextFieldDelegate, MLPAutoCompleteTextFieldDelegate>

@property (weak, nonatomic) IBOutlet MLPAutoCompleteTextField *autocompleteTextField;
@property (strong, nonatomic) IBOutlet GBProductAutocomplete *autocompleteDataSource;
@property (weak, nonatomic) IBOutlet MLPAutoCompleteTextField *textField;

@end

GBViewController.m

#import "GBManualAddViewController.h"
#import "MLPAutoCompleteTextField.h"
#import "GBProductAutocomplete.h"

@interface GBManualAddViewController ()

@end

@implementation GBManualAddViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
//    [self.textField setAutoCompleteDataSource:[[GBProductAutocomplete alloc] init]];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
          shouldConfigureCell:(UITableViewCell *)cell
       withAutoCompleteString:(NSString *)autocompleteString
         withAttributedString:(NSAttributedString *)boldedString
        forAutoCompleteObject:(id<MLPAutoCompletionObject>)autocompleteObject
            forRowAtIndexPath:(NSIndexPath *)indexPath;
{
    //This is your chance to customize an autocomplete tableview cell before it appears in the autocomplete tableview
    NSString *filename = [autocompleteString stringByAppendingString:@".png"];
    filename = [filename stringByReplacingOccurrencesOfString:@" " withString:@"-"];
    filename = [filename stringByReplacingOccurrencesOfString:@"&" withString:@"and"];
    [cell.imageView setImage:[UIImage imageNamed:filename]];

    return YES;
}

- (void)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
  didSelectAutoCompleteString:(NSString *)selectedString
       withAutoCompleteObject:(id<MLPAutoCompletionObject>)selectedObject
            forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(selectedObject){
        NSLog(@"selected object from autocomplete menu %@ with string %@", selectedObject, [selectedObject autocompleteString]);
    } else {
        NSLog(@"selected string '%@' from autocomplete menu", selectedString);
    }
}

@end

If I uncomment the line [self.textField setAutoCompleteDataSource:[[GBProductAutocomplete alloc] init]]; in viewDidLoad the autocomplete will work, but I cannot figure out why I cannot drag from the outlet in the nib to connect the property.

EddyBorja commented 10 years ago

Hard to tell what's going on in a nib file from code, did you create an object instance in your nib that is set to the datasource class? This is the object you would connect to your IBOutlet for the view.

The latest version of the demo project connects the datasource to the autocomplete textfield directly in the nib file, check that nib file out and see if it helps.

trobrock commented 10 years ago

This is what my nib looks like https://gist.github.com/trobrock/cb00b52aae730a9ca785. I confirmed the Files Owner is configured to my Controller class and linked to the correct view, and the text field is using the proper subclass for the autocomplete. The autoCompleteDataSource outlet shows in the toolbar on the right, but wont let me drag from it to connect it to the code.

trobrock commented 10 years ago

Also just pulled down the demo project and when I enter something in the text field I get the following:

2014-05-30 09:37:32.483 MLPAutoCompleteDemo[93499:60b] Unknown class DEMODataSource in Interface Builder file.
2014-05-30 09:37:37.330 MLPAutoCompleteDemo[93499:1003] *** Assertion failure in -[MLPAutoCompleteFetchOperation main], /Users/trobrock/Sites/MLPAutoCompleteTextField/MLPAutoCompleteTextField/MLPAutoCompleteTextField.m:895
2014-05-30 09:37:37.331 MLPAutoCompleteDemo[93499:1003] GoogleAnalytics 2.0b4 void GAIUncaughtExceptionHandler(NSException *) (GAIUncaughtExceptionHandler.m:41): Uncaught exception: An autocomplete datasource must implement either autoCompleteTextField:possibleCompletionsForString: or autoCompleteTextField:possibleCompletionsForString:completionHandler:
gioy commented 10 years ago

Hi, I'm getting the same error. I'm on osx 10.9.3, and I'm using xcode 5.1.1. I tried to run the demo on both iOS 7.0 and 7.1, but I'm getting the same error described by trobrock.

Thank you for your time.

Giorgio

On Fri, May 30, 2014 at 06:38 PM, Trae Robrock, wrote:

Also just pulled down the demo project and when I enter something in the text field I get the following:

2014-05-30 09:37:32.483 MLPAutoCompleteDemo[93499:60b] Unknown class DEMODataSource in Interface Builder file.
2014-05-30 09:37:37.330 MLPAutoCompleteDemo[93499:1003] *** Assertion failure in -[MLPAutoCompleteFetchOperation main], /Users/trobrock/Sites/MLPAutoCompleteTextField/MLPAutoCompleteTextField/MLPAutoCompleteTextField.m:895
2014-05-30 09:37:37.331 MLPAutoCompleteDemo[93499:1003] GoogleAnalytics 2.0b4 void GAIUncaughtExceptionHandler(NSException *) (GAIUncaughtExceptionHandler.m:41): Uncaught exception: An autocomplete datasource must implement either autoCompleteTextField:possibleCompletionsForString: or autoCompleteTextField:possibleCompletionsForString:completionHandler:

Reply to this email directly or view it on GitHub: https://github.com/EddyBorja/MLPAutoCompleteTextField/issues/34#issuecomment-44671717

EddyBorja commented 10 years ago

Can you guys confirm that you have have DEMODataSource.h and DEMODataSource.m in the project?

gioy commented 10 years ago

This is really strange. In the symbol navigator pane I can see the definition for DEMODataSource, but clicking on it shows only the header file. What's really weird it's that I can see the definition for the following methods: -setSimulateLatency: -setTestWithAutoCompleteObjectInsteadOfStrings: -simulateLatency -testWithAutoCompleteObjectInsteadOfStrings

but clicking on any of them doesn't do or show anything.

Can't find any DEMODataSource.m at all.

I'll try to clone the repository again.

EddyBorja commented 10 years ago

Did recloning it work? How about cleaning and rebuilding the project?

gioy commented 10 years ago

I've tried to clone the project twice. Same error. I even tried to download the iOS 6.1 Simulator. Nothing changes. I can't find any DEMODatasource.* file at all, but in the symbol navigator I can see the definitions of DEMODataSource.h.

trobrock commented 10 years ago

I actually do have those file cloned:

trobrock@Traes-MacBook-Pro [12:56:14] [~/Sites/MLPAutoCompleteTextField] [master *]
-> % find ./ -name 'DEMOData*'
.//MLPAutoCompleteDemo/DEMODataSource.h
.//MLPAutoCompleteDemo/DEMODataSource.m

However I don't see them in the file explorer:

screen shot 2014-06-03 at 12 57 47 pm

gioy commented 10 years ago

same here.

EddyBorja commented 10 years ago

Have you guys downloaded the 2 files manually and added them to the demo project? Does it still give the error?

bluekite2000 commented 10 years ago

I see you use xib and drag the autcompleteDatasource to the Autocomplete Datasource object to set the outlet. How can I do the same thing using storyboard?

gioy commented 10 years ago

@bluekite2000 I made a really basic version of the MLPAutoCompleteDemo that uses storyboard: https://github.com/gioy/MLPAutoCompleteDemoStoryboard

oziade commented 9 years ago

Thanks @gioy. In my case, the problem came from the empty data source object label in the storyboard (by default). I added one and it works like a charm.

harryhow commented 9 years ago

HELP! I also had problem to add valid dataSource. My implementation is like this,

- (void)viewDidLoad {

    NSLog(@"++++viewDidLoad");

    [super viewDidLoad];

    self.autocompleteTextField = [[MLPAutoCompleteTextField alloc] initWithFrame:CGRectMake(10, 200, 300, 40)];
    self.autocompleteTextField.delegate = self;
    self.autocompleteTextField.autoCompleteDataSource = self.autocompleteDataSource;
    self.autocompleteTextField.autoCompleteDelegate = self;

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShowWithNotification:) name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHideWithNotification:) name:UIKeyboardDidHideNotification object:nil];

    [self.typeSwitch addTarget:self
                        action:@selector(typeDidChange:)
              forControlEvents:UIControlEventValueChanged];

    //Supported Styles:
    //[self.autocompleteTextField setBorderStyle:UITextBorderStyleBezel];
    //TODO[self.autocompleteTextField setBorderStyle:UITextBorderStyleLine];
    //[self.autocompleteTextField setBorderStyle:UITextBorderStyleNone];
    [self.autocompleteTextField setBorderStyle:UITextBorderStyleRoundedRect];

    //You can use custom TableViewCell classes and nibs in the autocomplete tableview if you wish.
    [self.autocompleteTextField registerAutoCompleteCellClass:[CustomAutoCompleteCell class]
                                       forCellReuseIdentifier:@"CustomCellId"];

    [self.view addSubview:self.autocompleteTextField];

    NSLog(@"----viewDidLoad");

}

And I also create dataSource via Storyboard like @gioy 's example and also check @oziade 's hint. But after these, got no luck and keep having this error.

rminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An autocomplete datasource must implement either autoCompleteTextField:possibleCompletionsForString: or autoCompleteTextField:possibleCompletionsForString:completionHandler:'

Any hint?