Взаимодействие с пользователями iOS и Mac OS

Есть два пути для редактирования данных:
  • редактирование-на-месте - один и тот же интерфейс используется для отображения и редактирования данных;
  • отдельный интерфейс для редактирования данных.

На Mac OS отдельный интерфейс для редактирования данных создается с помощью modal sheet или окна. А на iOS с помощью popover или view.

Human Interface Guidelines:

Интерфейс на iPad лучше делать так чтобы у пользователя всё было на виду и не надо было использовать навигацию.


Переключение на отдельный интерфейс для редактирования данных


Добавьте Detail Disclosure Accessory к строке:

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @”AgendaCell;
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
cell.editingAccessoryType = UITableViewCellAccessoryNone;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
// Configure the cell.
if (indexPath.row < [self.jobs count]) {
Job *myJob = [self.jobs objectAtIndex:indexPath.row];
cell.textLabel.text = myJob.job_description;
cell.detailTextLabel.text = myJob.rate;
// you might want to add an image to the cell with cell.imageView.image
// = something.
}
return cell;
}

Далее надо обработать событие тапа (аналог клика на touch-интерфейсах) на кнопке detail disclosure:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
Job *myItem = [self.jobs objectAtIndex:indexPath.row];
nextViewController = [[JobDetailController alloc]
initWithNibName:@”JobViewbundle:nil];
nextViewController.detailItem = myItem;
self.rootViewController setDetailView: nextViewController;
}

В этом методе надо создать новый view controller и настроить его на отображение строки по которой был сделан тап.

Наконец нужно установить новый view controller:

- (void)setDetailView: newDetailView {
detailViewController = (DetailViewController*)nextViewController;
// Update the split view controller’s view controllers array.
NSArray *viewControllers = [[NSArray alloc]
initWithObjects:self.navigationController,
nextViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];
// Dismiss the popover if it’s present.
if (popoverController != nil) {
[popoverController dismissPopoverAnimated:YES];
}
// Configure the new view controller’s popover button (after the view
// has been
// displayed and its toolbar/navigation bar has been created).
if (rootPopoverButtonItem != nil) {
[nextViewController
showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
}

Использование Popover-ов на iOS

Пример:

Создайте view controller, который будет отображаться в popover-e. Это будет наследник UIPopoverContentViewController.

Инстанцируйте view controller в соответствующем месте.

- (void)viewDidLoad {
[super viewDidLoad];
PopoverContentViewController *content = [[PopoverContentViewController
alloc] init];
// Setup the popover for use in the detail view.
detailViewPopover = [[UIPopoverController alloc]
initWithContentViewController:content];
detailViewPopover.popoverContentSize = CGSizeMake(320., 320.);
detailViewPopover.delegate = self;
// Setup the popover for use from the navigation bar.
barButtonItemPopover = [[UIPopoverController alloc]
initWithContentViewController:content];
barButtonItemPopover.popoverContentSize = CGSizeMake(320., 320.);
barButtonItemPopover.delegate = self;
[content release];
}

Для того чтобы показать popover можно использовать следующий код:

[detailViewPopover presentPopoverFromRect:tappedButton.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Для того чтобы показать popover по нажатию на toolbar item надо использовать следующий код:


if (barButtonItemPopover.popoverVisible == NO) {
[barButtonItemPopover presentPopoverFromBarButtonItem:tappedButton
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else {
[barButtonItemPopover dismissPopoverAnimated:YES];
}
[barButtonItemPopover presentPopoverFromBarButtonItem:tappedButton
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

Можно задать следующие направления:
  • UIPopoverArrowDirectionUp
  • UIPopoverArrowDirectionDown
  • UIPopoverArrowDirectionLeft
  • UIPopoverArrowDirectionRight
  • UIPopoverArrowDirectionAny
  • UIPopoverArrowDirectionUnknown

Создание sheet-окна на Mac OS

Sheet-окно прикреплено к родительскому и как бы выезжает из его заголовка. Приостанавливается только родительское окно.

Загрузка sheet-а из bundle:

if (mySheet == nil)
{
NSBundle *myBundle = [NSBundle bundleForClass:[self class]];
NSNib *nib = [[NSNib alloc] initWithNibNamed:@”MySheet
bundle:myBundle];
BOOL success = [nib instantiateNibWithOwner:self
topLevelObjects:nil];
[nib release];
if (success != YES)
{
// handle error
return;
}
}

Используйте beginSheet для начала модальной сессии.

[NSApplication *app = [NSApplication sharedApplication];
[app beginSheet:mySheet
modalForWindow:documentWindow
modalDelegate:self
didEndSelector: @selector(mySheetDidEnd:returnCode:contextInfo:)
contextInfo:NULL];

В mySheetDidEnd можно выполнить обработку:

if (returnCode ==
NSOKButton)

Для того чтобы закрыть sheet-окно надо выполнить код:


[NSApp endSheet:mySheet returnCode:NSOKButton];
[NSApp endSheet:mySheet returnCode:NSCancelButton];

Создание модального окна

Модальное окно приостанавливает всё приложение.


- (NSInteger)runModalForWindow:(NSWindow *)aWindow