0

iOSプログラミングは初めてなので、練習のために、タップしてカードの前面を表示できるビューに戻ったトランプを使用した簡単なアプリを作成しようとしています。カードの表面は、タップするたびに異なります。私が達成しようとしているのは、カードをタップしたときです:

  1. 裏返してランダムなカードを表示し、
  2. カードをめくるたびに 1 ずつ増加するラベルを持つ

2 番目の要件は完了しましたが、最初の要件を正しく取得できないようです。私は 3 つのモデル (Card、Deck、PlayingCard) を持っています。私の Deck モデルはカードのランダム化を担当しており、コードは次のとおりです。

Deck.h

#import <Foundation/Foundation.h>
#import "Card.h"

@interface Deck : NSObject
- (void)addCard:(Card *)card atTop:(BOOL)atTop;

- (Card *)drawRandomCard;

@end

Deck.m

#import "Deck.h"
@interface Deck()

@property (strong, nonatomic) NSMutableArray *cards;

@end

@implementation Deck
-(NSMutableArray *)cards
{
    if(!_cards) _cards =[[NSMutableArray alloc] init];
    return _cards;
} 

- (void)addCard:(Card *)card atTop:(BOOL)atTop
{
    if(card){
        if(atTop){
            [self.cards insertObject:card atIndex:0];
        }
        else
        {
            [self.cards addObject:card];
        }
    }
} 

- (Card *)drawRandomCard
{
    Card *randomCard = nil;  

    if(self.cards.count){
        unsigned index = arc4random() % self.cards.count;
        randomCard = self.cards[index];
        [self.cards removeObjectAtIndex:index];
    }

    return randomCard;
}
@end

My PlayingCard は、基本的にカードの内容を記述します。たとえば。ハートのジャック、ダイヤモンドの 2 ジャックがカードの「ランク」であり、「ハート」がカードのスーツであり、一緒にカードの内容を形成します。

PlayingCard.h

#import <Foundation/Foundation.h>
#import "Card.h"
@interface PlayingCard : NSObject

@property (strong, nonatomic) NSString *suit;
@property (nonatomic) NSUInteger   rank;

+ (NSArray *) validSuits;
+ (NSUInteger) maxRank;

- (NSString *)contents;
@end

PlayingCard.m

#import "PlayingCard.h"

@implementation PlayingCard

- (NSString *)contents
{
    NSArray *rankStrings = [PlayingCard rankStrings];
    return [rankStrings[self.rank] stringByAppendingString:self.suit];
}

@synthesize suit = _suit;

+(NSArray *)validSuits{
    return @[@"♥", @"♦", @"♠", @"♣"] ;
}

+(NSArray *)rankStrings{
    return  @[@ "?", @"A", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9",@"10", @"J", @"Q", @"K"];

}
-(void)setSuit:(NSString *)suit
{
    if([[PlayingCard validSuits] containsObject:suit]){
        _suit = suit;
    }
}

-(NSString *)suit{
    return _suit ? _suit: @"?";
}

+ (NSUInteger)maxRank {
    return [self rankStrings].count-1;
}

-(void)setRank:(NSUInteger)rank{
    if(rank <= [PlayingCard maxRank]) {
        _rank = rank;
    }
}
@end

最後に私の ViewController.m

#import "CardGameViewController.h"
#import "Card.h"
#import "Deck.h"
#import "PlayingCard.h"

@interface CardGameViewController ()
@property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
@property (nonatomic) int flipCount;
@property (nonatomic) NSString *title;
@property (weak, nonatomic) IBOutlet UIButton *cardRandom;
@end

@implementation CardGameViewController

- (void)setFlipCount:(int)flipCount
{
    _flipCount = flipCount;
    self.flipsLabel.text = [NSString stringWithFormat:@" Flips:%d", self.flipCount ];
}

- (IBAction)flipCard:(UIButton *)sender
{

    if(sender.isSelected) {
        sender.selected = NO;
        self.flipCount ++;
    }
    else{
        sender.selected = YES;
        self.flipCount ++;         
    }
}

@end

これについて調べたところ、おそらく使用する必要があることがわかりました

- (void)setTitle:(NSString *)title forState:(UIControlState)state

コンテンツを含むカードの前面がボタンの選択されたコンテンツであるため、状態は UIControlStateSelected になりますが、モデルによって開発されたランダムなカード コンテンツに従ってタイトルを設定する方法がわかりません。

4

2 に答える 2

1

CardGameViewController に Deck クラス (cardDeck と呼ばれる) のプロパティがあり、addCard メソッドを使用してそのプロパティにカードを既に設定しているとします。ユーザーがフリップボタンをタップすると、次のようにする必要があります::

- (IBAction)flipCard:(UIButton *)sender
{

  //draw a random card
  Card *randomCard = [self.cardDeck drawRandomCard];

  //set the button title
  [sender setTitle:[randomCard contents] forState:UIControlStateSelected];

  if(sender.isSelected) {
    sender.selected = NO;
    self.flipCount ++;
  }
  else{
    sender.selected = YES;
    self.flipCount ++;         
  }
}

お役に立てれば

PS :: drawRandomCard メソッドの戻り値の型は「Card」です。「PlayingCard」にするか、PlayingCard クラスの名前を Card にする必要があります。

于 2013-01-29T20:12:37.870 に答える
0

トランプ デッキを初期化していません。ViewController.m ファイルは次のようになります (flipCard メソッドですべてのカードが表示されたら、デッキもリセットします)。

    #import "CardViewViewController.h"
    #import "PlayingCardDeck.h"

    @interface CardViewViewController ()
    @property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
    @property (nonatomic) int flipCount;
    @property (nonatomic) PlayingCardDeck *myDeck;
    @end
    @implementation CardViewViewController
    -(PlayingCardDeck *)myDeck
    {
        if(!_myDeck) _myDeck=[[PlayingCardDeck alloc] init];
        return _myDeck;
    }

    -(void)setFlipCount:(int)flipCount
    {
        _flipCount= (int) flipCount;
        self.flipsLabel.text=[NSString stringWithFormat:@"Flips: %d",self.flipCount];
    }
    - (IBAction)flipCard:(UIButton *)sender
    {
        if (!sender.isSelected)
        {
            if (self.flipCount >= 52)
            {
                self.flipCount = 0;
                self.myDeck = nil;
            }
            Card *cCard = [self.myDeck drawRandomCard];
            [sender setTitle: [cCard contents] forState:UIControlStateSelected];
            self.flipCount++;
        }
        sender.selected = !sender.isSelected;
    }

@end
于 2013-03-13T23:42:35.230 に答える