понедельник, 26 ноября 2012 г.

Кратко про Objective-C на iOS Часть 2

Отрисовка картинок


- (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

Примеры исходного кода:
examples.oreilly.com/0636920021728

Комментариев нет:

Отправить комментарий