textFieldShouldReturn not being called


#1

The textFieldShouldReturn method isn’t being entered when the “Done” button is pressed. In fact, nothing at all seems to happen.

I set File’s Owner to be the delegate for the UITextField and declared that WhereamiViewController conforms to the UITextFieldDelegate protocol. I’m not sure what else the problem would be…


#2

Did you implement the method textFieldShouldReturn:?

...
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    return YES;
}

#3

Yes, it looks like this:

- (BOOL)textFieldShoudReturn:(UITextField *)textField
{
    [self findLocation];
    
    [textField resignFirstResponder];
    
    return YES;
}

#4

You could set a breakpoint to this method, to see whether it´s called. Or you write
NSLog(@“TextFieldShouldReturn was called”);
into the method.
Such interface builder trouble can be really annoying…


#5

Does it look like this in the right hand inspector in the xib file?
when you click on the textField and the arrow icon in the inspector
http://share.pho.to/3Tng4/original
and when you click on the files owner and the third icon in the inspector
http://share.pho.to/3Tnfz/original


#6

Yes, I did both those things which is how I know the method isn’t being entered.

For the first image, yes. I’m not sure your second image is what you meant - it doesn’t seem very informative…


#7

The WhereamiViewController methods that are being called are:

initWithNibName: bundle:
viewDidLoad
mapView: didUpdateUserLocation:

None of the other methods are entered, which I assume makes sense given that textFieldShouldReturn is not being entered, and the other methods are dependent on that call.

Here’s all the Whereami code:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface WhereamiViewController : UIViewController
    <CLLocationManagerDelegate, MKMapViewDelegate, UITextFieldDelegate>
{
    CLLocationManager *locationManager;
    
    IBOutlet MKMapView *worldView;
    IBOutlet UIActivityIndicatorView *activityIndicator;
    IBOutlet UITextField *locationTitleField;
}

- (void)findLocation;
- (void)foundLocation:(CLLocation *)loc;

@end
#import "WhereamiViewController.h"
#import "BNRMapPoint.h"

@implementation WhereamiViewController

- (id)initWithNibName:(NSString *)nibNameOrNil
               bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    
    if (self)
    {
        locationManager = [[CLLocationManager alloc] init];
        
        [locationManager setDelegate:self];
        
        [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    }
    
    return self;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    
    NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
    if (t < -180)
    {
        return;
    }
    
    [self foundLocation:newLocation];
}

- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error
{
    NSLog(@"could not find location: %@", error);
}

- (void)dealloc
{
    [locationManager setDelegate:nil];
}

- (void)viewDidLoad
{
    [worldView setShowsUserLocation:YES];
}

- (void)mapView:(MKMapView *)mapView
    didUpdateUserLocation:(MKUserLocation *)userLocation
{
    CLLocationCoordinate2D loc = [userLocation coordinate];
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
    [worldView setRegion:region animated:YES];
}

- (BOOL)textFieldShoudReturn:(UITextField *)textField
{
    [self findLocation];
    
    [textField resignFirstResponder];
    
    return YES;
}

- (void)findLocation
{
    [locationManager startUpdatingLocation];
    [activityIndicator startAnimating];
    [locationTitleField setHidden:YES];
}

- (void)foundLocation:(CLLocation *)loc
{
    CLLocationCoordinate2D coord = [loc coordinate];
    
    BNRMapPoint *mp = [[BNRMapPoint alloc] initWithCoordinate:coord title:[locationTitleField text]];
    
    [worldView addAnnotation:mp];
    
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 250, 250);
    [worldView setRegion:region animated:YES];
    
    // Reset the UI
    [locationTitleField setText:@""];
    [activityIndicator stopAnimating];
    [locationTitleField setHidden:NO];
    [locationManager stopUpdatingLocation];
}

@end

I would appreciate any insight.


#8

If I add “[locationManager startUpdatingLocation];” back to initWithNibName:bundle:, then locationMangerDidUpdate:fromLocation:toLocation: gets called, so it seems able to receive messages as a MKMapViewDelegate and a CLLocationManagerDelegate, but not as a UITextFieldDelegate.


#9

I finally figured out that I had “textFieldShoudReturn” instead of “textFieldShouldReturn”. I visually checked that a couple of times, but didn’t notice the discrepancy until I copy pasted from the reference to the line right above my method and compared them right next to each other. o_O


#10

[quote]Yes, it looks like this:

[code]- (BOOL)textFieldShoudReturn:(UITextField *)textField
{
[self findLocation];

[textField resignFirstResponder];

return YES;[/code]

}[/quote]
[size=150]Giant TIP[/size] :slight_smile: Do not enter published-method names by hand, even if you are an excellent touch typer; always copy and paste them from the class or protocol references.


#11

Great! I myself am using the autocompletion too fast… Always in tableViews I select the method …didDeselect…
instead of didSelect :wink: Also a very common forum topic in the later chapters.
But don´t copy them from somewhere! It takes too long to search. If you want to have autocompletion, just type

and the autocompletion offers you the whole method together with return type.
Push enter to use the suggestion
If you type the return type first, you waste a lot of logic of the autocompletion!