8

Я разрабатываю приложение iOS, и теперь я в недоумении. Я пытаюсь передать данные с первого View Controller на первую вкладку TabBarViewController (используя раскадровку). Я нашел много учебников, которые объясняют, как передавать данные между контроллерами представлений, но ничего не работало с моей панелью вкладок. Я знаю, что контроллер панели вкладок содержит своего рода массив представлений. Связь между контроллером просмотра и контроллером панели вкладок реализуется с помощью segue (push). Итак, я подумал, что легко использовать метод prepareForSegue(). Как что:Передача данных с контроллера вида на контроллер панели вкладок в iOS

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 
if ([[segue identifier] isEqualToString:@"tab"]) { 

// ... 

    } 
} 

К сожалению, соотношение между Адвокатской контроллером Tab и каждый вид панели вкладок нет реального Segue. Это всего лишь «отношения». Это означает, что нет идентификатора segue, который я могу использовать для вышеупомянутого метода. Есть ли возможность использовать prepareForSegue в этом случае? Если нет, есть идеи, как решить эту проблему? Я знаю, что есть аналогичный вопрос, но ответ был не так полезен. Должен ли я создавать новый файл для каждой вкладки (просмотра) в контроллере панели вкладок? Или возможно иметь один класс (m. & h.) Для всего контроллера панели вкладок, получая доступ к нескольким представлениям с помощью objectAtIndex()?

Заранее благодарен!

ответ

8

Вот моя установка, которая работала:

  1. Настройка Segue:
    1. Setup View Controller с Segue на панели вкладок контроллер с 2 детьми Просмотр контроллеров в раскадровке
    2. Укажите идентификатор SEGUE (tab)
  2. Установки в раскадровке:
      класса
    1. View Controller = ViewController класса
    2. Tab Bar Controller = TabBarController класса
    3. Tab Bar Controller Child View Controller = TabsViewController (общего между обеими)
  3. Setup labelString свойством в панели вкладок контроллера:

    1. В TabBarController.h:

      @property (nonatomic, strong) NSString *labelString; 
      
    2. В TabBarController.m:

      @synthesize labelString; 
      
  4. prepareForSegue Настройка метода в ViewController.m:

    #import "TabBarController.h" 
    
    ... 
    
    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 
        if ([[segue identifier] isEqualToString:@"tab"]){ 
         TabBarController *tabBar = [segue destinationViewController]; 
         [tabBar setLabelString:[NSString stringWithFormat:@"This has been set"]]; 
        } 
    } 
    
  5. Настройка UILabel s для Tab Bar Детского Посмотреть контроллеры.

    1. Drag по умолчанию UILabel управления в оба ребенка View Controllers
    2. Создать недвижимость в TabsViewController.h:

      @property (nonatomic, strong) IBOutlet UILabel *label; 
      
    3. Крюк 5.1 и 5.2 в раскадровке

  6. Настройка ViewDidLoad метод TabsViewController.m:

    #import "TabBarController.h" 
    
    ... 
    
    @synthesize label; 
    
    ... 
    
    - (void)viewDidLoad 
    { 
        [super viewDidLoad]; 
    
        TabBarController *tabBar = (TabBarController *)self.tabBarController; 
        label.text = [NSString stringWithFormat:@"Tab %i: %@",[tabBar.viewControllers indexOfObject:self],tabBar.labelString]; 
    } 
    

Щелкнув на 1-й и 2-й вкладки будут иметь метки отображения Tab 0: This has been set и Tab 1: This has been set соответственно.

+0

Кажется, это логика. Я пытался это понять, но я получаю исключение. В этот момент я не знаю, почему .. – Keks

+0

Я сбивал с толку все имена классов панели вкладок в своем ответе, поэтому я, возможно, переключил некоторые из них в моем исходном сообщении. Недавно отредактирован для более логичного отображения. Подтверждено работать на моем конце. – Yazid

+0

Я думаю, что существует проблема с 'setLabelString', потому что: 2013-07-19 15: 20: 54.412 iCRS Master [1364: 11303] - [UITabBarController setLabelString:]: непризнанный селектор отправлен в экземпляр 0x7550810 2013-07-19 15: 20: 54.414 iCRS Master [1364: 11303] *** Завершение приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина: '- [UITabBarController setLabelString:]: нераспознанный селектор, отправленный в экземпляр 0x7550810'. – Keks

0

Первое:

1 Вы хотите передать данные на вкладке по какой-то причине ...

или:

2- Вы хотите передать данные на вкладку так то вы можете перейти к другому UIViewController?

Если это второй вариант, наиболее распространенным шаблоном для него является Singleton. Там, где вы можете хранить общие данные, которые могут использоваться/повторно использоваться различными частями приложения.

+0

Я хочу передать данные, потому что: у меня есть NSDictionary в моем ViewController. Теперь мне нужны элементы этого словаря в контроллере панели вкладок, чтобы визуализировать определенные значения. – Keks

