6

テキストフィールドをフォーマットするために、このメソッドをコードに追加しています。以下のコードを使用してメソッドを追加しようとしていますが、機能しません。何が間違っていますか?

.h ファイル

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

.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 ;
}
4

4 に答える 4

7

使用している方法:

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

NSString オブジェクトを返します。あなたの場合、メソッドを正しく呼び出していますが、返された NSString オブジェクトを何にも設定していません。ぶら下がっているだけです。次のように phoneFieldTextField をフォーマットされたテキストに設定する必要があります。

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

注 - return メソッドについて詳しく知りたい場合は、以下をお読みください。

ほとんどのメソッドがvoid型であることに気付いた場合。次のようなメソッドを見ると、これがわかります。

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

void が意味することは、someMethod が何も返さないということです。メソッド内のコードを実行するだけです。オブジェクトまたはその他のデータ型を返すメソッドは次のようになります。

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

最初に気付くのは、戻り値の型が void ではなく int になっていることです。これは、メソッドが整数型を返すことを意味します。この場合、コードが実行され、x の値が返されます。

これは return メソッドのトピックの始まりにすぎませんが、うまくいけば、物事が少し明確になることを願っています.

于 2013-05-15T17:12:35.370 に答える
3

まず、が機能していないかをお知らせください。アプリとすべてのコードがありません。何が機能し、何が機能していないかを正確に説明する必要があります。あなたの質問がなぜ機能しtextField:shouldChangeCharactersInRange:ないのかを理解するのに必要以上に時間がかかりました。関数にブレークポイントを設定して、関数が何をしているかを確認しましたか。呼ばれていませんでしたか?

つまり、バグはtextField:shouldChangeCharactersInRange:タグを使用してテキストフィールドを識別しているが、残りのコードはポインターを使用しているということです

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

また、コードも含まれていませんでしたmakeTextField:placeholder:。そこにも問題がある可能性があります。makeTextField:placeholder:あなたのコードを私のサンプルと比較してください。

GitHub にサンプル プロジェクトを作成しました。これを修正するには。また、テーブル ビューを使用して入力フォームを作成するためのより優れた方法のデモも行います。

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

両方の差分を見て、YourTableViewController.m動作させるために私が何をしたかを確認してください。

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

ここには他にもたくさんの問題があります:

  • [super viewDidLoad] を呼び出す必要があります。あなたのviewDidLoadメソッドで
  • コードを正しくインデントする必要があります (カット アンド ペーストの問題である可能性があります)。
  • ビューを作成するには、ストーリーボードを使用する必要があります。Better Solution タブと BetterTableViewController の実装を参照してください。

必見 - iOS 開発ビデオ

于 2013-05-18T20:42:27.800 に答える
1

.h ファイルでデリゲートを設定しておらず、呼び出すために<UITextFieldDelegate>テキストフィールドのデリゲート プロパティを self に割り当てていないようです。tf.delegate = self;- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

それを試してみて、それがどうなるか教えてください

-幸運を!

于 2013-05-23T21:12:04.407 に答える
1

@koray は正しかった: クラスのデリゲートを設定する必要があります。クラスは、プロトコル UITextFieldDelegate を実装するものとして宣言する必要があります (UITableViewDataSource に加えて、私は仮定します)

次に、makeTextField: (NSString*)text placeholder: (NSString*)placeholder メソッドで、次のようなものが必要です。

-(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 ;
}

次に、デリゲート メソッドを正しくセットアップする必要があります。次の例では、数字パッドに戻るボタンや完了ボタンがないため、ナビゲーション バーがあります。完了ボタンとして機能するボタンをセットアップします (キーボードを操作する別の方法があり、テキスト フィールドを切り替えるといずれにせよ編集の終了がトリガーされます)。

- (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;
}

次に、textDidEndEditing デリゲート メソッドで魔法が起こります。

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if ( textField == phoneFieldTextField ) {
        self.phone = [self formatPhoneNumber:textField.text deleteLastChar:YES] ; // convert
        [phoneFieldTextField setText:self.phone]; // display
    }
    // (...)
}
于 2013-05-24T21:26:15.687 に答える