无法从子类更新UI

时间:2013-12-30 19:44:35

标签: ios objective-c uiviewcontroller polymorphism

我有一个子类UIViewController。我有24张扑克牌,开始全脸朝下。当我点击每张卡片时,他们需要“翻转”,这实际上意味着我正在将他们的背景图像从黑色变为白色。但是,当我点击卡片时,我无法在UI中更改背景图像。是的,我肯定知道(因为我已经在另一个类中完成了)图像存在且名称正确。

我可以从NSLog调用中看到我的代码正在执行,但我对为什么我的UI不会更新感到困惑。谁能看到我做错了什么?


超级

CardGameViewController.h

#import <UIKit/UIKit.h>
#import "Deck.h"
#import "CardMatchingGame.h"

@interface CardGameViewController : UIViewController

// protected (for subclassing)
- (Deck *) createDeck; // abstract

- (void) updateUI;
- (NSString *) titleForCard:(Card *) card;
- (UIImage *) backgroundImageForCard:(Card *) card;
- (NSMutableArray *) cardsSelected;
- (void) setCardsSelected:(NSMutableArray *)cardsSelected;
- (UILabel *) recentCardLabel;
- (void) setRecentCardLabel:(UILabel *)label;
- (NSInteger) gain;
- (UILabel *) matchAttemptLabel;
- (CardMatchingGame *) game;

@end

CardGameViewController.m

#import "CardGameViewController.h"

@interface CardGameViewController ()
@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
@property (strong, nonatomic) CardMatchingGame *game;
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
@property (strong, nonatomic) NSMutableArray *cardsSelected;
@property (weak, nonatomic) IBOutlet UILabel *recentCardLabel;
@property (weak, nonatomic) IBOutlet UILabel *matchAttemptLabel;
@property (nonatomic) NSInteger gain;
@end

@implementation CardGameViewController

- (CardMatchingGame *) game
{
    if (!_game) {
        _game = [[CardMatchingGame alloc]
                 initWithCardCount:[self.cardButtons count]
                         usingDeck:[self createDeck]];
    }

    return _game;
}

- (Deck *) createDeck  // abstract
{
    return nil;
}

- (IBAction)touchCardButton:(UIButton *)sender
{
    self.gain = -self.game.score; // capture previous score

    NSUInteger chosenButtonIndex = [self.cardButtons indexOfObject:sender];

    [self.game chooseCardAtIndex:chosenButtonIndex]; // note that this will update the game score

    self.gain += self.game.score; // increment gain by updated score
    self.gain += [self.game getGuessPenalty]; // add back the penalty for guessing

    [self updateUI];
}

- (void) updateUI
{
    int i=1;
    for (UIButton *cardButton in self.cardButtons) {
        NSLog(@"%d", i++);
        NSUInteger cardButtonIndex = [self.cardButtons indexOfObject:cardButton];
        Card *card = [self.game cardAtIndex:cardButtonIndex];
        [cardButton setTitle:[self titleForCard:card] forState:UIControlStateNormal];
        [cardButton setBackgroundImage:[self backgroundImageForCard:card] forState:UIControlStateNormal];
        cardButton.enabled = !card.isMatched;
    }

    self.scoreLabel.text = [NSString stringWithFormat:@"Score: %d", self.game.score];    
}

- (NSString *) titleForCard:(Card *)card {
    return card.isChosen ? card.contents : @"";
}

- (UIImage *) backgroundImageForCard:(Card *) card {
    return [UIImage imageNamed:card.isChosen ? @"cardfront" : @"cardback"];
}

@end

子类

SetGameViewController.h

#import "CardGameViewController.h"

@interface SetGameViewController : CardGameViewController

@end

SetGameViewController.m

#import "SetGameViewController.h"
#import "SetCardDeck.h"

@interface SetGameViewController ()
@end

@implementation SetGameViewController

- (void) viewDidLoad
{
    [super viewDidLoad];
    [self updateUI];
}

- (Deck *) createDeck
{
    return [[SetCardDeck alloc] init];
}

- (void) updateUI
{
    [super updateUI];

    self.recentCardLabel.text = [NSString stringWithFormat:@"Recent Cards:"];
}

- (NSString *)titleForCard:(Card *)card
{

    NSString *string;

    string = @"A";

    return string;

}

- (UIImage *) backgroundImageForCard:(Card *)card
{
    UIImage *image = [UIImage imageNamed:@"cardback"];
    if (!image) NSLog(@"no such image");
    else NSLog(@"image found");
    return image;
}
@end

我的两个NSLog命令的输出如下:

1
image found
2
image found
...
24
image found

所以我知道我的代码正在以正确的顺序执行,子类层次结构是正确的等等。我甚至可以在我的UI上获取标签文本以进行更新。但我无法让这些卡片(UIButtons)上的背景图像发生变化。我做错了什么?

感谢。抱歉这篇长篇文章。它是大海捞针,我找不到针。

1 个答案:

答案 0 :(得分:0)

只是一个疯狂的猜测,你的子类不应该调用[super backgroundImageForCard]吗?