Здравствуйте, дорогие читатели Хабра!
Вот и я решил сделать что-нибудь из тридцати строк на родном 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/
Добавить комментарий