Сохранение состояния сцены приложения iOS

Это может быть невозможно, но я пытаюсь сохранить состояние моего приложения между переходами сцены, но я не могу понять, что делать. В настоящее время мне нравится, когда при запуске приложения и нажатии кнопки "домой" вы можете вернуться к этому приложению только там, где вы остановились, но если вы переходите между сценами (в раскадровке), как только вы вернетесь к этой сцене состояние приложения не было сохранено.

У меня есть только две разные сцены, которые нужно сохранить (вы переходите назад и вперед от одного к другому). Как я могу сэкономить состояние сцен раскадровки, не занимая точную память?

Подробнее: Вот моя вся раскадровка. Вы переключаетесь между сценами с помощью кнопки панели инструментов плюс. На второй сцене пользователь может нажать на ячейки представления таблицы, и реальное изображение заполнит изображение (см. Рисунок 1.2).

Figure 1.1 Рисунок 1.1

На рисунке 1.2 вы видите, что происходит, когда вы нажимаете внутри одной из многих ячеек таблицы (открывается изображение).

Figure 1.2 Рисунок 1.2

ПРОБЛЕМА: При нажатии на ячейку просмотра таблицы, которая заполняет изображение (см. рисунок 1.2), он отлично работает, если вы остаетесь на этой сцене или даже нажали кнопку iPhone home (если вы нажали кнопку iPhone home, а затем снова открыли приложение, состояние сцены было сохранено, и изображение, заполненное простым изображением, по-прежнему отображается так же, как мы его оставили), но если я перейду (используя кнопку плюс) обратно в первую сцену, а затем используйте кнопку "плюс" на первой сцене, чтобы вернуться ко второй сцене, изображение, которое я создал (показано на рисунке 1.2), исчезает, а вторая сцена загружается без сохранения просматриваемых состояний и изображений.

EDIT: Я попытался использовать один и тот же контроллер представления для обеих сцен, но это не решило проблему.

UPDATE: Я только что нашел следующий код (который, я думаю, сохраняет состояние просмотров). Как я могу использовать это, и это то, что я искал?

MyViewController *myViewController=[MyViewController alloc] initWithNibName:@"myView" bundle:nil];
[[self navigationController] pushViewController:myViewController animated:YES];
[myViewController release];

Ответ 1

Я бы предложил сочетание двух вещей: 1. Возьмите DBD и убедитесь, что вы не постоянно создаете новые виды 2. Создайте общий класс, который является контроллером данных (для игроков в гольф, чтобы данные не зависели от сцены)

Правильный способ сделать segues состоял бы в том, чтобы один из ведущих контроллеров слева находился справа от него. Однако, чтобы отклонить тот, который находится справа, вы можете использовать

-(IBAction)buttonPushed:(id)sender 
      [self dismissModalViewControllerAnimated:YES];
}

Это приведет к возврату контроллера просмотра слева, при этом контроллер просмотра слева находится в исходном состоянии. Теперь проблема заключается в том, как сохранить данные справа.

Для этого вы можете создать одноэлементный класс. В классах Singleton есть только один экземпляр, поэтому независимо от того, сколько раз вы направляетесь в контроллер просмотра справа, данные всегда будут одинаковыми.

Реализация Singleton класса (из класса DataManager) - Заголовок

@interface DataManager : NSObject {
}

+(id)initializeData;
-(id)init;
@end

Реализация Singleton класса (из класса DataManager) - Main

static DataManager *sharedDataManager = nil;

@implementation DataManager
+(id)initializeData {
    @synchronized(self) {
        if (sharedDataManager == nil)
            sharedDataManager = [[self alloc] init];
    }
    return sharedDataManager;
}

-(id)init { 
    if(self == [super init]) {
    } 
    return self;
}
@end

Затем внутри кода контроллера вида вы можете захватить этот экземпляр следующим образом

DataManager *sharedDataManager = [DataManager initializeDataManager];

