Передача данных между контроллерами, просмотренными в режиме быстрого просмотра?
Что он делает
- Когда загружается первая страница в моем контроллере панели вкладок, я извлекаю данные из json файла
- Я храню его в массиве (в первом контроллере представления)
- Полученные данные будут отображаться во втором контроллере. Данные уже загружены и сохранены в массиве в первом контроллере представления.
Проблема:
Я не могу определить способ передачи данных между двумя контроллерами представлений. Не удается передать данные на основе идентификатора segue, так как это контроллер панели вкладок.
Пожалуйста, помогите!
Ответы
Ответ 1
Вы можете сохранить данные в AppDelegate. Доступ к ним из нескольких контроллеров.
Но если вам нужно передать данные между диспетчерами, то:
var secondTab = self.tabBarController?.viewControllers[1] as SecondViewController
secondTab.array = firstArray
Ответ 2
Н. Пример кода Сердара является правильным, чтобы получить доступ к другому контроллеру представления таблиц и предоставить ему данные.
Имейте в виду, что когда вы передаете массив в Swift, вы передаете его по значению, в отличие от Objective-C, который передает его по ссылке. Это означает, что изменения, внесенные вашим вторым контроллером представления, не будут отображаться в вашем первом контроллере представления, потому что ваш второй использует копию массива, а не тот же массив. Если вы хотите, чтобы оба контроллера вида отображали один и тот же массив, поместите массив в класс и передайте один экземпляр этого класса.
Некоторые другие соображения:
Вы можете подклассифицировать TabBarController, чтобы дать ему свойство, которое будет хранить ваши данные, и это будет доступно для всех вкладок, используя:
if let tbc = tabBarController as? YourCustomTabBarSubclass {
println("here my data \(tbc.array)")
}
В этой ситуации вы будете получать доступ к одному и тому же массиву из нескольких вкладок, поэтому изменения на одной вкладке отражаются в другом месте.
Я рекомендую против подхода использования вашего App Delegate в качестве централизованного места для хранения данных. Это не цель делегирования приложения. Его цель - обрабатывать вызовы делегатов для объекта приложения.
Контроллеры просмотра должны иметь все данные, инкапсулированные внутри них, что они должны выполнять свою работу. У них есть связь с их модельными данными (такими как ваш массив или ссылка на базу данных или контекст управляемых объектов), так как у них есть контроллер вида, который обращается к другому объекту путем перемещения графика контроллера представления или перехода в делегат или даже используя глобальную переменную. Эта модульная самостоятельная конструкция контроллеров View позволяет вам перестроить ваше приложение для подобных, но уникальных проектов на разных устройствах, например, представлять контроллер представления в виде на одном устройстве (например, iPad) и представлять его на весь экран на другом, например iPhone.
Ответ 3
В итоге я использовал синглтон, как предложил Вустер в своем ответе выше.
В Swift 3
Создайте новый быстрый файл и создайте класс:
class Items {
static let sharedInstance = Items()
var array = [String]()
}
В любом из ваших контроллеров просмотра вы можете получить доступ к вашему массиву следующим образом:
Items.sharedInstance.array.append("New String")
print(Items.sharedInstance.array)
Ответ 4
SWIFT 3
В вашем первом диспетчере представлений объявите переменную (в вашем случае массив), как обычно.
В вашем втором диспетчере представлений сделайте следующее:
var yourVariable: YourVariableClass {
get {
return (self.tabBarController!.viewControllers![0] as! FirstViewControllerClass).yourVariable
}
set {
(self.tabBarController!.viewControllers![0] as! FirstViewControllerClass).yourVariable = newValue
}
}
Это работает, потому что в tabbarcontroller инициализируются все viewcontrollers за вкладками. Делая это во втором диспетчере представлений, вы фактически получаете/устанавливаете переменную из/в первом диспетчере представлений.
Ответ 5
У меня есть контроллер с вкладками в моем приложении, и я использую тот же массив для нескольких видов вкладок. Я выполняю это, объявляя массив вне любых классов (в строках между импортом UIKit и объявлением класса), так что это, по сути, глобальная переменная, доступ к которой может иметь каждый вид. Вы пробовали это?