Статьи

iOS SDK: ориентация устройства чтения iPad

Добро пожаловать в последний выпуск нашей серии, посвященный созданию устройства для чтения iPad для проекта « Война миров с листьями». В сегодняшнем посте я продемонстрирую несколько методов, которые можно использовать для настройки интерфейса при изменении ориентации устройства.

Со времени моего последнего поста в этой серии прошло около двух недель, поэтому я кратко расскажу о том, что мы уже рассмотрели:

В первом уроке из этой серии я познакомил вас с проектом Leaves и показал, как его интегрировать с Xcode 4. Затем я показал, как использовать UISlider с Leaves, чтобы пользователи могли быстро пролистывать PDF. Наконец, я продемонстрировал, как добавить пользовательское оглавление, чтобы пользователи могли переключаться между главами.

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

Однако, прежде чем идти дальше, позвольте мне рассказать, что этот учебник не будет делать: я не буду добавлять какие-либо новые основные функции в проект Leaves. Есть некоторые действительно удивительные вещи, которые вы могли бы осуществить, если бы захотели взломать код основного проекта или разорвать проект Leaves самостоятельно. Я призываю тех, кто участвует в сообществе, взять факел и сделать это. К сожалению, внести существенные изменения в основной проект в этой серии не представляется возможным из-за нехватки времени. Вместо этого я просто продемонстрирую, как лучше всего использовать то, что Leaves уже предоставляет, а также как настроить созданные нами пользовательские представления и элементы управления интерфейсом.

Это видео-демонстрация того, как этот урок научит вас строить:

Первый шаг в создании ориентации приложения — указать, какие ориентации может поддерживать WOTWViewController , основной контроллер представления проекта. Это делается с помощью следующего метода:

Метод shouldAutorotateToInterfaceOrientation: наследуется от UIViewController и позволяет каждому контроллеру представления указать, какие ориентации интерфейса поддерживаются. В этом уроке мы хотим поддержать их всех, поэтому я просто возвращаю «ДА». Однако мы могли бы проверить определенные значения UIInterfaceOrientation здесь, проверив параметр interfaceOrientation .

Если вы посмотрите на наш проект в Симуляторе сейчас, вы заметите, что все начинает меняться, когда меняется ориентация, но вы также заметите, что эти изменения по умолчанию оставляют желать лучшего. Есть два основных подхода к решению этой проблемы. Один из подходов состоит в том, чтобы подключиться к методам UIViewController , которые уведомляются, когда происходит изменение ориентации, например didRotateFromInterfaceOrientation: и вручную вносить в них необходимые изменения. Тем не менее, лучший подход для нашей установки — просто настроить свойство autoresizingMask в наших элементах интерфейса для гибкой адаптации к изменениям экрана автоматически.

Если вы новичок в autoresizingMask , не беспокойтесь. Вы правильно видели это в Интерфейсном Разработчике, где вы можете настроить его графически следующим образом:

IB Autoresizing

Возможно, вы не поняли, что вы также можете установить свойство вручную в коде (примечание: как правило, если вы можете сделать это в Интерфейсном Разработчике, вы можете сделать это в коде), и это позволяет вам контролировать как будут происходить автоматические изменения ориентации. Возможны следующие варианты ориентации:

  • UIViewAutoresizingNone
  • UIViewAutoresizingFlexibleLeftMargin
  • UIViewAutoresizingFlexibleWidth
  • UIViewAutoresizingFlexibleRightMargin
  • UIViewAutoresizingFlexibleTopMargin
  • UIViewAutoresizingFlexibleHeight
  • UIViewAutoresizingFlexibleBottomMargin

Поскольку свойство autoresizingMask представляет собой целочисленную битовую маску, вы можете объединить несколько значений в одно, просто используя оператор побитового ИЛИ для их объединения.

Например, если бы я хотел, чтобы myContentView имел все параметры UIViewAutoresizing , я мог бы сделать это:

1
myContentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |

Или, если бы я хотел, чтобы у myContentView не было поведения авторазмера, я мог бы настроить это так:

1
myContentView.autoresizingMask = UIViewAutoresizingNone;

Мы будем использовать этот метод для настройки поведения автоматического изменения размеров следующих объектов интерфейса: contentsButton , pageSlider , tableOfContentsView , bookHeading , bookOneSubtitle , bookTwoSubtitle и sectionButton .

Каждое из приведенных ниже изменений будет внесено в WOTWViewController.m , а соответствующий номер строки указан вместе с исходным кодом.

1
contentsButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
1
self.pageSlider.autoresizingMask = UIViewAutoresizingFlexibleTopMargin |
1
tableOfContentsView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin |
1
bookHeading.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
1
bookOneSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
1
bookTwoSubtitle.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
1
sectionButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
1
sectionButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |

После добавления всех вышеперечисленных свойств сохраните, соберите и запустите проект. Вы должны найти, что оглавление выглядит намного лучше в альбомной ориентации сейчас! Однако, если вы проницательны, вы заметите один явный недостаток: список оглавления «КНИГА I» обрезается по вертикали в альбомной ориентации.

