Pull to refresh

усложняем приложение для iPhone

Reading time4 min
Views3.5K
усложним немного наше приложение, которое отображало логотип хабра.

Я буду использовать iPhone SDK beta 4, проект от beta 2 подошел и откомпилировался. Если будут проблемы с компиляцией проекта — пишите в каментах.

multitouch


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

Для начала подключим к файлу MyView.m заголовочный файл math.h. Далее в конструкторе класса MyView — -(id)initWithFrame:(CGRect)frame в блоке if допишем две строки:
[self setMultipleTouchEnabled:YES];
[habrView setMultipleTouchEnabled:YES];

как видно, мы явно указываем, что хотим чтобы наш UIView и UIImageView, в котором находится логотип хабра поддерживали несколько касаний.

Теперь относительно обработки касаний. В классе UIView определены следующие обработчики касаний:
— (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
— (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
— (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
— (void)touchesChangedWithEvent:(UIEvent *)event;
— (void)touchesCancelled;
исходя из их названий не сложно догадаться в каком случае какой использовать

Определим две глобальные переменные(в заголовочный файл их заносить не надо): CGPoint startLoc0,startLoc1. В них будем хранить точки начальных касаний, если касаний два.

Теперь определим функцию обработки начала касания:
— (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
&nbsp if ([touches count] == 2) {
&nbsp &nbsp startLoc0 = [[[touches allObjects] objectAtIndex:0] locationInView:self];
&nbsp &nbsp startLoc1 = [[[touches allObjects] objectAtIndex:1] locationInView:self];
&nbsp &nbsp if (startLoc0.x == startLoc1.x) startLoc0.x+=0.05;
&nbsp &nbsp if (startLoc0.y == startLoc1.y) startLoc0.y+=0.05;
&nbsp }
}

Теперь определим функцию изменения положения касаний:
— (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
&nbsp if([touches count] == 1) {
&nbsp &nbsp UITouch *touch = [touches anyObject];
&nbsp &nbsp if ([touch view] == habrView) {
&nbsp &nbsp &nbsp CGPoint location = [touch locationInView:self];
&nbsp &nbsp &nbsp [habrView setCenter:location];
&nbsp &nbsp }
&nbsp }
&nbsp else if ([touches count] == 2) {
&nbsp &nbsp UITouch *touch0 = [[touches allObjects] objectAtIndex:0];
&nbsp &nbsp UITouch *touch1 = [[touches allObjects] objectAtIndex:1];
&nbsp &nbsp CGPoint loc0 = [touch0 locationInView:self];
&nbsp &nbsp CGPoint loc1 = [touch1 locationInView:self];
&nbsp &nbsp CGFloat scaleX = fabs((loc0.x — loc1.x)/(startLoc0.x — startLoc1.x));
&nbsp &nbsp CGFloat scaleY = fabs((loc0.y — loc1.y)/(startLoc0.y — startLoc1.y));
&nbsp &nbsp [habrView setTransform:CGAffineTransformMakeScale(scaleX, scaleY)];
&nbsp &nbsp }
&nbsp else
&nbsp &nbsp NSLog(@«too many touches :(»);
}

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

Но теперь остался основной вопрос: а как симулировать на эмуляторе несколько одновременных касаний? В результате загугливания выяснилось, что достаточно зажать кнопку Option.

Запускаем и радуемся результату:


splash screen


Добавим еще одну мелочь под названием splash screen. Splash screen — это картинка, которая будет отображаться сразу после клика по значку программы и до окончания работы функции — (void)applicationDidFinishLaunching:(UIApplication *)application. Полезно если хотите вывести краткую информацию про программу, производителя, версию и т.д.
Чтобы добавить splash screen к программе достаточно добавить в проект png файл с названием Default.png. Естесственно лучше чтобы этак картинка было с разрешением таким же как и экран iPhone.

application suspend


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

Создадим новый Objective-C класс, назовем его ApplicationSuspend, этот класс будет наследником класса UIApplication.

Содержание h файла должно быть таким:
#import <UIKit/UIKit.h>
interface ApplicationSuspend: UIApplication {
}
end


Содержание m файла должно быть таким:
#import «ApplicationSuspend.h»
@implementation ApplicationSuspend
— (void) applicationSuspend:(struct __GSEvent*) event {
}
end


Как видим, просто определили функцию applicationSuspend. Этого достаточно, чтобы при нажатии на кнопку Home программа уходила в suspend, а при нажатии на иконку — возвращалась.

Также можно переодпределить функции applicationResume:, menuButtonUp:, menuButtonDown:, launchApplicationWithIdentifier:suspended:.
Описание того, что так можно сделать, в офф документации не нашел, но нашел здесь. Но пока в iPhone SDK красуется надпись beta, то это можно простить.

А теперь самое главное, как указать программе, что следует использовать измененный UIApplication?
Откройте файл main.m и найдите строку:
&nbsp &nbsp int retVal = UIApplicationMain(argc, argv, nil, @«HelloHabrAppDelegate»);
как видим, третий парамет задан nil, вот как раз вместо него и надо вписать название измененного нами класса:
&nbsp &nbsp int retVal = UIApplicationMain(argc, argv, @«ApplicationSuspend», @«HelloHabrAppDelegate»);

Если все делали правильно, то запустите программу, переместите логотип хабра, нажмите на Home и потом снова войдите в программу, логотип должен остаться на прежнем месте.

Файл проекта здесь
Tags:
Hubs:
+22
Comments37

Articles