2013-05-15 3 views
6

Aggiungo questo Method al mio codice per formattare il campo di testo. Sto usando il codice qui sotto per provare ad aggiungere il metodo, ma non funziona, cosa sto facendo male?Aggiunta di un metodo al mio uitextfield nella cella?

file h

NSString* phone_; 
UITextField* phoneFieldTextField; 
@property (nonatomic,copy) NSString* phone; 

di file .m

@synthesize phone = phone_; 

ViewDidLoad{ 
self.phone = @""; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; 

// Make cell unselectable and set font. 
cell.selectionStyle = UITableViewCellSelectionStyleNone; 
cell.textLabel.font = [UIFont fontWithName:@"ArialMT" size:13]; 

if (indexPath.section == 0) { 

    UITextField* tf = nil; 
    switch (indexPath.row) { 
case 3: { 
      cell.textLabel.text = @"Phone" ; 
      tf = phoneFieldTextField = [self makeTextField:self.phone placeholder:@"xxx-xxx-xxxx"]; 
      phoneFieldTextField.keyboardType = UIKeyboardTypePhonePad; 

      [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES]; 

      [cell addSubview:phoneFieldTextField]; 
      break ; 
} 
    // Textfield dimensions 
    tf.frame = CGRectMake(120, 12, 170, 30); 

    // Workaround to dismiss keyboard when Done/Return is tapped 
    [tf addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit]; 

} 
} 

// Textfield value changed, store the new value. 
- (void)textFieldDidEndEditing:(UITextField *)textField { 

//Section 1. 
if (textField == nameFieldTextField) { 
    self.name = textField.text ; 
} else if (textField == addressFieldTextField) { 
    self.address = textField.text ; 
} else if (textField == emailFieldTextField) { 
    self.email = textField.text ; 
} else if (textField == phoneFieldTextField) { 
    self.phone = textField.text ; 
}else if (textField == dateOfBirthTextField) { 
    self.dateOfBirth = textField.text ; 
} 

} 

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
NSString* totalString = [NSString stringWithFormat:@"%@%@",textField.text,string]; 

// if it's the phone number textfield format it. 
if(textField.tag == 10) { 
    if (range.length == 1) { 
     // Delete button was hit.. so tell the method to delete the last char. 
     textField.text = [self formatPhoneNumber:totalString deleteLastChar:YES]; 
    } else { 
     textField.text = [self formatPhoneNumber:totalString deleteLastChar:NO ]; 
    } 
    return false; 
} 

return YES; 
NSLog(@"Testing should change character in range"); 
} 

-(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar { 

if(simpleNumber.length == 0) return @""; 
// use regex to remove non-digits(including spaces) so we are left with just the numbers 
NSError *error = NULL; 
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error]; 
simpleNumber = [regex stringByReplacingMatchesInString:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:@""]; 

// check if the number is to long 
if(simpleNumber.length>10) { 
    // remove last extra chars. 
    simpleNumber = [simpleNumber substringToIndex:10]; 
} 

if(deleteLastChar) { 
    // should we delete the last digit? 
    simpleNumber = [simpleNumber substringToIndex:[simpleNumber length] - 1]; 
} 

// 123 456 7890 
// format the number.. if it's less then 7 digits.. then use this regex. 
if(simpleNumber.length<7) 
    simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d+)" 
                  withString:@"($1) $2" 
                   options:NSRegularExpressionSearch 
                   range:NSMakeRange(0, [simpleNumber length])]; 

else // else do this one.. 
    simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d{3})(\\d+)" 
                  withString:@"($1) $2-$3" 
                   options:NSRegularExpressionSearch 
                   range:NSMakeRange(0, [simpleNumber length])]; 

if (simpleNumber.length == 10 && deleteLastChar == NO) { [self resignFirstResponder];} 

return simpleNumber; 
NSLog(@"Testing format phone number"); 
} 

#pragma mark - TextField 
-(UITextField*) makeTextField: (NSString*)text 
       placeholder: (NSString*)placeholder { 
UITextField *tf = [[UITextField alloc] init]; 
tf.placeholder = placeholder; 
tf.text = text ; 
tf.autocorrectionType = UITextAutocorrectionTypeNo ; 
tf.autocapitalizationType = UITextAutocapitalizationTypeNone; 
tf.adjustsFontSizeToFitWidth = YES; 
tf.returnKeyType = UIReturnKeyDone; 
tf.textColor = [UIColor colorWithRed:56.0f/255.0f green:84.0f/255.0f blue:135.0f/255.0f alpha:1.0f]; 
return tf ; 
} 

risposta

8

Il metodo che si sta utilizzando:

-(NSString*) formatPhoneNumber:(NSString*) simpleNumber deleteLastChar:(BOOL)deleteLastChar 

restituisce un oggetto NSString. Nel tuo caso stai chiamando il metodo correttamente ma non stai impostando l'oggetto NSString restituito su nulla. È semplicemente appeso lì. È necessario impostare la phoneFieldTextField al testo formattato in questo modo:

phoneFieldTextField.text = [self formatPhoneNumber:phoneFieldTextField.text deleteLastChar:YES]; 

NOTA - Se volete saperne di più sui metodi di ritorno poi leggere il seguente:

Se avete notato alcune maggior parte dei metodi sono di il tipo vuoto. Tu sai che questo quando si vede un metodo come questo:

- (void)someMethod { 
    int x = 10; 
} 

Quali mezzi vuoto è che il someMethod non restituisce niente. Esegue semplicemente il codice all'interno del metodo. Ora metodi di restituire un oggetto o qualche altro tipo di dati simile a questa:

