将字符串值前缀为IBOutlet和INT变量名称

时间:2013-02-22 01:24:26

标签: objective-c xcode string iboutlet

我有很多IBOutlets,前缀是'playerOne''plam2'等等。

@property (weak, nonatomic) IBOutlet UIButton *playerOneTurnButton;
@property (weak, nonatomic) IBOutlet UIButton *playerTwoTurnButton;
@property (weak, nonatomic) IBOutlet UIButton *playerOneChallengeButton;
@property (weak, nonatomic) IBOutlet UIButton *playerTwoChallengeButton;
@property (weak, nonatomic) IBOutlet UILabel *playerOneTimeLabel;
@property (weak, nonatomic) IBOutlet UILabel *playerTwoTimeLabel;

我有一些声明了一些变量,这些变量也以'playerOne''playerTwo'等为前缀......

int playerOneTimeRemaining;
int playerTwoTimeRemaining;
int playerThreeTimeRemaining;

etc ...

在各个方面,我想操纵这些出口(调整alpha,隐藏和活动属性),这取决于轮到谁,我还需要更改某些变量的int值。 我有各种NSStrings(本例中的一个称为whoWasChallengedFromGame),它记录了它的用途。每个玩家都有@"playerOne"@playerTwo"等。

目前我有一个if语句,它检查字符串并执行一段代码。每次只调整出口和变量的名称时,这段代码几乎相同......

-(void)challengeAccepted {
Store *myStore = [Store sharedStore];
if (([myStore.whoWasChallengedFromGame isEqual:@"playerOne"]) && ([myStore.brutalModeFromOptions isEqual:@"lenient"])) {
    playerOneTimeRemaining -= 30;
    playerOneTimeLabel.text = [NSString stringWithFormat:@"%i", playerOneTimeRemaining];
}

if (([myStore.whoWasChallengedFromGame isEqual:@"playerTwo"]) && ([myStore.brutalModeFromOptions isEqual:@"lenient"])) {
    playerTwoTimeRemaining -= 30;
    playerTwoTimeLabel.text = [NSString stringWithFormat:@"%i", playerTwoTimeRemaining];

}

etc etc for each player

正如您所看到的,随着玩家数量的增加,这实际上是不可控制的。 我要做的是能够编写一个代码块来检查字符串whoWasChallengedFromGame并在IBOutlet和变量名称前加上

所以代码将只需要说

"string"TimeRemaining -=30
"string"TimeLabel.text= blah blah

代码将简单地将“string”部分转换为playerOne或playerTwo或字符串whoWasChallengedFromGame中的任何内容。

如果可以做到这一点有什么想法吗?

2 个答案:

答案 0 :(得分:0)

创建一个PlayerControls课程,在viewDidLoad中为游戏中的每个玩家初始化,然后使用PlayerControls为当前玩家进行调整。

这是一个简单的例子:

@interface PlayerControls : NSObject
@property (weak, nonatomic) UIButton *turnButton;
@property (weak, nonatomic) UIButton *challengeButton;
@property (weak, nonatomic) UILabel *timeLabel;
@end

创建PlayerControls的每个玩家实例,并将它们放入数组中。将此声明添加到您的控制器:

PlayerControls *playerControls[2];

-(void)viewDidLoad {
    playerControls[0] = [[PlayerControls alloc] init];
    playerControls[0].turnButton = self.playerOneTurnButton;
    playerControls[0].challengeButton = self.playerOneChallengeButton;
    playerControls[0].timeLabel = self.playerOneTimeLabel;
    playerControls[1] = [[PlayerControls alloc] init];
    playerControls[1].turnButton = self.playerTwoTurnButton;
    playerControls[1].challengeButton = self.playerTwoChallengeButton;
    playerControls[1].timeLabel = self.playerTwoTimeLabel;
}

从这一点开始,您可以通过其索引来引用当前玩家:玩家1为零,玩家2为1。您可以根据需要添加更多播放器,而无需更改代码。

答案 1 :(得分:0)

使用Key-Value Coding(KVC)后,您可以实现自己的目标。

请特别注意this page。为了合并您的播放器信息,您可以执行以下操作:

[myInstance setValue:someAppropriateValue
              forKey:[NSString stringWithFormat:@"%@challengeButton", currentPlayer]];

但是,我可能会使用一个类来做这件事。我强烈建议您使用包装类来管理播放器,例如:

@interface PlayerStates

- (UIButton *)turnButtonForPlayer:(NSInteger)player
...etc

@end

这种方法的缺点是您不能直接使用IBOutlet(尽管您可以从IBOutletCollection构建它。)

如果您确实需要为每个小部件使用IBOutlet,我可能会使用KVC,但请确保为您的玩家使用命名常量:

typedef enum {
    PlayerOne,
    PlayerTwo,
} Player;

@property (nonatomic) Player currentPlayer;

然后使用以下方法获取KVC所需的字符串:

- (NSString *)stringForPlayer:(Player)player
{
    switch (player) {
        case PlayerOne:
            return @"playerOne";
        ...
}