Я пытаюсь понять делегирование. Я написал небольшой проект, чтобы попытаться решить эту проблему. Мне также помогал С.О. Я застрял на самой последней его части. Мой проект простой. У нас есть контроллер основного вида с кнопкой «Пуск». Эта кнопка запускает представление контейнера, привязанное к ContainerViewController. Я сделал небольшую анимацию, чтобы контейнер скользил сбоку. У меня есть еще одна кнопка «назад», которая заставляет представление контейнера исчезать с противоположной анимацией. Обратите внимание, я копирую много кода и дорабатываю остальное по мере обучения, поэтому могут быть ненужные строки, пожалуйста, не стесняйтесь комментировать.
ViewController.h
#import <UIKit/UIKit.h>
#import "ContainerViewController.h"
@interface ViewController : UIViewController <ContainerViewControllerDelegate>
- (IBAction)Start:(id)sender;
- (IBAction)back:(id)sender;
@end
Вот м файл:
#import "ViewController.h"
@interface ViewController ()
@property UIViewController *childView;
@property NSString *myReceivedValue;
@property ContainerViewController *controller;
@property IBOutlet UILabel *myLabel;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.childView = [self.storyboard instantiateViewControllerWithIdentifier:@"childVC"];
self.controller = [self.storyboard instantiateViewControllerWithIdentifier:@"childVC"];
self.controller.delegate = self;
self.childView = [self.childViewControllers lastObject];
[self.childView.view removeFromSuperview];
[self.childView removeFromParentViewController];
self.childView.view.userInteractionEnabled = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)Start:(id)sender {
self.childView.view.frame = CGRectMake(0, 84, 320, 210);
[self.childView didMoveToParentViewController:self];
CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.childView.view.layer addAnimation:transition forKey:nil];
[self.view addSubview:self.childView.view];
self.childView.view.userInteractionEnabled = YES;
}
- (IBAction)back:(id)sender {
[self.childView willMoveToParentViewController:nil];
[UIView animateWithDuration:1
delay:0.0
usingSpringWithDamping:1
initialSpringVelocity:1
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.childView.view.frame = CGRectMake(-320, 84, 320, 210);
} completion:^(BOOL complete){
[self.childView removeFromParentViewController];
}];
}
- (void) passValue:(NSString *) theValue
{
// here is where you receive the data
}
@end
Итак, у Container View есть pickerView, делегатом которого он является, и у этого pickerView есть только массив из десяти цветов на выбор:
h для представления контейнера:
#import <UIKit/UIKit.h>
@protocol ContainerViewControllerDelegate;
@interface ContainerViewController : UIViewController <UIPickerViewDelegate>
@property NSArray *colors;
@property (weak)id <ContainerViewControllerDelegate> delegate;
@property (weak, nonatomic) IBOutlet UIPickerView *myPickerView;
- (IBAction)chosenCol:(id)sender;
@end
@protocol ContainerViewControllerDelegate <NSObject>
- (void) passValue:(NSString *) theValue;
@end
m для представления контейнера:
#import "ContainerViewController.h"
@interface ContainerViewController ()
@property NSString *selValue;
@end
@implementation ContainerViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.colors = [[NSArray alloc] initWithObjects:@"blue", @"red", @"green", @"purple", @"black", @"white", @"orange", @"yellow", @"pink", @"violet", nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 10;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return self.colors[row];
}
- (IBAction)chosenCol:(id)sender {
[self.delegate passValue:[self.colors objectAtIndex:[self.myPickerView selectedRowInComponent:0]]];
}
@end
Вот изображение того, как это выглядит. Обратите внимание, что кнопка «выбранный» — это всего лишь временная кнопка, которую я поместил туда, чтобы убедиться, что все в порядке, и что я могу отключить выбранный цвет с помощью кнопки в контейнере. Что я хочу сделать, так это передать этот цвет родительскому контроллеру представления. Так что после того, как я закрою контейнер с его представлением выбора, у меня будут сохранены данные о том, какой цвет был выбран. Мне помог кто-то из S.O. и он проделал очень хорошую работу, помогая мне начать это. Единственное, чего я не понял, это то, что происходит, когда я получаю данные в конце файла m родителя:
- (void) passValue:(NSString *) theValue
{
// here is where you receive the data
}
Это явно нубский вопрос, но мне действительно нужно его разъяснить. Как мне на самом деле получить доступ к данным в родительском. Я спросил в разделе комментариев, и ответ был (я меняю класс, изначально он был uicolor):
"Нет, вы получите данные внутри метода - (void) passValue:(NSString *) theValue; поставьте точку останова в этом методе, чтобы убедиться, что он работает, вы можете получить к нему доступ следующим образом: NSString *myReceivedColor = theValue;
Я попытался написать дословно "NSString *myReceivedColor = theValue;" но «значение» не распознано.
В конечном счете, я хочу передать данные обратно родителю, чтобы, когда я нажимаю кнопку «назад», в родительском элементе метка «вы выбрали» обновлялась выбранным цветом».
Я никогда раньше не прикасался к делегированию, поэтому я потерян. Может ли милосердная душа найти время, чтобы объяснить этот последний момент в очень очевидных терминах? огромное спасибо
ОБНОВИТЬ------------------------------------------------- ----------------------
Итак, я смотрю на то, чтобы добавить в конце моего метода для кнопки «назад»
- (IBAction)back:(id)sender {
[self.childView willMoveToParentViewController:nil];
[UIView animateWithDuration:1
delay:0.0
usingSpringWithDamping:1
initialSpringVelocity:1
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.childView.view.frame = CGRectMake(-320, 84, 320, 210);
} completion:^(BOOL complete){
[self.childView removeFromParentViewController];
}];
пару строк:
self.myReceivedValue = theValue;
self.myLabel.text = self.myReceivedValue;
}
Чтобы иметь возможность обновить текст myLabel до цвета, который я выбрал в контейнере представления. Он возвращается с ошибкой: «использование необъявленного идентификатора« theValue ». Это все новое для меня, поэтому я просто копирую то, что люди сказали на SO, в надежде на понимание в конце концов. Что я здесь делаю неправильно? tx
NSString *myReceivedColor = theValue;
, которая дает вам ошибку? - person Phillip Mills   schedule 24.01.2016self.delegate passValue...
вchosenCol
. Посмотрите, каково значение делегата в этот момент. Затем, если все в порядке, войдите в метод делегата и посмотрите на передаваемую переменную. (Я не уверен, почему вы ожидаете, что что-то произойдет вback
.) - person Phillip Mills   schedule 24.01.2016