Рисовалка на Objective-C под iOS (30 строк)

от автора


Здравствуйте, дорогие читатели Хабра!

Вот и я решил сделать что-нибудь из тридцати строк на родном Objective-C. Попробуем в прямом эфире и прямо сейчас сделать рисовалку под iPhone и iPad, уложившись в 30 строк кода.

Работать мы будем полностью в файле main.m для удобства подсчета строк. Создаем новый проект — Single View Application — и удаляем файлы классов ViewController’a и AppDelegat’a, так как их мы перенесем в main.m. Соответственно, в Storyboard’e отвязываем ViewController от автоматически созданного класса. Чтобы не париться из-за статус бара — убираем его в настройках, а так же фиксируем ориентацию экрана, чтобы не волноваться насчет поворотов девайса.

Сейчас main.m выглядит так:

Жми меня!

// //  main.m //  LittleDrawer // //  Created by Nikita Kolmogorov on 19.11.13. //  Copyright (c) 2013 Nikita Kolmogorov. All rights reserved. //  #import <UIKit/UIKit.h>  #import "AppDelegate.h"  int main(int argc, char * argv[]) {     @autoreleasepool {         return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));     } } 

Очень, очень жирно! Приведем его к минимальному виду, учитывая то, что код между {} можно писать в одну строку. Простите — иначе сложно влезть в 30 строк. Изменим main.m:

#import <UIKit/UIKit.h> int main(int argc, char * argv[]) {@autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));} } 

В разы лучше! Весь стандартный main.m теперь умещается в 2 строки. Но мы же удалили AppDelegate. Поправим эту оплошность. Файл main.m:

#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end @implementation AppDelegate @end int main(int argc, char * argv[]) {@autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));} } 

Осталось всего 26 строк! Вызов принят.

Однако, AppDelegate, все-таки, придется немного поправить: нужно добавить нашу рисовалку на rootViewController:

@interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end @implementation AppDelegate  - (void)applicationDidFinishLaunching:(UIApplication *)application {     [self.window.rootViewController.view addSubview:[[Drawer alloc] init]]; } @end 

Добавим класс нашей рисовалки, и main.m приобретает вид:

Жми меня!

#import <UIKit/UIKit.h> @interface Drawer : UIView @end @implementation Drawer @end @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application {     [self.window.rootViewController.view addSubview:[[Drawer alloc] initWithFrame:self.window.rootViewController.view.frame]]; } @end int main(int argc, char * argv[]) {@autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));} } 

Использовали 9 строк, осталось 21 строка на рисование. Добавим текущий путь рисования и минимальный тач-функционал для правильной работы приложения в класс Drawer:

Жми меня!

@implementation Drawer static NSMutableArray *route; - (void)drawRect:(CGRect)rect {     CGContextSetStrokeColorWithColor(UIGraphicsGetCurrentContext(), [UIColor whiteColor].CGColor);     CGContextMoveToPoint(UIGraphicsGetCurrentContext(),[route[0][0] intValue],[route[0][1] intValue]);     for (int i = 1; i < [route count]; i++)         CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), [route[i][0] intValue], [route[i][1] intValue]);     CGContextStrokePath(UIGraphicsGetCurrentContext()); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {     route = [NSMutableArray array]; 	[route addObject:@[@([[touches anyObject]locationInView:self].x),@([[touches anyObject]locationInView:self].y)]]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {     [route addObject:@[@([[touches anyObject]locationInView:self].x),@([[touches anyObject]locationInView:self].y)]];     [self setNeedsDisplay]; } @end 

Просто рисуем текущий путь по прикосновениям и не заботимся о уже нарисованном. Финальный файл main.m выглядит так:

Жми меня!

#import <UIKit/UIKit.h> @interface Drawer : UIView @end @implementation Drawer static NSMutableArray *route; - (void)drawRect:(CGRect)rect {     CGContextSetStrokeColorWithColor(UIGraphicsGetCurrentContext(), [UIColor whiteColor].CGColor);     CGContextMoveToPoint(UIGraphicsGetCurrentContext(),[route[0][0] intValue],[route[0][1] intValue]);     for (int i = 1; i < [route count]; i++)         CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), [route[i][0] intValue], [route[i][1] intValue]);     CGContextStrokePath(UIGraphicsGetCurrentContext()); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {     route = [NSMutableArray array]; 	[route addObject:@[@([[touches anyObject]locationInView:self].x),@([[touches anyObject]locationInView:self].y)]]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {     [route addObject:@[@([[touches anyObject]locationInView:self].x),@([[touches anyObject]locationInView:self].y)]];     [self setNeedsDisplay]; } @end @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end @implementation AppDelegate -(void)applicationDidFinishLaunching:(UIApplication *)application {     [self.window.rootViewController.view addSubview:[[Drawer alloc] initWithFrame:self.window.rootViewController.view.frame]]; } @end int main(int argc, char * argv[]) {@autoreleasepool {return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));} } 

Ровно 30 строк кода на Objective-C. Вот и все! Мне даже почти удалось следовать своей стилистике кода. Единственное, на что не хватило строк — это расписать функцию main.

GitHub:
github.com/backmeupplz/LittleDrawer/

Instacode:

Жми меня!

ссылка на оригинал статьи http://habrahabr.ru/post/202834/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *