Я работаю над приложением с вкладками, в котором есть ошибка, из-за которой я остался в тупике (до сих пор).
Когда я перехожу на новую вкладку, данные, хранящиеся в части модели приложения, не используются представлением, которое, таким образом, отображает устаревшую информацию (график, числа и т. Д.). Я пробовал два способа принудительного обновления, которые обрабатываются в представлении [self updateDisplay]
. (1) В делегате приложения используйте метод UITabBarControllerDelegate
, чтобы определить, какая вкладка выбрана, а затем отправьте ему сообщение об обновлении. Вот часть тела метода делегата:
if (viewController == [tabBarController.viewControllers objectAtIndex:1]) {
NSLog(@"graphViewController selected, graphViewController = %@", graphViewController);
[graphViewController updateDisplay];
}
Вот так я бы хотел выполнить эту работу. Однако отображение не обновляется, хотя NSLog подтверждает, что updateDisplay сработал.
(2) Нажмите кнопку в представлении, чтобы обновить отображение, выполнив [self updateDisplay]
. Это работает, но не является удовлетворительным. Теперь самое интересное. В журнале ниже мы читаем: (1) вызывается метод делегата, (2) выбирается graphViewController
и (3) вызывается метод updateDisplay в графическом контроллере. Большой! Но barGraph
на этом этапе является нулевым, и отображение, включая метки, считываемые с плавающих чисел в ourLog
, не обновляется. Объект ourLog
является частью модели и синхронизируется с файлом на «диске». (barGraph
обновляется с ourLog
до updateDisplay
).
Двигаясь дальше, мы находимся в представлении, управляемом GraphViewController, нажимаем кнопку «test» (6), вызывается updateDisplay
, представление обновляется надлежащим образом.
Обратите внимание, что в 1-5, GraphViewController
было в 0x4e346e0, тогда как в 6-9 это было в 0x4b53c80. Если вы переключаетесь назад и вперед, нажимаете и нажимаете кнопку «test», вы всегда получаете шестнадцатеричные числа. Сначала я подумал, что как-то было два случая GraphViewController
, плавающих вокруг. Но я переопределил метод init
этого класса, чтобы зарегистрировать его. Это появляется только один раз. Так что я в полном недоумении.
- Джим
- 1] Вызван метод UITabBarControllerDelegate, self =
- 2] выбран graphViewController, graphViewController =
- 3] GraphViewController, вызывается updateDisplay, self =
- 4] ourLog:
- 5] updateDisplay, barGraph: (ноль)
- 6] тестовое нажатие
- 7] GraphViewController, вызывается updateDisplay, self =
- 8] ourLog:
- 9] updateDisplay, barGraph:>
PS. Я первоначально разместил это на UIVIew объект подкласса становится таинственно нулевым в приложении вкладок . Я публикую это заново, потому что проблема носит более общий характер, поскольку barGraph
является нулевым в различных точках жизненного цикла приложений. Каких-то вещей, которые должны быть доступны, когда я звоню, нет, поэтому я должен придумать другой способ назвать это. Но он не исчезает (я также перебрал dealloc
и не обнаружил, что barGraph
когда-либо был выпущен).
Приложение 1: BarGraph.
Вот как barGraph создается в GraphViewController:
@interface GraphViewController : UIViewController {
BarGraph *barGraph;
}
@property (nonatomic, retain) BarGraph *barGraph;
@property (nonatomic, retain) IBOutlet UIButton *testButton;
- (void) updateDisplay;
- (IBAction) testAction: (id) sender;
@end
In @implementation
, viewDidLoad
alloc-inits barGraph:
- (void) viewDidLoad {
[super viewDidLoad];
NSLog(@"xx:BARGRAPH: alloc-init in viewDidLoad, GraphBar");
barGraph = [[BarGraph alloc] initWithFrame:CGRectMake(15, 140, 289, 130)];
[self.view addSubview:barGraph];
[self updateDisplay];
}
Наконец, вот реализация updateDisplay
:
- (void) updateDisplay {
// Check to see where GraphViewController is:
NSLog(@"GraphViewController, updateDisplay called, self = %@", self);
// Get a pointer to the current data to graph
Log *ourLog = [self theDelegate].currentLog
// Log info
NSLog(@"ourLog: %@", ourLog);
NSLog(@"updateDisplay, barGraph: %@", self.barGraph);
// Get the current data out of ourLOg
self.barGraph.data = ourLog.log;
// And ask barGraph to display it
[barGraph setNeedsDisplay];
}
Приложение 2: viewWillAppear.
Я добавил viewWillAppear
к GraphViewController.m
следующим образом:
- (void) viewWillAppear:(BOOL)animated
{
NSLog(@"xx: GraphViewController, viewWillAppear has fired");
[super viewWillAppear:animated];
[self updateDisplay];
}
Это выглядит как нормальное и лучшее решение, но это viewWillAppear
никогда не срабатывает. Обратите внимание на метод testAction
, который активируется кнопкой:
- (IBAction) testAction: (id) sender {
NSLog(@"test pushed");
[self updateDisplay];
}
Нажатие на кнопку, к которой он подключен, корректно обновляет дисплей. Но, конечно, я хочу, чтобы iOS нажимала кнопку, а не я: -)