Проблемы с контроллерами вида, переходящими в фоновый режим UITabBarController
У меня есть UITabBarController с 3 контроллерами вида, подключенными к нему. Все работает нормально, кроме того, когда вы переключаетесь с одного вида на другой, новый вид занимает некоторое время, чтобы перезагрузить то, что он делал. Я знаю, что это не такая уж большая проблема, но это просто делает приложение немного неряшливым. Кто-нибудь знает, как я могу держать приложение запущенным в фоновом режиме, или что-то такое, что не нужно перезагружать каждый раз.
Как вы, возможно, заметили, я очень новичок в Objective-C, поэтому я могу понять если я неясен, но любая помощь действительно ценится!
ПРАВКА: ДЛЯ ДЭВИДА
Это код для секундомера в поле .файл m:
@implementation StopwatchViewController
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
isCounting = false;
}
- (IBAction)startOrStop:(id)sender
{
if (self->isCounting == false) {
self->isCounting = true;
[self startStopwatch];
} else {
self->isCounting = false;
[self stopStopwatch];
}
}
- (void)startStopwatch
{
[startStopButton setTitle:@"STOP" forState:UIControlStateNormal];
[self performSelector:@selector(stopwatch) withObject:self afterDelay:1.0];
}
- (IBAction)resetStopwatch:(id)sender
{
[self reset];
}
- (void)stopwatch
{
if (self->isCounting == false) {
return;
} else {
NSInteger hourInt = [hourLabel.text intValue];
NSInteger minuteInt = [minuteLabel.text intValue];
NSInteger secondInt = [secondLabel.text intValue];
if (secondInt == 59) {
secondInt = 0;
if (minuteInt == 59) {
minuteInt = 0;
if (hourInt == 23) {
hourInt = 0;
} else {
hourInt += 1;
}
} else {
minuteInt += 1;
}
} else {
secondInt += 1;
}
NSString *hourString = [NSString stringWithFormat:@"%02d", hourInt];
NSString *minuteString = [NSString stringWithFormat:@"%02d", minuteInt];
NSString *secondString = [NSString stringWithFormat:@"%02d", secondInt];
hourLabel.text = hourString;
minuteLabel.text = minuteString;
secondLabel.text = secondString;
CGRect hourFrame = self->hourBar.frame;
CGRect minuteFrame = self->minuteBar.frame;
CGRect secondFrame = self->secondBar.frame;
if ((NSInteger)hourFrame.size.height != hourInt) { // check if we need to modify
hourFrame.origin.y -= ((hourInt * 10.0) - hourFrame.size.height);
hourFrame.size.height = (hourInt * 10.0);
self->hourBar.frame = hourFrame;
}
if ((NSInteger)minuteFrame.size.height != minuteInt) { // check if we need to modify
minuteFrame.origin.y -= ((minuteInt * 4.0) - minuteFrame.size.height);
minuteFrame.size.height = (minuteInt * 4.0);
self->minuteBar.frame = minuteFrame;
}
if ((NSInteger)secondFrame.size.height != secondInt) { // check if we need to modify
secondFrame.origin.y -= ((secondInt * 4.0) - secondFrame.size.height);
secondFrame.size.height = (secondInt * 4.0);
self->secondBar.frame = secondFrame;
}
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(stopwatch) userInfo:nil repeats:NO];
}
}
- (void)stopStopwatch
{
[startStopButton setTitle:@"START" forState:UIControlStateNormal];
}
- (void)reset
{
[startStopButton setTitle:@"START" forState:UIControlStateNormal];
self->isCounting = false;
hourLabel.text = @"00";
minuteLabel.text = @"00";
secondLabel.text = @"00";
CGRect hourFrame = self->hourBar.frame;
CGRect minuteFrame = self->minuteBar.frame;
CGRect secondFrame = self->secondBar.frame;
hourFrame.size.height = 0;
minuteFrame.size.height = 0;
secondFrame.size.height = 0;
hourFrame.origin.y = 321.0;
minuteFrame.origin.y = 321.0;
secondFrame.origin.y = 321.0;
self->hourBar.frame = hourFrame;
self->minuteBar.frame = minuteFrame;
self->secondBar.frame = secondFrame;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
ВТОРАЯ ПРАВКА ДЛЯ ДЭВИДА:
Изменил основные части кода, чтобы они выглядели следующим образом:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES];
[self swapFrames];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
[self updateBars];
}
- (void)stopwatch
{
if (self->isCounting == false) {
return;
} else {
hourInt = [hourLabel.text intValue];
minuteInt = [minuteLabel.text intValue];
secondInt = [secondLabel.text intValue];
if (secondInt == 59) {
secondInt = 0;
if (minuteInt == 59) {
minuteInt = 0;
if (hourInt == 23) {
hourInt = 0;
} else {
hourInt += 1;
}
} else {
minuteInt += 1;
}
} else {
secondInt += 1;
}
NSString *hourString = [NSString stringWithFormat:@"%02d", hourInt];
NSString *minuteString = [NSString stringWithFormat:@"%02d", minuteInt];
NSString *secondString = [NSString stringWithFormat:@"%02d", secondInt];
hourLabel.text = hourString;
minuteLabel.text = minuteString;
secondLabel.text = secondString;
[self swapFrames];
[self updateBars];
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(stopwatch) userInfo:nil repeats:NO];
}
}
- (void)updateBars
{
if ((NSInteger)hourFrame.size.height != hourInt) { // check if we need to modify
hourFrame.origin.y -= ((hourInt * 10.0) - hourFrame.size.height);
hourFrame.size.height = (hourInt * 10.0);
self->hourBar.frame = hourFrame;
}
if ((NSInteger)minuteFrame.size.height != minuteInt) { // check if we need to modify
minuteFrame.origin.y -= ((minuteInt * 4.0) - minuteFrame.size.height);
minuteFrame.size.height = (minuteInt * 4.0);
self->minuteBar.frame = minuteFrame;
}
if ((NSInteger)secondFrame.size.height != (secondInt * 4.0)) { // check if we need to modify
secondFrame.origin.y -= ((secondInt * 4.0) - secondFrame.size.height);
secondFrame.size.height = (secondInt * 4.0);
self->secondBar.frame = secondFrame;
}
}
- (void)swapFrames
{
hourFrame = self->hourBar.frame;
minuteFrame = self->minuteBar.frame;
secondFrame = self->secondBar.frame;
}
Я разделил код так, что непосредственно перед появлением вида он должен обновить бары. Однако это не сработало. Я провел небольшое исследование, распечатав значения некоторых переменных в определенных точках. Оказывается, что в viewWillAppear, secondBar.рамка (и минутная клавиша и т.д.) обновился до нужной высоты. Однако в viewDidAppear это значение сбрасывается до 0. Такого не бывает, чтобы secondInt, или secondFrame. Где-то между этими двумя методами кадр сбрасывается, но я не могу понять, что это такое.
1 ответ:
Насколько я понимаю, рамки для ваших свойств
self.hourBar
,self.minuteBar
иself.secondBar
устанавливаются в 0 при переключении между вкладками, и только обновлять их каждую секунду.Если это действительно так, просто установите их правильные значения в методе viewControllers
viewWillAppear:
(назначьте их некоторому свойству вviewWillDisappear:
).Как сайднот, вы, кажется, исходите из C++. Нотация " - > "очень необычна для Objective-C, так как свойства доступны с помощью".", и соответствующие им переменная экземпляра с " ->". Использование нотации со стрелкой Не вызовет автосинтезированные методы геттера / сеттера свойств!
Кроме того, есть ли конкретная причина, по которой вы всегда создаете новые объектыNSTimer
вместо установкиrepeats:
в yes? Создание таймера и добавление его в runloop (чтоscheduledTimerWith:...
и делает) является относительно дорогостоящей операцией.