Как передать строку из текстового поля (встроенного в ячейку таблицы) во втором контроллере обратно в метку в первом контроллере (также встроенную в ячейку таблицы)?
Изменить 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;
}