0

I have 2 view controllers. viewController1 has a UILabel called nameLabel which I want to set in a different class, viewController2.

I try calling this code from viewController2.

Content1ViewController *viewController1 = [Content1ViewController new];
    viewController1.nameLabel.text = @"HELLO";

    NSLog(@"%@",viewController1.nameLabel);

However, the viewController1 nameLabel doesn't change when I call the code? Also the NSLog returns "null"?? Can someone tell me why this is happening and also how I can change the nameLabel from a different class? Thanks!

  • You initialize the label in the init method of Content1ViewController? – Nekak Kinich May 20 '15 at 20:42
  • This is my code for Content1ViewController `@interface Content1ViewController () @end @implementation Content1ViewController - (void)viewDidLoad { [super viewDidLoad]; _nameLabel.text = @"nameLabel"; } @end` Is that initialising it? – Cool Kat Studios May 20 '15 at 20:45
  • You're creating another instance of `Content1ViewController` rather than referring to the one that is already instantiated. You must figure out how to identify that other view controller. But, frankly, it is incorrect for one view controller to update a label on another view controller's view, anyway. The second view controller should inform the first view controller of the new data (e.g. via delegate protocol or notification) and the first view controller should updates its views labels itself. – Rob May 20 '15 at 20:46
  • Did you bind the outlet to the UITextLabel correctly? – Entalpi May 20 '15 at 20:48
  • No if you don't have a IBOutlet linked to this variable. – Nekak Kinich May 20 '15 at 20:51
  • See [Passing Data between View Controllers](http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers). – Rob May 20 '15 at 20:52
  • 1
    BTW - It's a really bad idea to be directly updating the view of another view controller. You should simply pass the data to the view controller and let the view controller update whatever is appropriate. It will make your code far less fragile to change. – rmaddy May 20 '15 at 21:10

4 Answers4

2

Controls are not initialized when you manually create the instance. This is done on a later stage of view controller life cycle.

If I'm not mistaken, first event where you will see controls initialized is viewDidLoad

