user3613119
user3613119

Reputation: 91

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];

}

Upvotes: 1

Views: 387

Answers (2)

Duncan C
Duncan C

Reputation: 131408

You are totally lost and confused. Your code creates a new instance of a view controller, invokes a setter method on that new view controller, and then releases the view controller.

This is like having a notebook that you keep in your pocket to keep notes.

You go to the store, buy a new notebook (alloc/init), write a note in that new notebook, throw the notebook away (release), and then wonder why the note you wrote isn't in the notebook in your pocket.

Other things:

Don't use a method named setSomething unless it is a property setter. That is the naming convention for the setter for a property called "something", and that naming convention is enforced by the language.

You declared a method setlabel, but the code is calling a method setLabel. Different capitalization = different methods in C and C-like languages like Objective C.

When your "setLabel" method is called, the label may not exist yet.

I suggest that you create a string property, labelString.

Set that property in your ProductsViewController instance once you sort out how to get a pointer to the ProductsViewController that you are going to display. Then in your ProductsViewController's viewWillAppear method, copy the value of labelString to the label.

Post the code that sets up and displays the ProductsViewController and we can help show you how to set properties on that actual view controller instead of one that you create and then immediately throw away.

Upvotes: 2

CrimsonChris
CrimsonChris

Reputation: 4641

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

Upvotes: 2

Related Questions