15 April 2010

Всплывающие окна. Работа с UIPopoverController

Development for iOS
Translation
Original author: MLS-Automatization
В iPhone SDK 3.2 было добавлено несколько новых элементов интерфейса, таких как UIPopoverController и UISplitViewController.
В этом посте я покажу как пользоваться UIPopoverController.

Для начала, скачайте исходники из моей предыдущей статьи.
Откройте Interface Builder и создайте новый пустой документ.
Выставьте класс File's Owner в ImageScrubberPopupController, добавьте UIView и UIImageView как дочерний элемент UIView.
Сохраните документ и выберите команду «Write class files».
Сохраните класс как ImageScrubberPopupController.

Теперь, пропишите UIViewController родительским классом и добавьте член класса UIImageView * imgView.
Добавьте свойство для этого поля, чтоб получить доступ извне со спецификатором IBOutlet.
Вернитесь в Interface Builder, проведите связи между полем imgView и элементом формы UIImageView и полем view и элементом UIView.

Далее, немного модифицируем ImageScrubberToolbar для корректной работы со всплывающим окном.

UIPopoverController содержит 2 метода для показа всплывающего окна:
  • - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated
  • - (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated

Как следует из имён методов, первый показывает всплывающее окно из центра заданного прямоугольника
image

а второй — из кнопки панели, аналогично всплывающему окну в UISplitViewController в портретной ориентации.
image

Мы будем использовать первый метод, поэтому нас нужен прямоугольник выбранной превьюшки, чтоб отобразить всплывающее окно выходящим из неё.
-(CGRect) frameOfSelection
{
return CGRectMake(self.frame.origin.x + left + SMALL_SIZE*position - SIZE_DIF,
self.frame.origin.y - LARGE_SIZE,
LARGE_SIZE,
LARGE_SIZE);
}


* This source code was highlighted with Source Code Highlighter.

Далее, добавим UIPopoverControllerDelegate к протоколам класса ImageScrubberViewController.
Данный протокол содержит 2 опциональных (не обязательных к реализации) метода:
  • - (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController — вызывается, если пользователь выполнил действие, приводящее к скрытию всплывающего окна. Может возвратить NO для предотвращения скрытия.
  • - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController — оповещает о скрытии. Метод не вызывается, если -dismissPopoverAnimated: вызван напрямую.

Для создания всплывающего окна, достаточно всего лишь вызвать - (id)initWithContentViewController:(UIViewController *)viewController , передав требуемый для отображения UIViewController. Если необходимо, выставьте также свойство delegate.

Существует одна интересная особенность UIPopoverController.
Если UIViewController с содержимым всплывающего окна является также экземляром класса UINavigationController, всплывающее окно будет иметь широкую верхнюю границу со всеми элементами панели навигации заданного UINavigationController.
image

Чтоб отобразить всплывающее окно, выставьте свойство popoverContentSize и вызовите один из методов: 
  • presentPopoverFromRect: inView: permittedArrowDirections: animated:
  • presentPopoverFromBarButtonItem: permittedArrowDirections: animated:


Если приложение поддерживает несколько ориентаций устройства, необходимо переопределить метод -(void) didRotateFromInterfaceOrientation: для UIViewController.
Если всплывающее окно отображается в момент поворота, необходимо его спрятать и снова показать.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[imageScrubberToolbar rebuild];

if ([popoverController isPopoverVisible])
{
[popoverController dismissPopoverAnimated:NO];

CGSize size = [self rotatedSize];
size.height -= imageScrubberToolbar.frame.size.height;

popoverController.popoverContentSize = size;

[popoverController presentPopoverFromRect:[imageScrubberToolbar frameOfSelection]
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionDown
animated:YES];
}
}


* This source code was highlighted with Source Code Highlighter.

При повороте интерфейса высота и ширина UIView НЕ МЕНЯЮТСЯ МЕСТАМИ!
Поэтому добавим метод, возвращающий действительный размер окна.
Если ориентация интерфейса по умолчанию ПОРТРЕТНАЯ, используйте следующий код:
-(CGSize)rotatedSize
{
if ((self.interfaceOrientation == UIInterfaceOrientationPortrait) ||
(self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
{
return self.view.frame.size;
}
else
{
return CGSizeMake(self.view.frame.size.height, self.view.frame.size.width);
}
}

* This source code was highlighted with Source Code Highlighter.

Иначе, замените UIInterfaceOrientationPortrait и UIInterfaceOrientationPortraitUpsideDown на UIInterfaceOrientationLandscapeRight и UIInterfaceOrientationLandscapeLeft.

Вот и всё. Мы добавили симпатичное всплывающее окошко к нашей полосе прокрутки.
image
Исходный код можно скачать здесь.
Tags:iPadAppleMac OS XXCodeObjective-C
Hubs: Development for iOS
+12
6.2k 33
Comments 7
Top of the last 24 hours