Таким образом, у вас будут одинаковые данные независимо от того, сколько раз вы переключаете представления. Кроме того, вы можете лучше придерживаться программирования MVC, сохраняя данные и контроллеры просмотра отдельно. (http://en.wikipedia.org/wiki/Model-view-controller)

Ответ 2

Рисунок 1.1 имеет фундаментальный недостаток, который я считаю основой вашей проблемы.

Segues (стрелки между контроллерами на раскадровке) создают новые версии UIViewControllers. У вас круговые переходы. Поэтому, когда вы возвращаетесь к исходному экрану через segue, вы действительно продвигаетесь вперед, создавая новую версию.

Это может создать серьезную проблему для использования памяти, но это также означает, что вы не можете поддерживать состояние, потому что каждый вновь созданный элемент является пустым списком.

Поскольку вы используете UINavigationController и pushViewController:animated:, вы должны "поп" вашего контроллера, чтобы избавиться от него.

На вашей "второй" сцене снимите выделение с кнопки + и создайте IBAction в событии touchUpInside. В коде IBAction добавьте "pop"

- (IBAction)plusButtonTapped {
    [self.navigationController popViewControllerAnimated:YES];
}

Ответ 3

Я понимаю, что вы имеете в виду. Это должно происходить с каждым приложением, так как когда последний контроллер представления в стеке навигации переходит от него, он освобождается и освобождается. Если вам нужно сохранить такие значения, как текстовые или позиционные позиции, может возникнуть вопрос о том, как можно использовать plist. См. этот связанный вопрос о том, как использовать plist.

Ответ 4

Apple не собирается делать это за вас. Вероятно, вы должны просто сохранить состояние каждого вида, используя NSUserDefaults, и каждый раз, когда ваше приложение запускает повторную загрузку сохраненных данных.

Если вы сохраняете все в CoreData, вам нужно будет сохранить только активный вид и несколько идентификаторов объектов, если вам не нужно сохранять какие-либо данные, которые у вас есть.

Не ожидайте, что iOS сохранит все, что у вас есть в памяти между запусками. Просто сохраните его в NSUserDefaults и загрузите его каждый раз.

Ответ 5

Сохраняйте состояние сцены в NSUserDefaults или внутри файла plist, а затем при загрузке сцены просто загрузите его с помощью настроек. Если изображения загружаются из Интернета, вы также можете сохранить их локально на своем жестком диске iphones, чтобы он работал немного более плавным.

Ответ 6

Я не думаю, что вам нужно циклически переключаться, просто используйте тот, который подключает viewcontroller 1 из viewcontroller 2, должно быть достаточно, и таким образом вы убедитесь, что дополнительные контроллеры просмотра не созданы (проблемы с памятью могут быть?)

Однако для вашей конкретной проблемы я считаю, что вы должны использовать основные данные для сохранения точного состояния вашей таблицы, потому что ios не сохраняет точное состояние просмотра в любое время. это потребует работы, но вы достигнете того, чего хотите. Вам нужно будет сохранить точную фотографию (используя код или перечисления, которые будут сохранены), местоположение в виде таблицы, счет или нужные данные, необходимые для сохранения этого состояния.

Лучше всего, что coredata настолько эффективна, что перезагружает данные, когда приложение обновляется или на передний план не требуется времени, и ive использует основные данные для загрузки более 5 тыс. записей до сих пор и работает нормально, а не замедляется вообще.

Когда я вернусь домой, предоставьте код, который вы можете использовать, чтобы понять, что я имею в виду.

Ответ 7

Ключ здесь:

  • Имейте какое-то хранилище для данных, которые необходимы вашему приложению. Это ваша модель данных приложения.

  • Предоставьте каждому контроллеру представления доступ к модели или, по крайней мере, к той части модели, которая должна выполнять свою работу. Контроллер вида может затем использовать данные из модели для настройки себя при ее создании или когда появится представление.

  • Попросите каждого контроллера представления обновить модель в соответствующее время, например, когда вид исчезнет или даже каждый раз, когда пользователь вносит изменения.

Существует множество способов организации ваших данных в памяти, и есть много способов сохранить их на диске (то есть в долгосрочном хранилище). Списки свойств, основные данные, простые старые файлы данных и архивы с ключами - все возможности для записи данных в файл. NSArray, NSDictionary, NSSet и т.д. - все классы, которые вы можете использовать, чтобы помочь вам организовать ваши данные в памяти. Тем не менее, ничто из этого не имеет никакого отношения к тому, чтобы ваши контроллеры представления чувствовали себя стойкими. Вы будете использовать их, конечно, но тот, который вы выберете, действительно не имеет значения, поскольку обновление ваших контроллеров просмотров идет. Еще важнее то, что у вас есть какая-то модель и что у ваших контроллеров просмотров есть доступ к ней.

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

Что-то еще, что может помочь, заключается в том, что вам не нужно удалять ваш контроллер просмотра, когда они удаляются из стека навигации. Вы можете настроить оба диспетчера представлений в своем делетете, если хотите, чтобы они держались. Затем вы можете использовать те, что у вас есть, а не создавать новые все время, и при этом вы автоматически получите некоторую степень настойчивости.