- (int)returnSomething { 
    int x = 10; 
    return x; 
} 

La prima cosa che si nota è il tipo di ritorno non è più vuoto, è un int. Ciò significa che il metodo restituirà un tipo intero. In questo caso il codice viene eseguito e viene restituito il valore di x.

Questo è solo l'inizio dell'argomento dei metodi di restituzione, ma si spera che ciò renda le cose un po 'più chiare per voi.

3

Prima di tutto è necessario dirci Che cosa non funziona non abbiamo la tua app e tutto il tuo codice. Devi spiegare cosa funziona e cosa non funziona esattamente. Ci è voluto più tempo del necessario per capire che la tua domanda è perché il textField:shouldChangeCharactersInRange: non funziona. Hai impostato un breakpoint nella funzione per vedere cosa stava facendo. Non è stato chiamato?

Detto tuo bug è che textField:shouldChangeCharactersInRange: sta usando i tag per identificare i campi di testo, ma il resto del codice sta usando puntatori

// if it's the phone number textfield format it. 
- if(textField.tag == 10) { 
+ if(textField.tag == phoneFieldTextField) { 

Inoltre è non include il codice per makeTextField:placeholder: Ci potrebbero essere problemi in esso pure. Confronta il tuo codice con lo makeTextField:placeholder: nel mio esempio.

Ho creato un progetto di esempio su GitHub. Per risolvere questo. Dimostrò anche un approccio migliore alla creazione di moduli di input utilizzando le visualizzazioni di tabella.

https://github.com/GayleDDS/TestTableViewTextField.git

guardare sia diff per vedere quello che ho fatto a YourTableViewController.m a far funzionare le cose.

https://github.com/GayleDDS/TestTableViewTextField/commit/d65a288cb4da7e1e5b05790ea23d72d472564793 https://github.com/GayleDDS/TestTableViewTextField/commit/31ecaec8c9c01204643d72d6c3ca5a4c58982099

C'è un mucchio di altri problemi qui:

  • È necessario chiamare [super viewDidLoad]; nel tuo metodo viewDidLoad
  • Hai bisogno di indentare correttamente il tuo codice (potrebbe essere un problema di copia e incolla)
  • Dovresti utilizzare lo storyboard per creare le tue visualizzazioni. Vedi la scheda soluzione migliore e l'implementazione BetterTableViewController.

deve guardare - iOS Sviluppo Video

+0

In primo luogo, la mia domanda nel titolo dice esattamente ciò che non funziona. In secondo luogo, il "bug" non si trova in 'textField: shouldChangeCharactersInRange:' perché non è nemmeno il mio metodo, e Dana in basso è riuscito a farlo funzionare correttamente. Ho impostato il textField.tag di conseguenza. Ho anche registrato ciò che viene chiamato.Il mio caso 3 viene chiamato correttamente e tutto funziona bene con la cella e il segnaposto. – Jason

+0

Il problema è la formattazione della cella per utilizzare il metodo del numero di telefono che ho trovato su questo sito e referenziato correttamente. 'superView didLoad' è anche nel mio' viewDidLoad' non è necessario per questa domanda. Sto anche usando gli storyboard come suggerivi. – Jason

+1

Ciao @ Jason hai scaricato e verificato la mia app di esempio? Ok la tua impostazione del tag hai impostato anche il delegato? Puoi includere anche il codice makeTextField nella tua domanda di cui sopra. Grazie – GayleDDS

1

Sembra che tu non sta impostando il delegato <UITextFieldDelegate> nel file h, e non assegnando la proprietà delegata del tuo campo di testo a self tf.delegate = self; per chiamare - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

Provalo e fammi sapere come va

-Buona fortuna!

1

@koray aveva ragione: è necessario impostare il delegato per la classe. La classe deve essere dichiarato come l'attuazione del UITextFieldDelegate protocollo (in aggiunta a UITableViewDataSource, suppongo)

poi nel makeTextField: (NSString *) testo segnaposto: (NSString *) Metodo segnaposto, è necessario disporre di qualcosa di simile a:

-(UITextField*) makeTextField: (NSString*)text 
       placeholder: (NSString*)placeholder { 
    UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(40, 0, 150, 40)]; 
    tf.placeholder = placeholder; 
    // (...) 
    tf.delegate = self; 
    return tf ; 
} 

Quindi è necessario impostare correttamente i metodi delegato. Nel seguente esempio, ho una barra di navigazione, dal momento che il tastierino numerico non ha un pulsante di ritorno o un pulsante fatto. I ha installato un pulsante che fungerà da pulsante di fatto (si può avere un altro modo di fare la tastiera andare, e il passaggio tra i campi di testo attiverà la fine dell'edizione in ogni caso):

- (void) textFieldDidBeginEditing:(UITextField *)textField { 
    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneEditing:)]; 

    self.navBar.topItem.rightBarButtonItem = doneBtn; 
} 

- (void) doneEditing:(id) sender { 
    if(phoneFieldTextField.isFirstResponder) { 
     [phoneFieldTextField resignFirstResponder]; 
    } 
    // (...) 
    self.navBar.topItem.rightBarButtonItem = nil; 
} 

Poi, la magia accade in il metodo textdidEndEditing delegate:

- (void)textFieldDidEndEditing:(UITextField *)textField { 
    if (textField == phoneFieldTextField) { 
     self.phone = [self formatPhoneNumber:textField.text deleteLastChar:YES] ; // convert 
     [phoneFieldTextField setText:self.phone]; // display 
    } 
    // (...) 
}