1

我有许多 IBOutlets 前缀为“playerOne”“playerTwo”等。

@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

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

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

4

2 回答 2

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

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

于 2013-02-22T01:36:38.513 回答
0

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

特别是看看这个页面。为了合并您的玩家信息,您可以执行以下操作:

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

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

@interface PlayerStates

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

@end

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

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

typedef enum {
    PlayerOne,
    PlayerTwo,
} Player;

@property (nonatomic) Player currentPlayer;

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

- (NSString *)stringForPlayer:(Player)player
{
    switch (player) {
        case PlayerOne:
            return @"playerOne";
        ...
}
于 2013-02-22T02:23:41.613 回答