2016-11-28 17 views
0

У меня возникла проблема при попытке набросать на UIView, который является дочерним видом в UIScrollView.Sketch On UIView В UIScrollView

Проблема возникает, когда вы пытаетесь выполнить эскиз на UIView после того, как он был увеличен или прокручен. Кажется, мой код эскиза (показано ниже) не учитывает масштаб или масштаб UIView в пределах UIScrollView, потому что линии размыты и не отображаются там, где они должны. Пожалуйста, дайте мне знать, есть ли что-то, что можно сделать с моим кодом или предоставить другое решение.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

     NSLog(@"Draw touchesBegan"); 

     mouseSwipedPSVC = NO; 
     UITouch *touch = [touches anyObject]; 
     lastPointPSVC = [touch locationInView:sheetDrawView]; 

} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 

     mouseSwipedPSVC = YES; 
     UITouch *touch = [touches anyObject]; 
     CGPoint currentPoint = [touch locationInView:sheetDrawView]; 

     UIGraphicsBeginImageContext(sheetDrawView.frame.size); 
     [drawImageView.image drawInRect:CGRectMake(0, 0,  sheetDrawView.frame.size.width, sheetDrawView.frame.size.height)]; 
     CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPointPSVC.x, lastPointPSVC.y); 
     CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); 
     CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
     CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushPSVC); 
     CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), redPSVC, greenPSVC, bluePSVC, 1.0); 
     CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal); 

     CGContextStrokePath(UIGraphicsGetCurrentContext()); 
     drawImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
     drawImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
     [drawImageView setAlpha:opacityPSVC]; 
     UIGraphicsEndImageContext(); 

     lastPointPSVC = currentPoint; 

} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 

    if(!mouseSwipedPSVC) { 
     NSLog(@"Check 1"); 

     UIGraphicsBeginImageContext(sheetDrawView.frame.size); 
     [drawImageView.image drawInRect:CGRectMake(0, 0, sheetDrawView.frame.size.width, sheetDrawView.frame.size.height)]; 
     CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
     CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushPSVC); 
     CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), redPSVC, greenPSVC, bluePSVC, opacityPSVC); 
     CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPointPSVC.x, lastPointPSVC.y); 
     CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPointPSVC.x, lastPointPSVC.y); 
     CGContextStrokePath(UIGraphicsGetCurrentContext()); 
     CGContextFlush(UIGraphicsGetCurrentContext()); 
     drawImageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

    } 

} 

Я хотел бы добавить, что этот код работает отлично, если UIView не увеличены или прокручивается на. Кроме того, sheetDrawView является поднабором UIScrollView.

+0

Примените AffineTransform, чтобы масштабировать вид так же, как и масштаб scrollView. Затем попробуйте рисовать? – Brandon

+0

Звучит неплохо. Можете ли вы предоставить примерный код для AffineTransform, с которым я могу работать, и я буду рад попробовать? – user2621075

ответ

1

Создано небольшое приложение для рисования (тестируется только на iPhone 7 Plus 10.1 Simulator).

enter image description here

Сначала я создал PalleteView. Этот вид позволяет вам выбирать цвета для рисования.

PaletteView.h:

// 
// PaletteView.h 
// DrawingIO 
// 
// Created by Brandon T on 2016-11-27. 
// Copyright © 2016 XIO. All rights reserved. 
// 

#import <UIKit/UIKit.h> 

@class PaletteView; 

@protocol PaletteViewDelegate <NSObject> 
- (void)didSelectColour:(PaletteView * _Nonnull)paletteView colour:(UIColor * _Nonnull)colour; 
@end 

@interface PaletteView : UIView 
@property (nullable, nonatomic, weak) id<PaletteViewDelegate> delegate; 
@end 

PaletteView.m:

// 
// PaletteView.m 
// DrawingIO 
// 
// Created by Brandon T on 2016-11-27. 
// Copyright © 2016 XIO. All rights reserved. 
// 

#import "PaletteView.h" 

#define kPaletteViewCell @"kPaletteViewCell" 

@interface PaletteView() <UICollectionViewDelegate, UICollectionViewDataSource> 
@property (nonnull, nonatomic, strong) UICollectionView *collectionView; 
@property (nonnull, nonatomic, strong) NSArray<NSArray<UIColor *> *> *colours; 
@end 

@implementation PaletteView 
- (instancetype)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     [self initControls]; 
     [self setTheme]; 
     [self registerClasses]; 
     [self doLayout]; 
    } 
    return self; 
} 

