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

Автор оригинала: 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.
Продолжение смотрите здесь

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 16

    +3
    Недавно в App Store не пустидли приложение для iPad, в котором реализовали жест как в приложении Photos. Этот жест позволяет двумя пальцами приоткрывать стопку фотографий. И его, кстати тоже небыло в SDK. Подробнее тут itabletka.ru/ipost/1450

    Так что вот так.
      +1
      ого! спс! будем знать!
      жестко они!
      0
      Смотрел видео и прозревал с этого эффекта — клёво.
      Жаль, что так происходит — а как же Apple Style?
        0
        Ну возможно этот элемент и не под запретом, тогда почему его нет в SDK?
          0
          UIPopoverControllerDelegate и UIPopoverController тоже не было в оф. документации, пока не вышла final-версия SDK.
          1 вариант — ещё появится.
          2 вариант — «пишите сами, там ничего сложного»
          3 вариант — запретят.

          Как по мне, 3 вариант в данном случае маловероятен.
            0
            UIPopoverController был, есть даже пример от apple разработчиков, ToolbarSearch с его использованием, зуб даю!
          0
          Жест как бы был не запрещен и в то же время не разрешили, мотивировав тем что только в приложениях Apple это может использоваться. Но пост в любом случае полезен.
            0
            в следующей статье будет сделаем покрасивее и добавим прокрутку.
            так что Welcome!
            0
            Совет — для исходников, если они открытые, лучше использовать тот же GitHub. Ссылки на файлообменники как-то не true.
              0
              ок, буду иметь ввиду.
              и ещё раз спасибо за карму.
              0
              А можно вопрос немного не в тему? Вы в чем кодите? Мне для личной статистики и просто из интереса. Я никак не могу освоиться в Xcode уже год, какая-то крайне кривая поделка. Нет ли каких-то вменяемых альтернатив?
                0
                Работаю в XCode и вполне доволен.
                Автодополнение есть, дебаггер вполне приличный, инструменты — вообще прелесть.
                Выставьте Layout в All-in-one, настройте горячие клавиши для автодополнения и всё.
                Первый месяц я плевался, а сейчас привык настолько, что как раз MSVC кажется поделкой.
                  0
                  А как же навигация по открытым файлам с клавиатуры (это самая большая проблема)? А перемещение по коду без с Макбуковой клавиатуры? Аналог PgUp/PgDn — Fn + Opt + Up/Dn — это же пальцы сломаешь каждый раз нажимать? Search and replace ужасный. В дебаггере вместо каких-нибудь удобных шорткатов для Step in/out/over какие-то идиотские Opt-Shift-O и т.п., F7 гораздо проще нажать. Я понимаю, что можно перелопатить все конфиги, перенастроить все и т.п., но это дело принципа, получается, что Эпплу наплевать на разработчиков. Какая-нибудь VS 2003 (а то и более ранняя) просто недостижимая высота для Xcode.

                  У меня дофига претензий, можно список на несколько страниц написать. Вот и думаю как люди с этим уживаются.

                  Если бы была нормальная возможность все делать из командной строки, это было бы уже прекрасно. Так и этой возможности Эппл не дает нам в полной мере.
                    0
                    По поводу перемещений по коду и нелогичной (на первый взгляд) работы клавиш — дело привычки.
                    Уже привык, да и пальцы не сломал.
                    Дебаггером пользусь не так уж и часто — но мне хватает и кнопочек.
                    Всё это дело привычки, у меня вот NetBeans вызвал лишь раздражение.
                      0
                      Я понимаю, что дело привычки, но вот у меня при 15-летнем опыте разработки во всевозможных средах и без них, первый раз такое, что аж за целый год я не могу привыкнуть и плююсь каждый раз, когда запускаю Xcode. Xcode на первый взгляд очень симпатичный и сначала я был доволен, думал привыкну, но со временем понял, что он совершенно не дружит с клавиатурой. Почитав форумы, я осознал, что не один я страдаю, люди просят хотя бы простейший Ctrl-Tab. И плагинов к Xcode не напишешь нормальных, т.к. API нет.
                        –1
                        я привык к xCode только когда заюзал оригинальную маковскую клаву и сидел только за маком, за пол года, все от пальцев отскакивало, а еще через год уже не задумывался, код сам рекой лился, особенно с пивом или вином :)

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое