0

可変量のオブジェクト(カード)をにロードしていますUIScrollView。各カードは、配列内のオブジェクトからプログラムで作成されます。アイデアは、ユーザーがカードをタップし、それが完了したことを示すために裏返すというものです。オブジェクト(カード)をロードするとUIScrollView、最後のカードだけが反転します。他のカードのいずれかをタップすると、その最後のカードがめくられます。

裏返したいオブジェクト(カード)へのポインタを指定する必要があると思いますが、その方法がわかりません。タップしたボタンにタグを付けてみましたが、うまくいきませんでした。UIScrollView内の特定のオブジェクトをターゲットにして、そのオブジェクトに対してアクションを実行するにはどうすればよいですか?

これが私がこれまでに持っているコードです:

// create a cardScrollView
    // if there are not cards for the schedule, display the no cards message.
    // if there are cards then create the scroller, add the cards, and then add to screen.
    if (cardCount == 0) {
        NSLog(@"There are no cards available");
        // place a label on screen that tells user there are no cards on the schedule. with animation.
        // *** TODO: this will eventually be a better graphical message. ***
        UILabel *noScheduleMsg = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 240, 50)];
        noScheduleMsg.backgroundColor = [UIColor clearColor];
        [noScheduleMsg setText:@"Opps! It doesn't look like there are picture cards on this schedule!"];
        [noScheduleMsg setLineBreakMode:UILineBreakModeCharacterWrap];
        noScheduleMsg.numberOfLines = 2;
        [noScheduleView addSubview:noScheduleMsg];

        // animate the view onto the screen
        [UIView animateWithDuration:.3 animations:^{
            noScheduleView.alpha = 1.0; 
        }];
    }
    else
    {
        NSLog(@"Display schedule cards");
        // check to see if there is a cardview first.
        if (!cardView) {

            // TODO: check for the last known completed card and show the following card in line.

            //create UIView that the scroller will go into.
            cardView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 320, 250)];
            //set cardView properties
            cardView.backgroundColor = [UIColor clearColor];
            //make sure I hide the cardview so that animation to full alpha is completed. Add to main view.
            cardView.alpha = 0.0;
            [self.view addSubview:cardView];

            //create the cardViewScroller. this is where all the cards will be placed.
            cardScroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 250)];
            cardScroller.backgroundColor = [UIColor clearColor];
            cardScroller.alwaysBounceVertical = NO;
            cardScroller.pagingEnabled = YES;
            cardScroller.showsVerticalScrollIndicator = NO;
            cardScroller.showsHorizontalScrollIndicator = NO;
            cardScroller.scrollEnabled = YES;    
            int cardscrollWidth = 120;
            cardScroller.contentSize = CGSizeMake(cardscrollWidth,80); 

            //iterate over the scheduleCards array and load each object into a view
            NSMutableArray *cards = [[NSMutableArray alloc] initWithArray:[selectedSchedule scheduleCards]];

            // this is to create the picture cards. itterate over each object and display in the cardScroller
            for (int i = 0; i < cardCount; i++) {

                // TODO: 
                // create the front of the card and put in a UIView object
                // create the back of the card and put in a UIView object.
                // Add a clear button to each isComplete to each card that is complete. if selected then show the backside of the card.
                // Add the flip logic
                // tie reset button to clear all isComplete values on the cards.

                // pull the right cards from the array at each index
                Cards *theCard = [cards objectAtIndex:i];

                UIButton *frontBtn = [[UIButton alloc] init];
                [frontBtn setFrame:CGRectMake(35, 0, 250, 250)];
                frontBtn.backgroundColor = [UIColor clearColor];
                [frontBtn setTag:i];
                [frontBtn addTarget:self action:@selector(changeTaskStatus:) forControlEvents:UIControlEventTouchUpInside];

                //set card border
                UIImageView *pcImageViewBg = [[UIImageView alloc] initWithFrame:CGRectMake(35, 0, 250, 250)];
                UIImage *bgimg = [UIImage imageNamed:@"bigCardbg@2x"];
                [pcImageViewBg setImage:bgimg];

                // set card image
                UIImageView *pcImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 230, 230)];
                NSString *ik = [theCard imageKey];
                if (ik) {
                    //get the image key from the store
                    UIImage *imageToDisplay = [[ScheduleImageStore sharedStore] imageForKey:ik];
                    // use that image to display in the view
                    [pcImageView setImage:imageToDisplay];
                } else {
                    //set default image.
                    [pcImageView setImage:[UIImage imageNamed:@"card"]];
                }

                // this is the front of the card.
                frontCard = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 255, 255)];

                // back of the card (done state)
                //backCard = [[UIView alloc] initWithFrame:CGRectMake(35, 0, 255, 255)];
                //[backCard addSubview:frontBtn];
                //backCard.backgroundColor = [UIColor redColor];

                // UIview for the flip (container)                
                CGRect frame;
                frame.origin.x = cardScroller.frame.size.width * i - 1;
                frame.origin.y = 0;
                frame.size = cardScroller.frame.size;                
                theCardFlipView = [[UIView alloc] initWithFrame:frame];
                //theCardFlipView.backgroundColor = [UIColor greenColor];

                // add the card views to the interface.                
                [pcImageViewBg addSubview:pcImageView];
                [frontCard addSubview:pcImageViewBg];
                [frontCard addSubview:frontBtn];
                // this is the container holding the frontcard and backcard
                // I need to target the appropriate 'theCardFlipView'
                [theCardFlipView addSubview:frontCard];
                [cardScroller addSubview:theCardFlipView];

                NSLog(@"%i",frontBtn.tag);
            }

            // set the contentsize of the scroller dynamically. it's based on how many cards there are in the schedule.
            cardScroller.contentSize = CGSizeMake(cardScroller.frame.size.width * cardCount, cardScroller.frame.size.height);

            //add scroller to card view.
            [cardView addSubview:cardScroller];

            // animate the cardview into view from transparent to opaque.
            [UIView animateWithDuration:.3 animations:^{ 
                cardView.alpha = 1.0;
            } completion: ^ (BOOL finished) {
                // if I want something to happen after loading the cardView, I could put it here.
            }];

        }