Есть, конечно, несколько способов справиться с тем фактом, что у нас недостаточно вертикального пространства для отображения списка глав BOOK I. Например, мы могли бы попытаться изменить высоту кнопок или переместить листинг в горизонтальное, а не вертикальное положение. По моему мнению, лучший пользовательский опыт — использовать представление прокрутки, чтобы контролировать, какая часть списка видна.

Это достаточно легко сделать. Начните с объявления нового UIScrollView для хранения кнопок наших глав в файле WOTWViewController.h :

1
UIScrollView *sectionScrollView;

Затем инициализируйте эту переменную в методе viewDidLoad и установите маску авторазмера:

1
2
sectionScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(20.0f, 100.0f, 530.0f, 700.0f)];
sectionScrollView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin |

Не забудьте выпустить это позже.

Затем установите для переменных colYOffset и colXOffset значение 0.0f для их начального значения, а затем обновите код в обоих циклах для добавления объектов sectionScrollView в качестве tableOfContentsScrollView sectionScrollView вместо tableOfContentsScrollView :

1
[sectionScrollView addSubview:sectionButton];
1
[sectionScrollView addSubview:sectionButton];

Затем установите свойство contentSize представления прокрутки:

1
sectionScrollView.contentSize = CGSizeMake(523.0f, 680.0f);

Свойство contentSize контролирует длину и высоту прокручиваемого содержимого и должно быть настроено для правильной работы этого объекта. Предоставляются следующие значения: A) 2-й столбец X смещение плюс 250 (длина одной кнопки) и B) первый столбец Y смещение, поскольку первый столбец имеет большую вертикальную высоту.

Теперь добавьте следующие строки кода:

1
2
sectionScrollView.hidden = YES;
[tableOfContentsView addSubview:sectionScrollView];

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

Поскольку больше нет необходимости вручную переключать объекты кнопки между включенным и отключенным состояниями, выполните поиск в WOTWViewController.m для «enabled = YES» и «enabled = NO» и удалите все строки, которые были ответственны за переключение этого значения в разделе кнопки, в том числе в пределах displayTableOfContents и contentsButtonPressed: методы.

После удаления упомянутых выше строк внесите следующие изменения, чтобы вызвать скрытие и показ вместо этого вида прокрутки:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
— (void)displayTableOfContents
{
    // Hide the page slider
    self.pageSlider.hidden = YES;
 
    // Show the scroll view
    sectionScrollView.hidden = NO;
     
    // Animate the transition with a horizontal flip from right to left
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5f];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self->leavesView cache:YES];
    [self->leavesView bringSubviewToFront:tableOfContentsView];
    [UIView commitAnimations];
}
 
— (void)contentsButtonPressed:(UIButton *)sender
{
     
    // Update the PDF display position
    self->leavesView.currentPageIndex = sender.tag;
     
    // Display the UISlider
    self.pageSlider.hidden = NO;
    self.pageSlider.value = (float) sender.tag;
     
    // Animate the PDF back to the top of the leavesView subviews
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5f];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self->leavesView cache:YES];
    [self->leavesView sendSubviewToBack:tableOfContentsView];
    [UIView commitAnimations];
     
    // Hide the scroll view added to the TOC when not in view
    sectionScrollView.hidden = YES;
}

Представление прокрутки теперь должно быть скрыто, когда отображается представление листьев, и отображается, когда отображается оглавление. Сохраните, соберите и запустите ваш проект. Все наши объекты пользовательского интерфейса теперь должны адаптироваться к изменениям ориентации!

Моя цель при написании этой серии заключалась в том, чтобы продемонстрировать, как добавить полезные функции в реализацию Leaves по умолчанию, а также научить вас приемам и приемам программирования iOS SDK на примере. Я надеюсь, что вы узнали хотя бы несколько интересных самородков и нашли эту серию полезной в ваших собственных проектах. Не стесняйтесь оставлять комментарий ниже и дайте мне знать, если это помогло!

В ходе этой серии мы увидели как преимущества, так и ограничения при использовании проекта Leaves. Лично мне нравится, как Leaves могут быстро позволить вам создавать базовую анимацию скручивания левой / правой страницы, поддерживая ряд различных форматов контента (включая PDF). Однако, как мы видели в течение этой серии, реализация проекта по умолчанию требует много работы, чтобы соответствовать большинству профессиональных проектов. Нам пришлось обходить основной код проекта, пытаясь добавить слайдер и оглавление, и мы даже не добрались до некоторых из более сложных, но обычно необходимых функций, таких как выделение текста, закладки, аннотации и т. Д. ,

Конечно, Leaves не единственный вариант для достижения такой функциональности. В своем первом посте я упомянул FlipView , HMGLTransitions и проект PaperStack (все еще не выпущенный по состоянию на 06.10.2011). Есть также несколько веток проекта Leaves и, вероятно, еще несколько проектов, которые я не перечислил здесь.

Мой вопрос к сообществу таков: соответствуют ли текущие параметры с открытым исходным кодом для создания приложений eReader вашим потребностям? Если нет, то почему нет? Какие функции вы хотели бы видеть добавленными к существующим проектам, которые в настоящее время недоступны? Soundoff ниже. В настоящее время я планирую присоединиться к одному из проектов eReader, который уже существует, или, возможно, даже начать новый, так что я хотел бы услышать ваши отзывы!