Extremesarova
@Extremesarova
Биоинформатика, машинное обучение, анализ данных.

Как изменить label при нажатии на кнопку в другом контроллере?

07ea44cc54514c70a30147a6bba5ef1f.png

Суть в том, что я хочу при нажатии на кнопку "Добавить" на крайнем правом контроллере изменить label на другом контроллере.
Правый контроллер - WBCAddWaterViewController.h (.m)
Левый контроллер - WBCViewController.h (.m)

Как мне это сделать?
  • Вопрос задан
  • 5215 просмотров
Решения вопроса 1
morozovdenis
@morozovdenis
в WBCViewController подпишитесь на событие:
-(void)viewDidLoad
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(needChangeLabel:) name:@"WBCAddWaterViewControllerChangeLabelNotification" object:nil];
}

- (void)needChangeLabel:(NSNotification *)n
{
    NSLog(@"%@", n.userInfo);
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"WBCAddWaterViewControllerChangeLabelNotification" object:nil];
}


в WBCAddWaterViewController отправляй событие:
NSDictionary *userInfo = @{@"key1" : @"value1", @"key2" : @"value2"};
[[NSNotificationCenter defaultCenter] postNotificationName:@"WBCAddWaterViewControllerChangeLabelNotification" object:nil userInfo:userInfo];
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Лучше отказаться от варианта с нотификациями, это из пушки по воробьям. Потом будет половина приложения нотификации ловить из одной вьюхи в другую.

Имхо, здесь логичнее использовать паттерн делегирования.
Контроллер с кнопкой "добавить"

@protocol AddControllerDelegate <NSObject>
// здесь передаете то, что было добавлено. если ничего не надо передавать, то без второго параметра
@required
- (void)addController:(AddController *)controller addedObject:(id)object;
@end

@interface AddController : UIViewController
@property (nonatomic, weak) id<AddControllerDelegate> delegate;
@end


Контроллер с label должен реализовать протокол и при переходе на второй контроллер
выставить себя делегатом для второго

// .h
@interface LabelController : UIViewController
@end

// .m

@interface LabelController() <AddControllerDelegate>
@property (nonatomic, weak) IBOutlet UILabel *label;
@end


@implementation LabelController
- (void)prepareForSegue:(UIStoryboardSegue *)segue
{
    if ([segue.identifier isEqualToString:@"your-segue-identifier"]) {
        AddController *addController = segue.destinationController;
        addController.delegate = self;
    }
}

#pragma mark - AddControllerDelegate

- (void)addController:(AddController *)controller addedObject:(id)object
{
    // здесь достаете новый текст label из пришедших данных
    NSString *labelText = [object labelText];

    self.label.text = labelText;
}

@end
Ответ написан
@Extremesarova, я не собирался сделать всю работу за вас, я дал вам концепцию, которую нужно было применить.

// WBCAddWaterViewController.h

@class WBCAddWaterViewController;

@protocol WBCAddWaterViewControllerDelegate <NSObject>
// здесь вместо WBCWater подставьте имя класса, который отображает вашу модель.
// ну или если я не угадал - второй параметр должен быть такого типа и так называться, чтобы показывать, что передается. Передаете просто строку - значит addedName:(NSString *)name. Никаких id, никакого кастования - максимум конкретики.
@required
- (void)addWaterController:(WBCAddWaterViewController *)controller addedWater:(WBCWater *)water;
@end

@interface WBCAddWaterViewController : UIViewController
@property (nonatomic, weak) id<WBCAddWaterViewControllerDelegate> delegate;
@end

// WBCAddWaterViewController.m

@implementation WBCAddWaterViewController

// обработка нажатия на кнопку "Добавить"
- (IBAction)addButtonTap:(id)sender
{
	WBCWater *water = ...;
	[self.delegate addWaterController:self addedWater:water];
	// не делайте здесь popViewController!
}

@end


// .h
@interface WBCViewController : UIViewController
@end

// .m

@interface WBCViewController() <WBCAddWaterViewControllerDelegate>
@property (nonatomic, weak) IBOutlet UILabel *label;
@end


@implementation WBCViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue
{
	// это segue, протянутая из WBCViewController в WBCAddWaterViewController
	// ей надо задать идентификатор и записать сюда
    if ([segue.identifier isEqualToString:@"your-segue-identifier"]) {
        WBCAddWaterViewController *addController = segue.destinationController;
        addController.delegate = self;
    }
}

#pragma mark - WBCAddWaterViewControllerDelegate

- (void)addWaterController:(WBCAddWaterViewController *)controller addedWater:(WBCWater *)water
{
    // я написал [water name] наугад, и вообще я сам WBCWater пытался угадать
    // здесь уже пора самому разобраться что и откуда
    NSString *labelText = [water name];

    self.label.text = labelText;

    // делегат должен бы сам управлять скрытием контроллера.
    // здесь очень здорово бы использовать unwindind segues, но сложно объяснить
    [self.navigationController popViewControllerAnimated:YES];
}

@end


Повторяю, бездумно скопипастить не получится.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы