Search code examples
iosobjective-cuilabeluipopovercontroller

How to change a UILabel through a UIPopoverController


I have a simple code, where it has been two classes: ViewController (which is the main rootViewController) and ProductsViewController (who is a Controller that opens through a PopoverController).

What is happening is the following, within the ViewController class I have a setter command that is responsible for updating the UILabel:

IBOutlet UILabel *myLabel;
@property(nonatomic,retain)  NSString *saver;

- (void)viewDidLoad{
    [super viewDidLoad];
    myLabel.text = saver;
}
-(void)setLabel:(NSString*)value{
    saver = value;
    myLabel.text = value;
}

In ProductsViewController Class I have the code which is responsible for activating the setter method:

ViewController *detailViewController = [[ViewController alloc] init];
[detailViewController setLabel:@"Changes?"];
[detailViewController release];

I believe the problem is the time when the popover is open, because I believe that somehow the UILabel is inactive, since if we put NSLog(@"Exists -> %@",myLabel); inside the setter method, we get (null)

Could someone help me solve this problem, and how to get around this?

Thanks.

EDIT

I tried to work with protocols that way:

ViewController.h

#import <UIKit/UIKit.h>
#import "ProductsViewController.h"

@interface ViewController : UIViewController <ProductsViewControllerDelegate>{

    IBOutlet UILabel *myLabel;
}

-(IBAction)showPopOver:(id)sender;
- (void)productWasSelected:(NSString *)product;
@end

ViewController.m

- (void)presentProductsViewController:(ProductsViewController *)productsViewController {
    productsViewController.delegate = self;
    //present in popover here...
}

- (void)productWasSelected:(NSString *)product{
    myLabel.text = product;
}

ProductsViewController.h

#import <UIKit/UIKit.h>

@protocol ProductsViewControllerDelegate <NSObject>
- (void)productWasSelected:(NSString *)product;
@end

@interface ProductsViewController : UIViewController
@property (nonatomic, retain) id<ProductsViewControllerDelegate> delegate;
@end

ProductsViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.delegate productWasSelected:@"Selected Product"];
    NSLog(@"Called!");
}

My ShowPopover Method is below:

-(IBAction)showPopOver:(id)sender{

    UIButton *btn =sender;
    ProductsViewController *productsView =[[ProductsViewController alloc] initWithNibName:@"ProductsViewController" bundle:nil];
    popOver =[[UIPopoverController alloc] initWithContentViewController:productsView];
    [popOver presentPopoverFromRect:btn.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];

    [productsView release];

}

Solution

  • Two objects that share the same class DO NOT make them the same object. You probably want to use delegation here. There are plenty of tutorials online. Here's an example...

    @protocol ProductsViewControllerDelegate <NSObject>
    - (void)productWasSelected:(NSString *)product;
    @end
    
    @interface ProductsViewController : UIViewController
    @property (nonatomic, weak) id<ProductsViewControllerDelegate> delegate;
    @end
    
    
    @implementation ProductsViewController
    
    - (void)didSelectProduct {
        [self.delegate productWasSelected:@"Selected Product"];
    }
    
    @end
    

    @interface MainViewController : UIViewController <ProductsViewControllerDelegate>
    @end
    
    
    @implementation MainViewController
    
    - (IBAction)showPopOver:(id)sender{
        UIButton *btn =sender;
        ProductsViewController *productsView =[[ProductsViewController alloc] initWithNibName:@"ProductsViewController" bundle:nil];
        productsView.delegate = self;
        popOver =[[UIPopoverController alloc] initWithContentViewController:productsView];
        [popOver presentPopoverFromRect:btn.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
    }
    
    - (void)productWasSelected:(NSString *)product {
        self.myLabel.text = product;
    }
    
    @end