- (void)drawRect:(CGRect)rect{
UIImage *image = [UIImage imageNamed:@"Xcode.png"];
if (image != nil){
NSLog(@"Successfully loaded the image.");
} else {
NSLog(@"Failed to load the image.");
}
}
- (void)drawRect:(CGRect)rect{
UIImage *xcodeIcon = [UIImage imageNamed:@"Xcode.png"];
[xcodeIcon drawAtPoint:CGPointMake(0.0f, 20.0f)];
[xcodeIcon drawInRect:CGRectMake(50.0f,
10.0f,
40.0f,
35.0f)];
}
Отрисовка линий
- (void)drawRect:(CGRect)rect{
/* Установка цвета, который бедет использоваться для отрисовки линии */
[[UIColor brownColor] set];
/* Получить текущий графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Установить ширину линии */
CGContextSetLineWidth(currentContext, 5.0f);
/* Начать рисовать линию с этой точки */
CGContextMoveToPoint(currentContext, 50.0f, 10.0f);
/* Закончить линию в этой точке */
CGContextAddLineToPoint(currentContext, 100.0f, 200.0f);
/* Использовать выбранный цвет для отрисовки линии */
CGContextStrokePath(currentContext);
}
- (void)drawRect:(CGRect)rect{
/* Установка цвета, который бедет использоваться для отрисовки линии */
[[UIColor brownColor] set];
/* Получить текущий графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Установить ширину линии */
CGContextSetLineWidth(currentContext, 5.0f);
/* Начать рисовать линию с этой точки */
CGContextMoveToPoint(currentContext, 20.0f, 20.0f);
/* Закончить линию в этой точке */
CGContextAddLineToPoint(currentContext, 100.0f, 100.0f);
/* Продолжить линию до другой точки */
CGContextAddLineToPoint(currentContext, 300.0f, 100.0f);
/* Использовать выбранный цвет для отрисовки линий */
CGContextStrokePath(currentContext);
}
Типы линий
- (void) drawRooftopAtTopPointof:(CGPoint)paramTopPoint textToDisplay:(NSString *)paramText lineJoin:(CGLineJoin)paramLineJoin{
/* Устанавливаем цвет для линий */
[[UIColor brownColor] set];
/* Получаем графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Устанавливаем тип соединения линий */
CGContextSetLineJoin(currentContext, paramLineJoin);
/* Устанавоиваем ширину линий */
CGContextSetLineWidth(currentContext, 20.0f);
/* Начинаем линию с этой точки */
CGContextMoveToPoint(currentContext, paramTopPoint.x - 140, paramTopPoint.y + 100);
/* Заканчиваем линию в этой точке */
CGContextAddLineToPoint(currentContext, paramTopPoint.x, paramTopPoint.y);
/* Продолжаем линию до другой точки, делая крышу */
CGContextAddLineToPoint(currentContext, paramTopPoint.x + 140, paramTopPoint.y + 100);
/* Рисуем линии, используя цвет */
CGContextStrokePath(currentContext);
/* Устанавливаем черный цвет для текста под крышей */
[[UIColor blackColor] set];
/* Теперь отрисовываем текст */
CGPoint drawingPoint = CGPointMake(paramTopPoint.x - 40.0f, paramTopPoint.y + 60.0f);
[paramText drawAtPoint:drawingPoint withFont:[UIFont boldSystemFontOfSize:30.0f]];
}
- (void)drawRect:(CGRect)rect{
[self drawRooftopAtTopPointof:CGPointMake(160.0f, 40.0f) textToDisplay:@"Miter" lineJoin:kCGLineJoinMiter];
[self drawRooftopAtTopPointof:CGPointMake(160.0f, 180.0f) textToDisplay:@"Bevel" lineJoin:kCGLineJoinBevel];
[self drawRooftopAtTopPointof:CGPointMake(160.0f, 320.0f)
textToDisplay:@"Round" lineJoin:kCGLineJoinRound];
}
Отрисовка путей
- (void)drawRect:(CGRect)rect{
/* Создаем путь */
CGMutablePathRef path = CGPathCreateMutable();
/* На сколько велик экран? Мы хотим покрыть X весь экран. */
CGRect screenBounds = [[UIScreen mainScreen] bounds];
/* Начинаем с левого верхнего угла */
CGPathMoveToPoint(path, NULL, screenBounds.origin.x, screenBounds.origin.y);
/* Рисуем диагональ из левого верхнего угла в правый нижний */
CGPathAddLineToPoint(path, NULL, screenBounds.size.width, screenBounds.size.height);
/*Начинаем вторую линию из правого верхнего угла */
CGPathMoveToPoint(path, NULL, screenBounds.size.width, screenBounds.origin.y);
/* Рисуем линию из правого верхнего угла в левый нижний */
CGPathAddLineToPoint(path, NULL, screenBounds.origin.x, screenBounds.size.height);
/* Получаем графический контекст для каждого пути */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Добавляем путь к контексту*/
CGContextAddPath(currentContext, path);
/* Устанвливаем синий цвет */
[[UIColor blueColor] setStroke];
/* Отрисовываем путь вместе с цветом */
CGContextDrawPath(currentContext, kCGPathStroke);
/* Наконец освобождаем обект path */
CGPathRelease(path);
}
Отрисовка прямоугольников
- (void)drawRect:(CGRect)rect{
/* Создаем путь */
CGMutablePathRef path = CGPathCreateMutable();
/* Это границы прямойгольника */
CGRect rectangle = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Добавляем прямойгольник в путь */
CGPathAddRect(path, NULL, rectangle);
/* Получаем графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Добавить путь в контекст */
CGContextAddPath(currentContext, path);
/* Заводим заполняющий цвет */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Заводим цвет линии */
[[UIColor brownColor] setStroke];
/* Устанавливаем толщину линии 5 */
CGContextSetLineWidth(currentContext, 5.0f);
/* Отрисовываем и заполняем путь */
CGContextDrawPath(currentContext, kCGPathFillStroke);
/* Освобождаем путь */
CGPathRelease(path);
}
- (void)drawRect:(CGRect)rect{
/* Создаем путь */
CGMutablePathRef path = CGPathCreateMutable();
/* Границы первого прямоугольника */
CGRect rectangle1 = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Границы второго прямоугольника */
CGRect rectangle2 = CGRectMake(40.0f,
100.0f,
90.0f,
300.0f);
/* Помещаем оба прямоугольника в массив */
CGRect rectangles[2] = {rectangle1, rectangle2};
/* Добавляем прямоугольники в путь */
CGPathAddRects(path, NULL, (const CGRect *)&rectangles, 2);
/* Получаем текущий графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Добавляем путь в контекст */
CGContextAddPath(currentContext, path);
/* Устанавливаем заполняющий цвет */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Устанавливаем цвет линии */
[[UIColor blackColor] setStroke];
/* Устанавливаем толщину линии 5 */
CGContextSetLineWidth(currentContext, 5.0f);
/* Отрисовываем и заполняем путь */
CGContextDrawPath(currentContext, kCGPathFillStroke);
/* Освобождаем путь */
CGPathRelease(path);
}
Добавляем тени к формам
- (void) drawRectAtTopOfScreen{
/* Получаем графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetShadowWithColor(currentContext, CGSizeMake(10.0f, 10.0f), 20.0f,[[UIColor grayColor] CGColor]);
/* Создаем путь */
CGMutablePathRef path = CGPathCreateMutable();
/* Задаем границы прямоугольника */
CGRect firstRect = CGRectMake(55.0f,
60.0f,
150.0f,
150.0f);
/* Добавляем прямоугольник в путь */
CGPathAddRect(path, NULL, firstRect);
/* Добавляем путь в контекст */
CGContextAddPath(currentContext, path);
/* Устанавливаем заполняющий цвет */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Отрисовываем и заполняем путь */
CGContextDrawPath(currentContext, kCGPathFill);
/* Освобождаем путь */
CGPathRelease(path);
}
- (void) drawRectAtBottomOfScreen{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGMutablePathRef secondPath = CGPathCreateMutable();
CGRect secondRect = CGRectMake(150.0f,
250.0f,
100.0f,
100.0f);
CGPathAddRect(secondPath, NULL, secondRect);
CGContextAddPath(currentContext, secondPath);
[[UIColor purpleColor] setFill];
CGContextDrawPath(currentContext, kCGPathFill);
CGPathRelease(secondPath);
}
- (void)drawRect:(CGRect)rect{
[self drawRectAtTopOfScreen];
[self drawRectAtBottomOfScreen];
}
- (void) drawRectAtTopOfScreen{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGContextSetShadowWithColor(currentContext, CGSizeMake(10.0f, 10.0f), 20.0f,[[UIColor grayColor] CGColor]);
CGMutablePathRef path = CGPathCreateMutable();
CGRect firstRect = CGRectMake(55.0f,
60.0f,
150.0f,
150.0f);
CGPathAddRect(path,NULL, firstRect);
CGContextAddPath(currentContext, path);
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
CGContextDrawPath(currentContext,
kCGPathFill);
CGPathRelease(path);
/* Восстанавливаем контекст в то состояние, в котором он был на старте */
CGContextRestoreGState(currentContext);
}
Отрисовываем градиенты
- (void)drawRect:(CGRect)rect{
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSaveGState(currentContext);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIColor *startColor = [UIColor orangeColor];
CGFloat *startColorComponents = (CGFloat *)CGColorGetComponents([startColor CGColor]);
UIColor *endColor = [UIColor blueColor];
CGFloat *endColorComponents = (CGFloat *)CGColorGetComponents([endColor CGColor]);
CGFloat colorComponents[8] = {
/* 4 компонента оранжевого цвета (RGBA) */
startColorComponents[0],
startColorComponents[1],
startColorComponents[2],
startColorComponents[3], /* Первый цвет = оранжевый */
/* 4 компонента синего цвета (RGBA) */
endColorComponents[0],
endColorComponents[1],
endColorComponents[2],
endColorComponents[3], /* Второй цвет = синий */
};
CGFloat colorIndices[2] = {
0.0f, /* Цвет 0 в массиве colorComponents */
1.0f, /* Цвет 1 в массиве colorComponents */
};
CGGradientRef gradient = CGGradientCreateWithColorComponents (colorSpace,(const CGFloat *)&colorComponents, (const CGFloat *)&colorIndices, 2);
CGColorSpaceRelease(colorSpace);
CGPoint startPoint, endPoint;
startPoint = CGPointMake(120, 260);
endPoint = CGPointMake(200.0f, 220);
CGContextDrawLinearGradient (currentContext,
gradient,
startPoint,
endPoint,
kCGGradientDrawsBeforeStartLocation |
kCGGradientDrawsAfterEndLocation);
CGGradientRelease(gradient);
CGContextRestoreGState(currentContext);
}
Перемещение форм на экране
- (void)drawRect:(CGRect)rect{
/* СОздание пути */
CGMutablePathRef path = CGPathCreateMutable();
/* Задание границ прямоугольника */
CGRect rectangle = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Смещаем прямоугольник вправо на 100 точек */
CGAffineTransform transform = CGAffineTransformMakeTranslation(100.0f, 0.0f);
/* Добавляем прямоугольник в путь */
CGPathAddRect(path, &transform, rectangle);
/* Получаем графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Добавляем путь в контекст */
CGContextAddPath(currentContext, path);
/* Устанавливаем заполняющий цвет */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Устанавливаем цвет линий */
[[UIColor brownColor] setStroke];
/* Устанавливаем толщину линии 5 */
CGContextSetLineWidth(currentContext, 5.0f);
/* Отрисовываем и заполняем путь */
CGContextDrawPath(currentContext, kCGPathFillStroke);
/* Освобождаем путь */
CGPathRelease(path);
}
Масштабирование форм на экране
- (void)drawRect:(CGRect)rect{
/* Создаем путь */
CGMutablePathRef path = CGPathCreateMutable();
/* Задаем границы прямоугольника */
CGRect rectangle = CGRectMake(10.0f,
10.0f,
200.0f,
300.0f);
/* Добавляем прямоугольник в путь*/
CGPathAddRect(path, NULL, rectangle);
/* Получаем графический контекст */
CGContextRef currentContext = UIGraphicsGetCurrentContext();
/* Уменьшаем масштаб всего на экране до половины размера */
CGContextScaleCTM(currentContext, 0.5f, 0.5f);
/* Добавляем путь в контекст */
CGContextAddPath(currentContext, path);
/* Устанавливаем заполняющий цвет */
[[UIColor colorWithRed:0.20f
green:0.60f
blue:0.80f
alpha:1.0f] setFill];
/* Устанавливаем цвет линий */
[[UIColor brownColor] setStroke];
/* Устанавливаем толщину линй 5 */
CGContextSetLineWidth(currentContext, 5.0f);
/* Отрисовываем и заполняем путь */
CGContextDrawPath(currentContext, kCGPathFillStroke);
/* Освобождаем путь*/
CGPathRelease(path);
}
Вращение форм на экране
/* Поворот прямоугольника на 45 градусов по часовой стрелке */
CGAffineTransform transform = CGAffineTransformMakeRotation((45.0f * M_PI) / 180.0f);
/* Добавление прямоугольника в путь */
CGPathAddRect(path, &transform, rectangle);
Анимация и движение объектов на экране
Файл Animating_and_Moving_ViewsViewController.h
#import <UIKit/UIKit.h>
@interface Animating_and_Moving_ViewsViewController : UIViewController
@property (nonatomic, strong) UIImageView *xcodeImageView;
@end
Файл Animating_and_Moving_ViewsViewController.m
#import "Animating_and_Moving_ViewsViewController.h"
@implementation Animating_and_Moving_ViewsViewController
@synthesize xcodeImageView;
- (void) viewDidLoad{
[super viewDidLoad];
UIImage *xcodeImage = [UIImage imageNamed:@"Xcode.png"];
self.xcodeImageView = [[UIImageView alloc] initWithImage:xcodeImage];
/* Устанавливаем рамер и делаем картинку меньше */
[self.xcodeImageView setFrame:CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.xcodeImageView];
}
- (void) viewDidAppear:(BOOL)paramAnimated{
[super viewDidAppear:paramAnimated];
/* Начинаем с левого верхнего угла */
[self.xcodeImageView setFrame:CGRectMake(0.0f,
0.0f,
100.0f,
100.0f)];
[UIView beginAnimations:@"xcodeImageViewAnimation" context:(__bridge void *)self.xcodeImageView];
/* 5 секунд анимации */
[UIView setAnimationDuration:5.0f];
/* Устанавливаем делегата анимации */
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector: @selector(imageViewDidStop:finished:context:)];
/* Заканчиваем в правом нижнем углу */
[self.xcodeImageView setFrame:CGRectMake(200.0f,
350.0f,
100.0f,
100.0f)];
[UIView commitAnimations];
}
- (void)imageViewDidStop:(NSString *)paramAnimationID finished:(NSNumber *)paramFinished context:(void *)paramContext{
NSLog(@"Animation finished.");
NSLog(@"Animation ID = %@", paramAnimationID);
UIImageView *contextImageView = (__bridge UIImageView *)paramContext;
NSLog(@"Image View = %@", contextImageView);
}
- (void)viewDidUnload{
[super viewDidUnload];
self.xcodeImageView = nil;
}
@end
В консоли будет выведено через NSLog:
Animation finished.
Animation ID = xcodeImageViewAnimation
Image View = <UIImageView: 0x68221a0;
frame = (200 350; 100 100);
opaque = NO;
userInteractionEnabled = NO;
layer = <CALayer: 0x68221d0>>
Одновременная анимация и масштабирование объектов на экране
- (void) viewDidAppear:(BOOL)paramAnimated{
[super viewDidAppear:paramAnimated];
/* Располагаем картинку в центра экрана View */
self.xcodeImageView.center = self.view.center;
/* Убеждаемся что к картинке применена translation */
self.xcodeImageView.transform = CGAffineTransformIdentity;
/* Начинаем анимацию */
[UIView beginAnimations:nil context:NULL];
/* Делаем анимацию в течении 5 секунд */
[UIView setAnimationDuration:5.0f];
/* Увеличиваем картинку в 2 раза */
self.xcodeImageView.transform = CGAffineTransformMakeScale(2.0f, 2.0f);
/* Коммитим анимацию */
[UIView commitAnimations];
}
Одновременная анимация и вращение объектов на экране
- (void) viewDidAppear:(BOOL)paramAnimated{
[super viewDidAppear:paramAnimated];
self.xcodeImageView.center = self.view.center;
/* Начинаем анимацию */
[UIView beginAnimations:@"clockwiseAnimation"
context:NULL];
/* Делаем анимацию в течении 5 секунд */
[UIView setAnimationDuration:5.0f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector: @selector(clockwiseRotationStopped:finished:context:)];
/* Поворачиваем картинку на 90 градусов */
self.xcodeImageView.transform =
CGAffineTransformMakeRotation((90.0f * M_PI) / 180.0f);
/* Коммитим анимацию */
[UIView commitAnimations];
}
- (void)clockwiseRotationStopped:(NSString *)paramAnimationID finished:(NSNumber *)paramFinished context:(void *)paramContext{
[UIView beginAnimations:@"counterclockwiseAnimation" context:NULL];
/* Анимация в течении 5 секунд */
[UIView setAnimationDuration:5.0f];
/* Возвращаемся к исходному положению */
self.xcodeImageView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
}
Обнаружение наличия акселерометра
Файл Detecting_the_Availability_of_an_AccelerometerAppDelegate.h
#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
@interface Detecting_the_Availability_of_an_AccelerometerAppDelegate
: UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
Файл Detecting_the_Availability_of_an_AccelerometerAppDelegate.m
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
if ([motionManager isAccelerometerAvailable]){
NSLog(@"Accelerometer is available.");
} else{
NSLog(@"Accelerometer is not available.");
}
if ([motionManager isAccelerometerActive]){
NSLog(@"Accelerometer is active.");
} else {
NSLog(@"Accelerometer is not active.");
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
В консоли будет выведено через NSLog:
Accelerometer is not available.
Accelerometer is not active.
Обнаружение наличия гироскопа
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
if ([motionManager isGyroAvailable]){
NSLog(@"Gryro is available.");
} else {
NSLog(@"Gyro is not available.");
}
if ([motionManager isGyroActive]){
NSLog(@"Gryo is active.");
} else {
NSLog(@"Gryo is not active.");
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
В консоли будет выведено через NSLog:
Gyro is not available.
Gyro is not active.
Получение данных с акселерометра
Файл Retrieving_Accelerometer_DataViewController.h
#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
@interface Retrieving_Accelerometer_DataViewController : UIViewController
@property (nonatomic, strong) CMMotionManager *motionManager;
@end
Файл Retrieving_Accelerometer_DataViewController.m
#import "Retrieving_Accelerometer_DataViewController.h"
@implementation Retrieving_Accelerometer_DataViewController
@synthesize motionManager;
- (void)viewDidLoad{
[super viewDidLoad];
self.motionManager = [[CMMotionManager alloc] init];
if ([self.motionManager isAccelerometerAvailable]){
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
NSLog(@"X = %.04f, Y = %.04f, Z = %.04f",
accelerometerData.acceleration.x,
accelerometerData.acceleration.y,
accelerometerData.acceleration.z);
}];
} else {
NSLog(@"Accelerometer is not available.");
}
}
- (void)viewDidUnload{
[super viewDidUnload];
self.motionManager = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return YES;
}
@end
Обнаружение сотрясений устройства
Файл Detecting_Shakes_on_an_iOS_DeviceAppDelegate.m
#import "Detecting_Shakes_on_an_iOS_DeviceAppDelegate.h"
#import "Detecting_Shakes_on_an_iOS_DeviceViewController.h"
#import "MyWindow.h"
@implementation Detecting_Shakes_on_an_iOS_DeviceAppDelegate
@synthesize window = _window;
@synthesize viewController = _viewController;
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.window = [[MyWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
UIUserInterfaceIdiom device = [[UIDevice currentDevice] userInterfaceIdiom];
if (device == UIUserInterfaceIdiomPhone) {
self.viewController =
[[Detecting_Shakes_on_an_iOS_DeviceViewController alloc] initWithNibName:@"Detecting_Shakes_on_an_iOS_DeviceViewController_iPhone" bundle:nil];
} else {
self.viewController = [[Detecting_Shakes_on_an_iOS_DeviceViewController alloc] initWithNibName:@"Detecting_Shakes_on_an_iOS_DeviceViewController_iPad"
bundle:nil];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
Файл MyWindow.m
#import "MyWindow.h"
@implementation MyWindow
- (void) motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{
if (motion == UIEventSubtypeMotionShake){
NSLog(@"Detected a shake");
}
}
@end
Получение данных с гироскопа
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
CMMotionManager *manager = [[CMMotionManager alloc] init];
if ([manager isGyroAvailable]){
if ([manager isGyroActive] == NO){
[manager setGyroUpdateInterval:1.0f / 40.0f];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[manager startGyroUpdatesToQueue:queue withHandler:^(CMGyroData *gyroData, NSError *error) {
NSLog(@"Gyro Rotation x = %.04f", gyroData.rotationRate.x);
NSLog(@"Gyro Rotation y = %.04f", gyroData.rotationRate.y);
NSLog(@"Gyro Rotation z = %.04f", gyroData.rotationRate.z);
}];
} else {
NSLog(@"Gyro is already active.");
}
} else {
NSLog(@"Gyro isn't available.");
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Синхронизация данных из массива с iCloud
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSUbiquitousKeyValueStore *kvoStore = [NSUbiquitousKeyValueStore defaultStore];
NSString *stringValue = @"My String";
NSString *stringValueKey = @"MyStringKey";
BOOL boolValue = YES;
NSString *boolValueKey = @"MyBoolKey";
BOOL mustSynchronize = NO;
if ([[kvoStore stringForKey:stringValueKey] length] == 0){
NSLog(@"Could not find the string value in iCloud. Setting...");
[kvoStore setString:stringValue forKey:stringValueKey];
mustSynchronize = YES;
} else {
NSLog(@"Found the string in iCloud, getting...");
stringValue = [kvoStore stringForKey:stringValueKey];
}
if ([kvoStore boolForKey:boolValueKey] == NO){
NSLog(@"Could not find the boolean value in iCloud. Setting...");
[kvoStore setBool:boolValue forKey:boolValueKey];
mustSynchronize = YES;
} else {
NSLog(@"Found the boolean in iCloud, getting...");
boolValue = [kvoStore boolForKey:boolValueKey];
}
if (mustSynchronize){
if ([kvoStore synchronize]){
NSLog(@"Successfully synchronized with iCloud.");
} else {
NSLog(@"Failed to synchronize with iCloud.");
}
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Результат вывода в консоль через NSLog:
Could not find the string value in iCloud. Setting...
Could not find the boolean value in iCloud. Setting...
Successfully synchronized with iCloud.
Создание и управление папками в iCloud
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSFileManager *fileManager = [[NSFileManager alloc] init];
/* Разместите ваш team ID здесь */
NSString *teamID = @"TEAM ID";
NSString *rootFolderIdentifier = [NSString stringWithFormat:
@"%@.com.pixolity.Creating-and-Managing-Folders-for-Apps-in-iCloud",
teamID];
NSURL *containerURL =
[fileManager URLForUbiquityContainerIdentifier:rootFolderIdentifier];
NSString *documentsDirectory = [[containerURL path]
stringByAppendingPathComponent:@"Documents"];
BOOL isDirectory = NO;
BOOL mustCreateDocumentsDirectory = NO;
if ([fileManager fileExistsAtPath:documentsDirectory isDirectory:&isDirectory]){
if (isDirectory == NO){
mustCreateDocumentsDirectory = YES;
}
} else {
mustCreateDocumentsDirectory = YES;
}
if (mustCreateDocumentsDirectory){
NSLog(@"Must create the directory.");
NSError *directoryCreationError = nil;
if ([fileManager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:&directoryCreationError]){
NSLog(@"Successfully created the folder.");
} else {
NSLog(@"Failed to create the folder with error = %@", directoryCreationError);
}
} else {
NSLog(@"This folder already exists.");
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL) createiCloudDirectory:(NSString *)paramDirectory recursiveCreation:(BOOL)paramRecursiveCreation teamID:(NSString *)paramTeamID iCloudContainer:(NSString *)paramContainer finalPath:(NSString **)paramFinalPath{
BOOL result = NO;
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString *rootFolderIdentifier = [NSString stringWithFormat:
@"%@.%@", paramTeamID, paramContainer];
NSURL *containerURL =
[fileManager URLForUbiquityContainerIdentifier:rootFolderIdentifier];
NSString *documentsDirectory = [[containerURL path]
stringByAppendingPathComponent:@"Documents"];
if (paramFinalPath != nil){
*paramFinalPath = documentsDirectory;
}
BOOL isDirectory = NO;
BOOL mustCreateDocumentsDirectory = NO;
if ([fileManager fileExistsAtPath:documentsDirectory isDirectory:&isDirectory]){
if (isDirectory == NO){
mustCreateDocumentsDirectory = YES;
}
} else {
mustCreateDocumentsDirectory = YES;
}
if (mustCreateDocumentsDirectory){
NSLog(@"Must create the directory.");
NSError *directoryCreationError = nil;
if ([fileManager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:paramRecursiveCreation attributes:nil error:&directoryCreationError]){
result = YES;
NSLog(@"Successfully created the folder.");
} else {
NSLog(@"Failed to create the folder with error = %@",directoryCreationError);
}
} else {
NSLog(@"This folder already exists.");
result = YES;
}
return result;
}
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
/* Разместите ваш team ID здесь */
NSString *teamID = @"TEAM ID";
NSString *containerID =
@"com.pixolity.Creating-and-Managing-Folders-for-Apps-in-iCloud";
NSString *documentsDirectory = nil;
if ([self createiCloudDirectory:@"Documents" recursiveCreation:YES teamID:teamID iCloudContainer:containerID finalPath:&documentsDirectory]){
NSLog(@"Successfully created the directory in %@", documentsDirectory);
} else {
NSLog(@"Failed to create the directory.");
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
/* Разместите ваш team ID здесь */
NSString *teamID = @"TEAM ID";
NSString *containerID =
@"com.pixolity.Creating-and-Managing-Folders-for-Apps-in-iCloud";
NSString *documentsDirectory = nil;
if ([self createiCloudDirectory:@"Documents" recursiveCreation:YES teamID:teamID iCloudContainer:containerID finalPath:&documentsDirectory]){
NSLog(@"Successfully created the directory in %@", documentsDirectory);
NSString *stringToSave = @"My String";
NSString *pathToSave = [documentsDirectory stringByAppendingPathComponent:@"MyString.txt"];
NSError *savingError = nil;
if ([stringToSave writeToFile:pathToSave atomically:YES encoding:NSUTF8StringEncoding error:&savingError]){
NSLog(@"Successfully saved the string in iCloud.");
} else {
NSLog(@"Failed to save the string with error = %@", savingError);
}
} else {
NSLog(@"Failed to create the directory.");
}
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Поиск файлов и папок в iCloud
Файл ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (nonatomic, strong) NSMetadataQuery *metadataQuery;
@end
Файл ViewController.m
#import "ViewController.h"
@implementation ViewController
@synthesize metadataQuery;
- (void)viewDidLoad{
[super viewDidLoad];
/* Отслеживаем уведомления, которые поступают когда завершается запрос на поиск данных */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMetadataQueryFinished:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
// Делаем типичные для .nib-файлов настройки после загрузки
self.metadataQuery = [[NSMetadataQuery alloc] init];
NSArray *searchScopes = [[NSArray alloc] initWithObjects: NSMetadataQueryUbiquitousDocumentsScope, nil];
[self.metadataQuery setSearchScopes:searchScopes];
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"%K like %@", NSMetadataItemFSNameKey, @"*"];
[self.metadataQuery setPredicate:predicate];
if ([self.metadataQuery startQuery]){
NSLog(@"Successfully started the query.");
} else {
NSLog(@"Failed to start the query.");
}
}
- (void)viewDidUnload{
[super viewDidUnload];
// Освобождаем subviews внутри main view.
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self setMetadataQuery:nil];
}
- (NSURL *) urlForDocumentsFolderIniCloud{
NSURL *result = nil;
#error Put your TEAM ID here
const NSString *TeamID = @"YOUR TEAM ID";
NSString *containerID = [[NSBundle mainBundle] bundleIdentifier];
NSString *teamIDAndContainerID = [[NSString alloc] initWithFormat:@"%@.%@", TeamID, containerID];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *appiCloudContainerURL = [fileManager URLForUbiquityContainerIdentifier:teamIDAndContainerID];
result = [appiCloudContainerURL URLByAppendingPathComponent:@"Documents" isDirectory:YES];
if ([fileManager fileExistsAtPath:[result path]] == NO){
/* Папка Documents не существует в контейнере iCloud вашего приложения. Создадим ее сейча. */
NSError *creationError = nil;
BOOL created = [fileManager createDirectoryAtURL:result withIntermediateDirectories:YES attributes:nil error:&creationError];
if (created){
NSLog(@"Successfully created the Documents folder in iCloud.");
} else {
NSLog(@"Failed to create the Documents folder in iCloud. Error = %@", creationError);
result = nil;
}
} else {
/* Папка Documents уже существует в контейнере iCloud вашего приложения. Ничего не делаем. */
}
return result;
}
- (NSURL *) urlForRandomFileInDocumentsFolderIniCloud{
NSURL *result = nil;
NSUInteger randomNumber = arc4random() % NSUIntegerMax;
NSString *randomFileName = [[NSString alloc] initWithFormat:@"%llu.txt",(unsigned long)randomNumber];
/* Проверяме существование файла */
__block BOOL fileExistsAlready = NO;
[self.metadataQuery.results enumerateObjectsUsingBlock: ^(NSMetadataItem *item, NSUInteger idx, BOOL *stop) {
NSString *itemFileName = [item valueForAttribute:NSMetadataItemFSNameKey];
if ([itemFileName isEqualToString:randomFileName]){
NSLog(@"This file already exists. Aborting...");
fileExistsAlready = YES;
*stop = YES;
}
}];
if (fileExistsAlready){
return nil;
}
result = [[self urlForDocumentsFolderIniCloud] URLByAppendingPathComponent:randomFileName];
return result;
}
- (NSURL *) urlForRandomFileInDocumentsFolderInAppSandbox :(NSString *)paramFileName{
NSURL *result = nil;
NSString *documentsFolderInAppSandbox =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsFolderInAppSandbox stringByAppendingPathComponent:paramFileName];
result = [NSURL fileURLWithPath:filePath];
return result;
}
- (void) enumerateMetadataResults:(NSArray *)paramResults{
[paramResults enumerateObjectsUsingBlock: ^(NSMetadataItem *item, NSUInteger index, BOOL *stop) {
NSString *itemName = [item valueForAttribute:NSMetadataItemFSNameKey];
NSURL *itemURL = [item valueForAttribute:NSMetadataItemURLKey];
NSNumber *itemSize = [item valueForAttribute:NSMetadataItemFSSizeKey];
NSLog(@"Item name = %@", itemName);
NSLog(@"Item URL = %@", itemURL);
NSLog(@"Item Size = %llu",
(unsigned long long)[itemSize unsignedLongLongValue]);
}];
}
- (void) handleMetadataQueryFinished:(id)paramSender{
NSLog(@"Search finished");
if ([[paramSender object] isEqual:self.metadataQuery] == NO){
NSLog(@"An unknown object called this method. Not safe to proceed.");
return;
}
/* Прекращаем слуашать цведомления, так как мы не ждем ничего больше */
[[NSNotificationCenter defaultCenter] removeObserver:self];
/* Мы выполнили запрос. Теперь остановим процесс. */
[self.metadataQuery disableUpdates];
[self.metadataQuery stopQuery];
[self enumerateMetadataResults:self.metadataQuery.results];
if ([self.metadataQuery.results count] == 0){
NSLog(@"No files were found.");
}
NSURL *urlForFileIniCloud = [self urlForRandomFileInDocumentsFolderIniCloud];
if (urlForFileIniCloud == nil){
NSLog(@"Cannot create a file with this URL. URL is empty.");
return;
}
NSString *fileName = [[[urlForFileIniCloud path] componentsSeparatedByString:@"/"] lastObject];
NSURL *urlForFileInAppSandbox = [self urlForRandomFileInDocumentsFolderInAppSandbox:fileName];
NSString *fileContent = [[NSString alloc] initWithFormat:@"Content of %@", [[self urlForRandomFileInDocumentsFolderIniCloud] path]];
/* Сохраняем временный файл в app bundle и затем перемещаем его в iCloud */
NSError *writingError = nil;
BOOL couldWriteToAppSandbox = [fileContent writeToFile:[urlForFileInAppSandbox path] atomically:YES encoding:NSUTF8StringEncoding error:&writingError];
/* Если невозможно сохранить файл, то просто выходим из метода, так как не имеет смысла продолжать. */
if (couldWriteToAppSandbox == NO){
NSLog(@"Failed to save the file to app sandbox. Error = %@", writingError);
return;
}
NSFileManager *fileManager = [[NSFileManager alloc] init];
/* Теперь перемещаем файл в iCloud */
NSError *ubiquitousError = nil;
BOOL setUbiquitousSucceeded = [fileManager setUbiquitous:YES itemAtURL:urlForFileInAppSandbox destinationURL:urlForFileIniCloud error:&ubiquitousError];
if (setUbiquitousSucceeded){
NSLog(@"Successfully moved the file to iCloud.");
/* Файл был перемещени из App Sandbox в iCloud */
} else {
NSLog(@"Failed to move the file to iCloud with error = %@", ubiquitousError);
}
}
@end
Хранение документов пользователя в iCloud
#import <UIKit/UIKit.h>
@class CloudDocument;
@protocol CloudDocumentProtocol<NSObject>
- (void) cloudDocumentChanged:(CloudDocument *)paramSender;
@end
@interface CloudDocument : UIDocument
@property (nonatomic, strong) NSString *documentText;
@property (nonatomic, weak) id<CloudDocumentProtocol> delegate;
/* Инициализатор */
- (id) initWithFileURL:(NSURL *)paramURL delegate (id<CloudDocumentProtocol>)paramDelegate;
@end
#import "CloudDocument.h"
@implementation CloudDocument
@synthesize documentText;
@synthesize delegate;
- (id) initWithFileURL:(NSURL *)paramURL delegate:(id<CloudDocumentProtocol>)paramDelegate{
self = [super initWithFileURL:paramURL];
if (self != nil){
if (paramDelegate == nil){
NSLog(@"Warning: no delegate is given.");
}
delegate = paramDelegate;
}
return self;
}
- (id) initWithFileURL:(NSURL *)paramURL{
return [self initWithFileURL:paramURL
delegate:nil];
}
- (id) contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError{
if ([self.documentText length] == 0){
self.documentText = @"New Document";
}
return [self.documentText dataUsingEncoding:NSUTF8StringEncoding];
}
- (BOOL) loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError{
NSData *data = (NSData *)contents;
if ([data length] == 0){
self.documentText = @"New Document";
} else {
self.documentText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
if ([delegate respondsToSelector:@selector(cloudDocumentChanged:)]){
[delegate cloudDocumentChanged:self];
}
return YES;
}
- (NSURL *) urlForDocumentsDirectoryIniCloud{
NSURL *result = nil;
#error Replace this with your own Team ID
NSString *teamID = @"TEAM ID";
#error Replace this with your own app identifier NSString *containerID = @"com.pixolity.Storing-User-Documents-in-iCloud";
NSString *teamIDAndContainerID = [NSString stringWithFormat:@"%@.%@", teamID, containerID];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *iCloudURL = [fileManager URLForUbiquityContainerIdentifier:teamIDAndContainerID];
NSURL *documentsFolderURLIniCloud = [iCloudURL URLByAppendingPathComponent:@"Documents" isDirectory:YES];
/* Если не существует, то создать его */
if ([fileManager fileExistsAtPath:[documentsFolderURLIniCloud path]] == NO){
NSLog(@"The documents folder does NOT exist in iCloud. Creating...");
NSError *folderCreationError = nil;
BOOL created = [fileManager createDirectoryAtURL:documentsFolderURLIniCloud withIntermediateDirectories:YES
attributes:nil error:&folderCreationError];
if (created){
NSLog(@"Successfully created the Documents folder in iCloud.");
result = documentsFolderURLIniCloud;
} else {
NSLog(@"Failed to create the Documents folder in iCloud. Error = %@", folderCreationError);
}
} else {
NSLog(@"The Documents folder already exists in iCloud.");
result = documentsFolderURLIniCloud;
}
return result;
}
- (NSURL *) urlForFileInDocumentsDirectoryIniCloud{
return [[self urlForDocumentsDirectoryIniCloud] URLByAppendingPathComponent:@"UserDocument.txt"];
}
@end
#import <UIKit/UIKit.h>
#import "CloudDocument.h"
@interface ViewController : UIViewController
<CloudDocumentProtocol, UITextViewDelegate>
@property (nonatomic, strong) CloudDocument *cloudDocument;
@property (nonatomic, strong) UITextView *textViewCloudDocumentText;
@property (nonatomic, strong) NSMetadataQuery *metadataQuery;
@end
- (void) setupTextView{
/* Создаем text view */
CGRect textViewRect = CGRectMake(20.0f,
20.0f,
self.view.bounds.size.width - 40.0f,
self.view.bounds.size.height - 40.0f);
self.textViewCloudDocumentText = [[UITextView alloc] initWithFrame: textViewRect];
self.textViewCloudDocumentText.delegate = self;
self.textViewCloudDocumentText.font = [UIFont systemFontOfSize:20.0f];
[self.view addSubview:self.textViewCloudDocumentText];
}
- (void) listenForKeyboardNotifications{
/* Поскольку мы имеем text view, когда клавиатура отображена на экране, то мы хотим убедится, что содержимое text view полностью видимо, так что слушаем уведомления клавиатуры */
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) startSearchingForDocumentIniCloud{
/* Начинаем поиск существующих текстовых документов */
self.metadataQuery = [[NSMetadataQuery alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@", NSMetadataItemFSNameKey, @"*"];
[self.metadataQuery setPredicate:predicate];
NSArray *searchScopes = [[NSArray alloc] initWithObjects: NSMetadataQueryUbiquitousDocumentsScope, nil];
[self.metadataQuery setSearchScopes:searchScopes];
NSString *metadataNotification = NSMetadataQueryDidFinishGatheringNotification;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMetadataQueryFinished:) name:metadataNotification object:nil];
[self.metadataQuery startQuery];
}
- (void)viewDidLoad{
[super viewDidLoad];
[self listenForKeyboardNotifications];
self.view.backgroundColor = [UIColor brownColor];
[self setupTextView];
[self startSearchingForDocumentIniCloud];
}
- (void)viewDidUnload {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self setTextViewCloudDocumentText:nil];
[self setMetadataQuery:nil];
[super viewDidUnload];
}
- (void) handleMetadataQueryFinished:(NSNotification *)paramNotification{
/* Убедимся, что это запрос метаданных, которые мы ожидаем */
NSMetadataQuery *senderQuery = (NSMetadataQuery *)[paramNotification object];
if ([senderQuery isEqual:self.metadataQuery] == NO){
NSLog(@"Unknown metadata query sent us a message.");
return;
}
[self.metadataQuery disableUpdates];
/* Теперь мы прекращаем слушать уведомления, потому что они уже не нужны */
NSString *metadataNotification = NSMetadataQueryDidFinishGatheringNotification;
[[NSNotificationCenter defaultCenter] removeObserver:self name:metadataNotification object:nil];
[self.metadataQuery stopQuery];
NSLog(@"Metadata query finished.");
/* Теперь определим создали ли мы до этого документ в cloud space пользователя, потому что, если да, тогда мы должны избегать перезаписывания документа и спользовть текущий документ */
__block BOOL documentExistsIniCloud = NO;
NSString *FileNameToLookFor = @"UserDocument.txt";
NSArray *results = self.metadataQuery.results;
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSMetadataItem *item = (NSMetadataItem *)obj;
NSURL *itemURL = (NSURL *)[item valueForAttribute:NSMetadataItemURLKey];
NSString *lastComponent = (NSString *)[[itemURL pathComponents] lastObject];
if ([lastComponent isEqualToString:FileNameToLookFor]){
if ([itemURL isEqual:[self urlForFileInDocumentsDirectoryIniCloud]]){
documentExistsIniCloud = YES;
*stop = YES;
}
}
}];
NSURL *urlOfDocument = [self urlForFileInDocumentsDirectoryIniCloud];
self.cloudDocument = [[CloudDocument alloc] initWithFileURL:urlOfDocument
delegate:self];
__weak ViewController *weakSelf = self;
/* Если документ существует, то открыть его*/
if (documentExistsIniCloud){
NSLog(@"Document already exists in iCloud. Loading it from there...");
[self.cloudDocument openWithCompletionHandler:^(BOOL success) {
if (success){
ViewController *strongSelf = weakSelf;
NSLog(@"Successfully loaded the document from iCloud.");
strongSelf.textViewCloudDocumentText.text = strongSelf.cloudDocument.documentText;
} else {
NSLog(@"Failed to load the document from iCloud.");
}
}];
} else {
NSLog(@"Document does not exist in iCloud. Creating it...");
/* Если документ не существует, то спросить класс CloudDocument сохранить новый файл по данному адресу для нас */
[self.cloudDocument saveToURL:[self urlForFileInDocumentsDirectoryIniCloud]
forSaveOperation:UIDocumentSaveForCreating completionHandler: ^(BOOL success){
if (success){
NSLog(@"Successfully created the new file in iCloud.");
ViewController *strongSelf = weakSelf;
strongSelf.textViewCloudDocumentText.text = strongSelf.cloudDocument.documentText;
} else {
NSLog(@"Failed to create the file.");
}
}];
}
}
- (void) textViewDidChange:(UITextView *)textView{
self.cloudDocument.documentText = textView.text;
[self.cloudDocument updateChangeCount:UIDocumentChangeDone];
}
- (void) cloudDocumentChanged:(CloudDocument *)paramSender{
self.textViewCloudDocumentText.text = paramSender.documentText;
}
- (void) handleKeyboardWillShow:(NSNotification *)paramNotification{
NSDictionary *userInfo = [paramNotification userInfo];
NSValue *animationCurveObject =
[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];
NSValue *animationDurationObject =
[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];
NSValue *keyboardEndRectObject =
[userInfo valueForKey:UIKeyboardFrameEndUserInfoKey];
NSUInteger animationCurve = 0;
double animationDuration = 0.0f;
CGRect keyboardEndRect = CGRectMake(0, 0, 0, 0);
[animationCurveObject getValue:&animationCurve];
[animationDurationObject getValue:&animationDuration];
[keyboardEndRectObject getValue:&keyboardEndRect];
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
/* Сконвертировать frame из координатной системы window координатной системы нашего View */
keyboardEndRect = [self.view convertRect:keyboardEndRect fromView:window];
[UIView beginAnimations:@"changeTextViewContentInset" context:NULL];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];
CGRect intersectionOfKeyboardRectAndWindowRect = CGRectIntersection(window.frame, keyboardEndRect);
CGFloat bottomInset = intersectionOfKeyboardRectAndWindowRect.size.height;
self.textViewCloudDocumentText.contentInset = UIEdgeInsetsMake(0.0f,
0.0f,
bottomInset,
0.0f);
[UIView commitAnimations];
}
- (void) handleKeyboardWillHide:(NSNotification *)paramNotification{
if (UIEdgeInsetsEqualToEdgeInsets(self.textViewCloudDocumentText.contentInset,
UIEdgeInsetsZero)){
/* Содержимое нашего text View не повреждено, так что не нужно делать reset */
return;
}
NSDictionary *userInfo = [paramNotification userInfo];
NSValue *animationCurveObject =
[userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey];
NSValue *animationDurationObject =
[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey];
NSUInteger animationCurve = 0;
double animationDuration = 0.0f;
[animationCurveObject getValue:&animationCurve];
[animationDurationObject getValue:&animationDuration];
[UIView beginAnimations:@"changeTextViewContentInset" context:NULL];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:(UIViewAnimationCurve)animationCurve];
self.textViewCloudDocumentText.contentInset = UIEdgeInsetsZero;
[UIView commitAnimations];
}
Примеры элементов интерфейса iOS UI Elements (iOS UI Element Usage Guidelines):
developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW34
Примеры исходного кода:
Комментариев нет:
Отправить комментарий