Something you can do is adding a NSString property named (let's say) nameLabelText and do nameLabel.text = nameLabelText; on viewDidLoad

Claudio Redi
  • 67,454
  • 15
  • 130
  • 155
0

You need to take the same instance of viewController which was on the window. If you are pushing viewController2 into navigation controller stack then get instance of viewController1 from navigation stack and then try to set the label.

If you are using present modal then use presentingViewController instance of viewController2 in order to access instance of viewController1 like

viewController1 *controller = [viewController2 presentingViewController];
[controller.nameLabel setText:@"WhatEver"];
deoKasuhal
  • 2,867
  • 20
  • 27
  • I am using a pageviewcontroller, so I am trying to set a UILabel of a view controller before a user swipes to it. – Cool Kat Studios May 20 '15 at 21:10
  • 1
    You can get the instance of viewController1 using your pageviewcontroller, you can use pageviewcontroller.viewControllers to get instance of viewController1. then set the label against that instance. – deoKasuhal May 20 '15 at 21:15
  • that sounds simple, could you please explain ? Because when I am in my pageviewcontroller class, I go `viewController1.nameLabel` but it doesnt recognize the nameLabel reference? – Cool Kat Studios May 20 '15 at 21:18
  • You need to import viewController1 class into pageviewcontroller and make sure that nameLabel is defined as Public. You are not getting reference of nameLabel because either you didn’t imported class viewController1 into pageviewcontroller or nameLabel is defined as private. – deoKasuhal May 20 '15 at 21:35
  • I have tried this `@public UILabel *test;` however it still doesn't come up? – Cool Kat Studios May 20 '15 at 21:46
  • define nameLabel into .h file instead of .m file. When you define any property into .h file that become Public. viewController1 *controller = [pageviewcontroller viewControllers][0] //Assuming instance is on 0 index of array [controller.nameLabel setText:@“Whatever”] – deoKasuhal May 20 '15 at 22:00
0

Where have you set the property for namelabel? Did you use Interface Builder (XIB or Storyboard) or have you done it all in code? If the you did it in InterfaceBuilder than

 [Content1ViewController new]

is the wrong approach. For XIB-Files you should use

initWithNibName:(NSString *)nibName
                     bundle:(NSBundle *)nibBundle

and if your ViewController has been defined in a storyboard you should use

instantiateViewControllerWithIdentifier:(NSString *)identifier

from UIStoryboard.

But as Claudio Redi already said the earliest point where you will be able to access the UILabel will be in viewDidLoad

If everything in code, you should put

[self setNameLabel:[[UILabel alloc] initWithFrame:CGRectMake(50.0f,50.0f,100.0f,100.0f)];

in the init-Method of your ViewController.

MatzeLoCal
  • 392
  • 3
  • 14
  • Thanks, but it doesn't need to be set at the earliest point, my issue is that 1 view controller will detect when the other view controllers labels need to get updated. So how can I set a view controller to automatically update when a BOOL turns true ? – Cool Kat Studios May 20 '15 at 21:38
  • I has nothing to do with when you want to update but more with hat you need to initialise the control first. In the OP you mentioned that _NSLog returns "null"_ I suppose you testing for the nameLabel. If so, then it clearly hints, that the nameLabel is not initialised. In your comment above you said: _So how can I set a view controller to automatically update when a BOOL turns true ?_ So I a few more questions rise: Is that VC visible or at least "alive"? A simple way to achive that would be using Notifications. But again, your problem above in the OP seems to be an uninitialised UILabel – MatzeLoCal May 21 '15 at 06:20
0
//
//  ViewController.m
//  UIPageViewControllerDemo
//
//  Created by YunYi1118 on 15/5/20.
//  Copyright (c) 2015年 Xiaoyi. All rights reserved.
//

#import "ViewController.h"
#import "MoreViewController.h"

@interface ViewController () <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

@property (strong, nonatomic) UIPageViewController *pageController;

@property (strong, nonatomic) NSArray *pageContent;

@end

@implementation ViewController

@synthesize pageContent = _pageContent;
@synthesize pageController = _pageController;

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createContentPages];
    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin] forKey:UIPageViewControllerOptionSpineLocationKey];

    self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];

    _pageController.dataSource = self;
    _pageController.view.frame = self.view.bounds;

    MoreViewController *initialViewController = [self viewControllerAtIndex:0];
    NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
    [self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    [self addChildViewController:_pageController];
    [self.view addSubview:_pageController.view];


}

- (MoreViewController *)viewControllerAtIndex:(NSUInteger)index
{
    if (self.pageContent.count == 0 || index >= self.pageContent.count) {
        return nil;
    }
    MoreViewController *dataViewController = [[MoreViewController alloc] init];
    dataViewController.dataObject = [self.pageContent objectAtIndex:index];
    return dataViewController;
}

- (void)createContentPages
{
    NSMutableArray *pageStrings = [NSMutableArray array];
    for (int i = 1; i < 11; i++) {
        NSString *contentString = [[NSString alloc] initWithFormat:@"Chapter%d, This is the page %d of content displayed using UIPageViewController ",i,i];
        [pageStrings addObject:contentString];
    }
    self.pageContent = [NSArray arrayWithArray:pageStrings];
}

#pragma mark - delegate

- (NSUInteger)indexOfViewController:(MoreViewController *)viewController
{
    return [self.pageContent indexOfObject:viewController.dataObject];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(MoreViewController *)viewController];
    if (index == 0 || index == NSNotFound) {
        return nil;
    }
    index--;
    return [self viewControllerAtIndex:index];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(MoreViewController *)viewController];
    if (index == NSNotFound) {
        return nil;
    }
    index++;
    if (index == self.pageContent.count) {
        return nil;
    }
    return [self viewControllerAtIndex:index];
}

@end
Andy Darwin
  • 478
  • 5
  • 19