Pull to refresh

Создание полосы прокрутки картинок а-ля iPhoto. Часть 1

Development for iOS *
Translation
Original author: MLS-Automatization
Начав программировать под iPad, я не нашёл компонента, подобного полосе прокрутки в приложении iPhoto для iPad.
image
Я попробовал реализовать что-то подобное.



Сначала, создадим ImageScrubberToolbar, который унаследуем от UIToolbar.
@interface ImageScrubberToolbar : UIToolbar
{
  IBOutlet id<ImageScrubberToolbarDelegate> delegate;
  NSArray * imagesArray;
  NSMutableArray * imageViewsArray;
  UIImageView * selectionImageView;
}
@property (nonatomic, retain) id<ImageScrubberToolbarDelegate> delegate;
-(void) setImagesArray:(NSArray *) array;
@end


* This source code was highlighted with Source Code Highlighter.



Теперь добавим private-методы ImageScrubberToolbar в m-файл.
@interface ImageScrubberToolbar()
-(int) checkTouchPosition:(CGPoint) aPoint;
-(void) slideSelection:(CGPoint) aTouchPoint;
-(float) leftMargin;
-(float) rightMargin;  
@end


* This source code was highlighted with Source Code Highlighter.



Опишем протокол делегата для реакции на событие выбора изображения.
@protocol ImageScrubberToolbarDelegate
-(void)imageSelected:(int) anIndex;
@end


* This source code was highlighted with Source Code Highlighter.



В метод – (id)initWithCoder:(NSCoder *)aDecoder мы добавим кастомную инициализацию.
    // Custom initialization
    imageViewsArray = [[NSMutableArray alloc] init];
    
    //setting custom height
    [self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y - 36, self.frame.size.width, 80)];
    
    //setting image for selection
    UIImage * img = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] resourcePath],@"selection.png"]];

    selectionImageView = [[UIImageView alloc] initWithImage:img];
    [self addSubview:selectionImageView];


* This source code was highlighted with Source Code Highlighter.



Теперь реализуем метод -(void) setImagesArray:(NSArray *) array для задания массива отображаемых картинок.
  if (imagesArray != array)
  {
    //release old array of images
    [imagesArray release];

    //remove old image views
    for (UIImageView * v in imageViewsArray)
    {
      [v removeFromSuperview];
    }
    [imageViewsArray removeAllObjects];

    //set new array of images
    imagesArray = [array retain];
    
    //calculate margins
    float leftMargin = [self leftMargin];
    float topMargin = (self.frame.size.height - SMALL_SIZE)/2.f;
  
    for (int i=0; i<[imagesArray count]; i++)
    {
      UIImage * img = [imagesArray objectAtIndex:i];
      
      //create new image view
      UIImageView * imgView = [[UIImageView alloc] initWithImage:img];
      [imageViewsArray addObject:imgView];
      [self addSubview:imgView];
      
      //disallow user interaction with image view
      imgView.userInteractionEnabled = NO;
      
      //set position
      imgView.frame = CGRectMake(leftMargin + SMALL_SIZE*i,
                    topMargin,
                    SMALL_SIZE,
                    SMALL_SIZE);
    }
    [selectionImageView setFrame:CGRectMake(leftMargin, 0, SMALL_SIZE, LARGE_SIZE)];
  }


* This source code was highlighted with Source Code Highlighter.



Следующий шаг — реализация методов для проверки точки касания и сдвига окошка выбора.
-(int) checkTouchPosition:(CGPoint) aPoint
{
  float leftMargin = [self leftMargin];
//  float topMargin = (self.frame.size.height - SMALL_SIZE)/2.f;
  
  return (aPoint.x - leftMargin)/SMALL_SIZE;  
}

-(void) slideSelection:(CGPoint) aTouchPoint
{  
  float x_min = [self leftMargin] - SMALL_SIZE/2.f;
  
  if (aTouchPoint.x < x_min)
  {
    return;
  }
  int pos = [self checkTouchPosition:aTouchPoint];
  
  if (pos > [imagesArray count] - 1)
  {
    return;
  }
  
  float x_pos = aTouchPoint.x - SMALL_SIZE/2.f;
  
  if (x_pos < x_min)
  {
    x_pos = x_min;
  }
  else
  {
    float x_max = [self rightMargin] - SMALL_SIZE/2.f;
    if (x_pos > x_max)
    {
      x_pos = x_max;
    }
  }
  [UIView beginAnimations:nil context:NULL]; 
  [UIView setAnimationDuration:ANIMATION_DURATION]; 
  
  [selectionImageView setFrame:CGRectMake(x_pos,
                      0,
                      SMALL_SIZE,
                      LARGE_SIZE)];  
  
  [UIView commitAnimations];
}


* This source code was highlighted with Source Code Highlighter.



Для обработки событий касания добавьте следующий код.
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  if ([touches count] != 1)
  {
    return;
  }
  
  UITouch * touch = [touches anyObject];
  CGPoint p = [touch locationInView:self];
  [self slideSelection:p];
}

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
  if ([touches count] != 1)
  {
    return;
  }
  
  UITouch * touch = [touches anyObject];
  CGPoint p = [touch locationInView:self];
  
  [self slideSelection:p];
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
  if ([touches count] != 1)
  {
    return;
  }
  
  UITouch * touch = [touches anyObject];
  CGPoint p = [touch locationInView:self];
  int pos = [self checkTouchPosition:p];
  
  if (pos < 0)
  {
    pos = 0;
  }
  else if (pos > [imagesArray count] - 1)
  {
    pos = [imagesArray count] - 1;
  }
  
  float leftMargin = [self leftMargin];
  [UIView beginAnimations:nil context:NULL]; 
  [UIView setAnimationDuration:ANIMATION_DURATION]; 

  [selectionImageView setFrame:CGRectMake(leftMargin + SMALL_SIZE*pos,
                      0,
                      SMALL_SIZE,
                      LARGE_SIZE)];
  [UIView commitAnimations];
  [delegate imageSelected:pos];
}


* This source code was highlighted with Source Code Highlighter.



Следующие шаги — добавление ImageScrubberToolbarDelegate в реализуемые нашим Application Delegate протоколы, добавление outlet'a ImageScrubberToolbar в члены Application Delegate и реализация метода -(void)imageSelected:(int) anIndex .
Итак, мы реализовали все главные классы и методы.

Наш ImageScrubberToolbar будет выглядеть так —
image

Вы можете скачать исходный код проекта ImageScrubber.
Продолжение смотрите здесь
Tags:
Hubs:
Total votes 33: ↑19 and ↓14 +5
Views 1.1K
Comments Comments 16