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

в 0:59, , рубрики: 30 строк, iOS, objective-c, все читают теги, ненормальное программирование, разработка под iOS, метки: , , ,

Рисовалка на 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:

Жми меня!

Автор: backmeupplz

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js