ボタンを押すことに基づく私の方法は次のとおりです。

-(void)changeTaskStatus:(UIButton *)sender {

    NSLog(@"button tag: %@",[sender tag]);
    if(toggleIsOn){
        //NSLog(@"incomplete card");
        [UIView transitionWithView:theCardFlipView
                          duration:0.8
                           options:UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionCurveEaseInOut
                        animations:^{
                            [[[theCardFlipView subviews] objectAtIndex:0] removeFromSuperview],
                            [theCardFlipView addSubview:frontCard];
                        }
                        completion:^(BOOL finished){
                            NSLog(@"card complete");
                        }];       
    }
    else {
        //NSLog(@"complete card");
        [UIView transitionWithView:theCardFlipView
                          duration:0.8
                           options:UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionCurveEaseInOut
                        animations:^{
                            [[[theCardFlipView subviews] objectAtIndex:0] removeFromSuperview],
                            [theCardFlipView addSubview:frontCard];
                        }
                        completion:^(BOOL finished){
                            //NSLog(@"front card tag: %i",frontBtn.tag);
                            NSLog(@"card not complete");
                        }];       
    }
    toggleIsOn = !toggleIsOn;

}

助言がありますか?これも非常に扱いにくいコードだと感じているので、どんな提案でも歓迎します。

4

2 に答える 2

0

カードビューを作成するループで、これを下部に追加します。

theCardFlipView.tag = i + 100; // since you're already using i for those button tags

100は任意の定数であり、他にこれらのタグを使用していない限り(99枚を超えるカードがない限り)問題ありません。

次に、ボタンを押す操作を行うときは、これを最初に配置します。

thecardFlipView = [cardScrollerView viewWithTag:sender.tag + 100];

これで作成したコードはボタンにタグを付けますが、めくりたい実際のビューは与えません。CardFlipViewを、反転させたいものに変更せずに使用しています(ループ内の最後のカードに割り当てられたままになります)。

とはいえ、ボタンを作成しなくても実際にこれを行うことができます。スクロールビューでタップジェスチャを処理し、タップされたポイントにあるカードを見つける必要があります。

編集:

また、使用しているトグル(toggleIsOn)はカード固有ではないように見えるため、誤った反転動作が発生することになります。どのカードが裏返され、どのカードが裏返されなかったかを追跡し、それと照合する必要があります。カードがUIViewサブクラスのインスタンスである場合は、そこにフラグを追加できます。そうでない場合は、その情報を含む別の配列を維持する必要があります。

于 2012-06-29T19:45:04.780 に答える
0

ディマの答えはあなたの問題を解決するはずです。

フロントUIビューとバックUIビューを含み、initステートメントにサブビューを設定するカードクラスに加えて、flipメソッドを作成すると、これが簡単に役立ちます。

于 2012-06-29T19:55:12.497 に答える