8

Если ваша иерархия Viewcontroller-> UItabbarcontroller-> ViewController

в моем случае я должен отправить данные в marketviewcontroller. В tabcontroller, marketviewcontroller присутствует в индексе 0.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
    { 
if ([[segue identifier] isEqualToString:@"tab"]) 
    { 
    UITabBarController *tabar=segue.destinationViewController; 
    MarketViewController *marketViewcontroller=[tabar.viewControllers objectAtIndex:0]; 

    // pass data to market view controller 
    [marketViewcontroller passobject:Yourdata]; 
// or 
    marketViewcontroller.value=Yourdata 
    } 
    } 

in MarketViewController.h 
@property(nonatomic,retain) NSString * value; 
+0

Да, иерархия такая. Используете ли вы один класс для всего контроллера панели вкладок? Или «MarketViewController» - первый вид вашей панели вкладок? – Keks

+0

yes MarketViewController - это первый вид панели вкладок – Kalpesh

+0

Хорошо, я создал его так, как я полагаю. Но что с этим «passobject»? Я получил следующую ошибку: Нет видимого @interface для «TabOneViewController» объявляет селектор «passpbject». Вы знаете мою ошибку? – Keks

1

Как вы показываете вашу TabBarViewController от вашего UIViewController?

Я угадываю с помощью segue. Если это так, вы можете передавать данные в этот UITabBarController, который является «родительским» для всех контроллеров внутри вкладок.

Скажите, что вы хотите передать строку в UITabBarController, вы бы определили свойство в этом контроллере и установили его перед segue.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
    { 
     if ([[segue identifier] isEqualToString:@"tab"]) 
     { 
      UITabBarController *tabBarVC=segue.destinationViewController; 
      tabBarVC.stringToSet = @"hi"; 
     } 
    } 

Затем, с помощью метода делегата, то есть выбранный контроллер представления, так что вы можете передать родительское свойство для детей:

- (void)tabBarController:(UITabBarController *)theTabBarController didSelectViewController:(UIViewController *)viewController { 
    viewController.stringToSet = self.stringToSet // self is UITabBarController 
} 
+0

Спасибо за вашу идею. Да, я использую segue. У меня есть кнопка в первом контроллере просмотра, которая подключена к контроллеру панели вкладок. И вышеперечисленный метод делегата используется для «отправки» строки каждому ребенку? – Keks

+0

Хорошо, я использую prepareForSegue в ViewController. Затем я создаю свойство в контроллере панели вкладок, верно? Где именно вы называете метод делегата? И не могли бы вы рассказать мне, как я могу получить доступ к переданным данным, используя его в панели вкладок? – Keks

+0

Извините, что ответили поздно, возможно, вы уже исправили это. Делегат - очень распространенная модель развития какао. Вы устанавливаете делегата вашего UITabBarController, а затем его методы-делегаты должны автоматически вызываться. Дополнительная информация здесь: http://developer.apple.com/library/ios/#documentation/general/conceptual/DevPedia-CocoaCore/Delegation.html – ade

1

Посмотрите на одиночек. Внутри вкладки вы создаете экземпляр класса-помощника, который реализует шаблон singleton, гарантируя, что на самом деле существует только один экземпляр. Это означает, что когда вторая вкладка создает экземпляр того же класса-помощника, у него будет доступ к тому же объекту, который вы можете использовать для обмена данными ...

например.: http://www.galloway.me.uk/tutorials/singleton-classes/

+0

Проблема состояла в том, чтобы передать данные с другого контроллера представления на вкладку вкладки бар. Я думаю, что ваш ответ полезен, если вы пытаетесь передать данные между различными вкладками панели вкладок, не так ли? – Keks

+0

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

+0

Действительно хороший момент, @Martin Mandl.Вы вдохновили меня, использование синглетов намного лучше для «масштабируемого сценария». Спасибо! –

0

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

Пример кода здесь:

Сначала нужно создать пользовательский класс, например

AppUtility.h

+(void)setXxxName:(NSString *)str; 
+(NSString *)getXxxName; 

AppUtility.m

static NSString *xxxname; 

+(void)setXxxName:(NSString *)str{ 

    xxxname=str; 
} 

+(NSString *)getXxxName{ 

    return xxxname; 
} 

FirstController.m

импорт пользовательский класс в контроллере

#import "AppUtility.h" 

установить значение из первого контроллера для пользовательского класса, используйте следующий код для установки значения:

[AppUtility setXxxName:@"xyz"]; 

Второй контроллер.m

импортировать пользовательский класс в contr Oller

#import "AppUtility.h" 

здесь получить значение из пользовательского класса, используйте следующий код, чтобы получить значение:

NSString *str = [AppUtility getXxxName]; 

В appUtility класс Используйте NSLog заявления для проверки значения является правильным или нет