2012-06-29 3 views
0

Я загружаю переменное количество объектов (карт) в UIScrollView. Каждая карта создается программно из объектов в массиве. Идея состоит в том, что пользователь будет использовать карту, и она перевернется, указывая на то, что она была завершена. Когда я загружаю объекты (карты) в UIScrollView, только последняя карта будет переворачиваться. Нажатие любой из других карт переворачивает последнюю карточку.Как выполнить флип-анимацию на объектах (UIViews) в 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:@"[email protected]"]; 
       [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; 

} 

Любые предложения? У меня такое чувство, что это очень клочковый код, так что любые предложения приветствуются.

ответ

0

В цикле, где вы создаете ваши взгляды карты, добавьте это в нижней части:

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

100 произвольная константа, которая будет хорошо, пока ничего больше не использует эти теги (и если у вас нет более 99 карт).

Затем, когда вы обращаетесь с кнопкой, поставьте это в самом начале.

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

код, который вы теперь дает тег к кнопке, но не фактический вид вы хотите, чтобы перевернуть. Вы используете theCardFlipView, не меняя его так, как вы хотите перевернуть (он просто остается привязанным к последней карте в вашем цикле).

Все, что было сказано, вы можете сделать это, даже не делая кнопку, вам просто нужно обрабатывать жесты касания на вашем просмотре прокрутки и найти, какая карта находится на отмеченной точке.

редактировать:

Это также выглядит как тумблер, который вы используете (toggleIsOn) не карты конкретных поэтому вы будете в конечном итоге с неправильным поведением листать. Вы должны следить за тем, какие карты перевернуты, а какие нет, и проверить на это. Если ваши карты были экземплярами подкласса UIView, вы можете добавить туда флаг, иначе вам может понадобиться поддерживать другой массив, содержащий эту информацию.

+1

Спасибо, Дима. Это то, что мне нужно. Ответ Ауги также заставил меня думать, что я собираюсь сделать это неправильно, поэтому я попытаюсь реорганизовать и сделать его более удобным. еще раз спасибо! – brandon

+0

@brandon вы могли бы поделиться кодом со мной, так как я пытаюсь сделать то же самое здесь. – lifemoveson

0

Ответ Димы должен исправить вашу проблему.

Создание класса карты, который содержит передний вид ui и обратно uiview, и устанавливает подвыборы в инструкции init, плюс метод flip поможет просто это.

Смежные вопросы