- (void)initControls { 

    CGFloat idealWidth = (self.frame.size.width/7.0) - (2.5 * 5.0); 
    CGFloat idealHeight = (self.frame.size.height/2.0) - (2.5 * 5.0); 

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 
    layout.minimumLineSpacing = 5.0; 
    layout.minimumInteritemSpacing = 5.0; 
    layout.sectionInset = UIEdgeInsetsMake(5.0, 5.0, 5.0, 5.0); 
    layout.scrollDirection = UICollectionViewScrollDirectionVertical; 
    layout.itemSize = CGSizeMake(idealWidth, idealHeight); 

    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; 

    self.colours = @[@[[UIColor blackColor], 
        [UIColor darkGrayColor], 
        [UIColor lightGrayColor], 
        [UIColor whiteColor], 
        [UIColor grayColor], 
        [UIColor redColor], 
        [UIColor greenColor]], 

        @[[UIColor blueColor], 
        [UIColor cyanColor], 
        [UIColor yellowColor], 
        [UIColor magentaColor], 
        [UIColor orangeColor], 
        [UIColor purpleColor], 
        [UIColor brownColor]]]; 
} 

- (void)setTheme { 
    [self.collectionView setDelegate:self]; 
    [self.collectionView setDataSource:self]; 
    [self.collectionView setAlwaysBounceHorizontal:YES]; 
    [self.collectionView setDelaysContentTouches:NO]; 
    [self.collectionView setShowsHorizontalScrollIndicator:NO]; 
    [self.collectionView setShowsVerticalScrollIndicator:NO]; 
    [self.collectionView setBackgroundColor:[UIColor colorWithRed:240.0/255.0 green:229.0/255.0 blue:227.0/255.0 alpha:1.0]]; 
} 

- (void)registerClasses { 
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kPaletteViewCell]; 
} 

- (void)doLayout { 
    [self addSubview:self.collectionView]; 

    [self.collectionView.leftAnchor constraintEqualToAnchor:self.leftAnchor].active = YES; 
    [self.collectionView.rightAnchor constraintEqualToAnchor:self.rightAnchor].active = YES; 
    [self.collectionView.topAnchor constraintEqualToAnchor:self.topAnchor].active = YES; 
    [self.collectionView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor].active = YES; 

    [self.collectionView setTranslatesAutoresizingMaskIntoConstraints:NO]; 
} 

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 
    return self.colours.count; //Two rows of colours. 
} 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 
    return [self.colours[section] count]; //7 colours per row in this example. 
} 

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kPaletteViewCell forIndexPath:indexPath]; 

    NSArray *section = [self.colours objectAtIndex:indexPath.section]; 
    [cell.contentView setBackgroundColor:section[indexPath.row]]; 

    return cell; 
} 

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    if ([self.delegate respondsToSelector:@selector(didSelectColour:colour:)]) { 
     NSArray *section = [self.colours objectAtIndex:indexPath.section]; 
     [self.delegate didSelectColour:self colour:section[indexPath.row]]; 
    } 
} 
@end 

Это простой CollectionView с каждой ячейкой быть окрашена. Я жестко закодировал размеры ячеек.

Далее я создал DrawingView. Это представление, которое пользователь будет использовать, используя свой палец. Это представление обрабатывает только один палец во временном чертеже. Сначала я подумал о том, чтобы рисовать в Bitmap из GameDesign. В играх вы хотите сначала нарисовать текстуры в памяти. Затем, когда вы закончите делать все свои чертежи, вы нажмете этот кадр на экран. Это значительно улучшает скорость, потому что вы не обновляете экран после КАЖДОЙ операции. Вместо этого вы обновляете экран в конце всего чертежа (когда пользователь поднимает палец).

Для достижения этой цели, я сделал следующее:

DrawingView.h:

// 
// DrawingView.h 
// DrawingIO 
// 
// Created by Brandon T on 2016-11-27. 
// Copyright © 2016 XIO. All rights reserved. 
// 

#import <UIKit/UIKit.h> 

@interface DrawingView : UIView 
- (void)setPaletteColour:(UIColor * _Nonnull)colour; 
@end 

DrawingView.m:

// 
// DrawingView.m 
// DrawingIO 
// 
// Created by Brandon T on 2016-11-27. 
// Copyright © 2016 XIO. All rights reserved. 
// 

#import "DrawingView.h" 

@interface DrawingView() 
@property (nonnull, nonatomic, strong) UIBezierPath *path; 
@property (nonnull, nonatomic, strong) UIImage *bufferedImage; 
@property (nonnull, nonatomic, strong) UIColor *strokeColour; 
@end 

@implementation DrawingView 

- (instancetype)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 

     [self setPath:[UIBezierPath bezierPath]]; 
     [self.path setLineWidth:1.0]; 

     [self setStrokeColour:[UIColor blackColor]]; 
     [self setMultipleTouchEnabled:NO]; 
    } 
    return self; 
} 

- (void)setPaletteColour:(UIColor *)colour { 
    self.strokeColour = colour; 
} 

- (void)renderToBufferedImage { 
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0); 

    [self.strokeColour setStroke]; 
    [self.bufferedImage drawAtPoint:CGPointZero]; 
    [self.path stroke]; 

    self.bufferedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
} 



- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    [self.path moveToPoint:[touch locationInView:self]]; 
} 

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    [self.path addLineToPoint:[touch locationInView:self]]; 
    [self setNeedsDisplay]; 
} 

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    [self.path addLineToPoint:[touch locationInView:self]]; 
    [self renderToBufferedImage]; 
    [self setNeedsDisplay]; 
    [self.path removeAllPoints]; 
} 

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    [self.path addLineToPoint:[touch locationInView:self]]; 
    [self renderToBufferedImage]; 
    [self setNeedsDisplay]; 
    [self.path removeAllPoints]; 
} 

- (void)drawRect:(CGRect)rect { 
    [self.strokeColour setStroke]; 
    [self.bufferedImage drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0]; 
    [self.path stroke]; 
} 

@end 

Я решил использовать drawInRect:blendMode:alpha потому, что позволит вам рисовать с различными вариантами смешивания и альфа-уровнями. В этом примере я рисую полностью непрозрачные 32-битные растровые изображения BGRA.

Далее я создал контроллер со встроенным ScrollView. Это позволяет пользователю ZOOM-IN/Масштабировать представление и нарисовать увеличенный/масштабированный вид. Когда вы увеличите масштаб изображения, вы увидите, что рисунок является точным (не искаженным или масштабированным).

ViewController.h:

// 
// ViewController.h 
// DrawingIO 
// 
// Created by Brandon T on 2016-11-27. 
// Copyright © 2016 XIO. All rights reserved. 
// 

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController 


@end 

ViewController.м:

// 
// ViewController.m 
// DrawingIO 
// 
// Created by Brandon T on 2016-11-27. 
// Copyright © 2016 XIO. All rights reserved. 
// 

#import "ViewController.h" 
#import "PaletteView.h" 
#import "DrawingView.h" 

@interface ViewController() <UIScrollViewDelegate, PaletteViewDelegate> 
@property (nonnull, nonatomic, strong) PaletteView *paletteView; 
@property (nonnull, nonatomic, strong) DrawingView *drawingView; 
@property (nonnull, nonatomic, strong) UIScrollView *scrollView; 
@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    [self initControls]; 
    [self setTheme]; 
    [self doLayout]; 
} 


- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 


- (void)initControls { 
    self.paletteView = [[PaletteView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, 100.0)]; 
    self.drawingView = [[DrawingView alloc] initWithFrame:self.view.frame]; 
    self.scrollView = [[UIScrollView alloc] init]; 
} 

- (void)setTheme { 
    [self.paletteView setDelegate:self]; 
    [self.paletteView setBackgroundColor:[UIColor whiteColor]]; 
    [self.drawingView setBackgroundColor:[UIColor whiteColor]]; 

    [self.scrollView setDelegate:self]; 
    [self.scrollView setScrollEnabled:NO]; 
    [self.scrollView setMinimumZoomScale:1.0]; 
    [self.scrollView setMaximumZoomScale:2.0]; 
} 

- (void)doLayout { 
    [self.view addSubview:self.paletteView]; 
    [self.view addSubview:self.scrollView]; 

    [self.paletteView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES; 
    [self.paletteView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES; 
    [self.paletteView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES; 

    [self.scrollView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES; 
    [self.scrollView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES; 
    [self.scrollView.topAnchor constraintEqualToAnchor:self.paletteView.bottomAnchor].active = YES; 
    [self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES; 

    [self.scrollView setTranslatesAutoresizingMaskIntoConstraints:NO]; 


    //Layout drawingView 
    [self.scrollView addSubview:self.drawingView]; 
} 

- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 
    return self.drawingView; 
} 

- (void)didSelectColour:(PaletteView * _Nonnull)paletteView colour:(UIColor * _Nonnull)colour { 
    [self.drawingView setPaletteColour:colour]; 
} 
@end 
+0

Я работаю через ваш пример здесь. Не возражаете ли вы пересмотреть свой ответ, исключив представление поддонов, поскольку у меня уже есть метод выбора цвета. Я также повесил трубку, когда добавляю UIView-c-файл с именем drawView. Я продолжаю получать ошибку, нет видимой. Интерфейс для «UIResponder» объявляет селектор «initWithFrame». То же самое, если я добавлю код в мой UIViewcontroller.m - нет видимого ATinterface для «UIViewController» объявляет селектор «initWithFrame». – user2621075

+0

Этот код должен быть как есть. Если вы хотите поменять папку palletView самостоятельно, вы можете заменить ее и заменить делегата своим собственным. Что касается вопроса UIResponder. У вас есть сильная ссылка на представление как UIResponder. UIView уже соответствует UIResponder, поэтому нет необходимости хранить его как UIResponder. – Brandon

+0

Осталось два вопроса. Строки черные, будучи нарисованы. Как я могу изменить это на другой цвет? Нарисованные линии размыты вокруг краев при увеличении. Как я могу сделать эту строку более четкой/чистой? – user2621075

 Смежные вопросы

  • Нет связанных вопросов^_^