简体   繁体   中英

Setting UILabel text is not working

Here is my .h file

#import <UIKit/UIKit.h>

@interface PersonViewController : UIViewController

@property(strong,nonatomic) NSString *personTitle;

And here is my .m file

@interface PersonViewController ()

@property (weak, nonatomic) IBOutlet UILabel *titleView;

@end

@implementation PersonViewController
//stuff …

-(void)setPersonTitle:(NSString *)personTitle
{
    [self.titleView setText:personTitle];// also self.titleView.text=personTitle
    [self.titleView setNeedsDisplay];
    NSLog(@"The title shoud match as %@ :: %@",personTitle,self.titleView.text);
}

-(NSString *)personTitle
{
    return self.titleView.text;
}

//… more stuff

@end

The logging shows that the value is (null) for self.titleView.text whereas personTitle prints the appropriate value.

I remember doing this same thing a number of times and it worked. Any ideas why it's failing this time?

update I use storyboard to set my scenes. And I am using xcode-5 and iOS-7

update: how I call

The user clicks a button, leading to a push segue

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"enter prepare for segue.");
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];

 if ([segue.identifier isEqualToString:the_identifier_for_person]) {
        NSLog(@"segue to person is progressing“);
        if ([segue.destinationViewController isKindOfClass:[PersonViewController class]]) {
            NSLog(@"segue to person destination is a match");

            PersonViewController *aPerson = (PersonViewController *)segue.destinationViewController;
            aPerson.personTitle=((MyItem*)self.allItems[indexPath.row]).title;
            NSLog(@"segue to person is done");

        }
    }
}

This sounds like you forgot to wire up your UILabel in the storyboard. Can you confirm that self.titleView is not null?

View controllers create their views on demand, but can spot that only via a call to view . When the view is loaded, your outlets will be populated.

Either call view to force loading or keep the string in abeyance until you get viewDidLoad .

(aside: prior to iOS 6, views would also be released in low-memory situations so the idiomatic thing is to store the string and populate on viewDidLoad)

Having accepted another answer, I wanted to show the pattern that I actually used to solve the problem, in case someone else comes looking. This pattern is best practice (yes, I forgot it for a long moment there).

#pragma mark - update UI
-(void)setPersonTitle:(NSString *)personTitle
{
    _personTitle=personTitle;
    if (self.view.window) [self updateUI];//only if I am on screen; or defer to viewWillAppear
}
-(void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self updateUI];
}
-(void)updateUI
{
    self.titleView.text=self.personTitle;
}

It is always important to update the ui when the data has changed, which is why I must make the call inside setPersonTitle . But because the IBOutlets are not yet set when I set personTitle in prepareForSegue, then I must also make the call inside viewWillAppear .

Do you actually call the -(void)setPersonTitle:(NSString *)personTitle method?

It seems that you aren't calling it correctly which would result in the title being null.

After reviewing the prepareForSeque it is clear that you are not calling the method. You are actually just changing the @property named personTitle.

In the viewDidLoad you should have it so that self.titleView.text = self.personTitle;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM