Как передать строку из текстового поля (встроенного в ячейку таблицы) во втором контроллере обратно в метку в первом контроллере (также встроенную в ячейку таблицы)?

Изменить 1: я думаю, что я понял проблему, я просто не смог ее решить. В SecondViewController.m, где определено textFieldShouldReturn, "if ([self.delegate RespondsToSelector:@selector(passString:)])" возвращает false, поскольку NSLog не был запущен.

Изменить 2: Проверка NSLogs того, кто является делегатом в обоих ViewControllers, дала хорошее понимание проблемы. В FirstViewController prepareForSegue назначает правильный делегат. После перехода к SecondViewController делегат становится "нулевым".

Это то, чего я пытался достичь в течение недели без успеха. Я понимаю, что мне нужно передать данные обратно в стек двухслойной навигации с помощью делегатов. Однако я не уверен, почему мой код не работает (строка не передается).

Было бы также очень признательно, если бы кто-нибудь мог сказать мне (ссылки и другие ресурсы), как правильно сделать представление формы / представления (2-й контроллер) для ввода данных, которые можно повторно использовать для редактирования меток определенных ячеек в представлении отображения (1-й контроллер)).

Вот мой код:

SecondViewController.h

#import <UIKit/UIKit.h>

@protocol PassStringDelegate
- (void)passString:(NSString *)stringFromTextField;
@end

@interface SecondViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>

@property (strong, nonatomic) IBOutlet UITableView *detailTable;

@property (weak, nonatomic) id <PassStringDelegate> delegate;

@end

SecondViewController.m

#import "SecondViewController.h"
#import "CustomCell.h" // My cell is custom built in IB.

@interface SecondViewController ()

@end

@implementation SecondViewController

@synthesize delegate;

@synthesize stringFromTextField;

- (void)viewDidLoad
{
    ...            
    NSLog(@"%@", self.delegate);                          // Returns "(null)".
}    

...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Data Entry" forIndexPath:indexPath];
    [cell setEditing:YES animated:YES];
    cell.customTextField.clearsOnBeginEditing = NO;
    cell.customTextField.returnKeyType = UIReturnKeyDone;
    cell.customTextField.delegate = self;                 // customTextField is a custom textfield embedded in the custom cell.
    [self textFieldShouldReturn:cell.customTextField];    // This function supposedly will trigger passString:stringFromTextField when the cell is done with editing.

    return cell;
}

...

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    if ([self.delegate respondsToSelector:@selector(passString:)]) {
        [self.delegate passString:textField.text];
        NSLog(@"Sent back: %@", textField.text);          // I checked NSLog, this was never called.
    }
    return YES;
}

FirstViewController.h

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

@interface FirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate, PassStringDelegate>

@property (strong, nonatomic) IBOutlet UITableView *table;

@property (copy, nonatomic) NSArray *myList;

@property (weak, nonatomic) NSString *obtainedString;

@end

FirstViewController.m

#import "FirstViewController.h"
#import "CustomCell.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

@synthesize obtainedString;

...

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self passString:obtainedString];
}

...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Display" forIndexPath:indexPath];
    cell.customLabel.text = obtainedString;             // I want the label to display the text in the text field in the second controller.
    cell.detailCustomLabel.text = self.myList[indexPath.row];

    return cell;
}

...

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"segue"])
     {
        SecondViewController *detailedView = [[SecondViewController alloc] init];
        detailedView.delegate = self;
        NSLog(@"%@", detailedView.delegate);            // Returns "<SecondViewController: 0x10967b590>".
     }
}

...

- (void)passString:(NSString *)stringFromTextField
{
    obtainedString = stringFromTextField;
}

Пожалуйста, проверьте мой путь делегата и звонки, чтобы увидеть, было ли то, что я сделал, близко к уместному. Большое спасибо!

2 ответа

Решение

Попробуй это:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"segue"]) {
        //SecondViewController *detailedView = [[SecondViewController alloc] init];
        //this creates a new object of SecondViewController that has nothing to do
        //with the segue

        //this should fix it:
        SecondViewController *detailedView = [segue destinationViewController];
        detailedView.delegate = self;
    }
}

Вы создавали новый объект SecondViewController и установка делегата на это.
К сожалению, этот объект вообще не использовался, так как segue уже создал объект и выдвигает этот объект вместо того, который вы создали здесь.

Добавьте свойство @property (retain) FirstViewControllor *parentController во второй viewcontrollor и перед тем, как вы нажмете SecondViewControllor

добавлять

secondviewcontrollor.parentController=self;

И в

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    (FirstViewControllor)self.parentController.obtainedString=textField.text;
}
Другие вопросы по тегам