Рисование и обновление линии между двумя изображениями

#ios #objective-c

#iOS #objective-c

Вопрос:

В настоящее время у меня есть два UIImageViews, которые можно перетаскивать, чтобы перемещать их по экрану:

 - (void)panWasRecognized:(UIPanGestureRecognizer *)panner {
    UIView *draggedView = panner.view;
    CGPoint offset = [panner translationInView:draggedView.superview];
    CGPoint center = draggedView.center;
    draggedView.center = CGPointMake(center.x   offset.x, center.y   offset.y);
    [panner setTranslation:CGPointZero inView:draggedView.superview];
}

- (void)panWasRecognized2:(UIPanGestureRecognizer *)panner2 {
    UIView *draggedView = panner2.view;
    CGPoint offset = [panner2 translationInView:draggedView.superview];
    CGPoint center = draggedView.center;
    draggedView.center = CGPointMake(center.x   offset.x, center.y   offset.y);
    [panner2 setTranslation:CGPointZero inView:draggedView.superview];
}
  

Однако я не был уверен, как я буду делать следующий шаг, который должен был заключаться в рисовании линии между двумя центрами UIImageViews, которые постоянно обновляются по мере перемещения изображений пользователем. Я примерно знаю, как нарисовать простую линию от точки к точке, но кто-нибудь может предложить, как постоянно обновлять эту линию синхронно с движением двух изображений? Заранее спасибо 🙂

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

1. Ну, это зависит от того, где вы выполняете рисование; я предполагаю, что родительский вид UIImageViews ? В этом случае вы можете просто указать виду перерисовать с помощью setNeedsDisplay (или setNeedsDisplayInRect: ), а затем реализовать рисунок в drawRect: .

2. Вам нужна соединительная линия от одного центра изображения к другому?

3. Да, это просто линия, протянувшаяся от центра первого изображения ко второму изображению, которая может перемещаться в соответствии с положением любого изображения

Ответ №1:

Вы можете легко сделать это, создав родительский класс UIView . Просто создайте класс и скопируйте-вставьте код для

DrawView.h

 #import <UIKit/UIKit.h>

@interface DrawView : UIView
-(void)refreshWithPointA:(CGPoint)pointA andPointB:(CGPoint)pointB;
@end
  

DrawView.m

 #import "DrawView.h"

@interface DrawView()
@property(nonatomic, strong) UIBezierPath *linePath;
@end

@implementation DrawView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}



-(void)refreshWithPointA:(CGPoint)pointA andPointB:(CGPoint)pointB{
    _linePath = [UIBezierPath bezierPath];
    [_linePath setLineWidth:2.0];
    [_linePath moveToPoint:pointA];
    [_linePath addLineToPoint:pointB];
    [self setNeedsDisplay];
}


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{

    // Drawing code
    [[UIColor blackColor] setStroke];
    [_linePath stroke];
}


@end
  

Теперь просто измените родительский класс UIView, к которому вы добавили UIImageView . И назначьте тег 1 и 2 двум представлениям изображений. И используйте приведенный ниже метод в своем pangesture selectors

 -(void)refreshLine{
    CGPoint centreA=[self.view viewWithTag:1].center;
    CGPoint centreB=[self.view viewWithTag:2].center;
    [self.drawView refreshWithPointA:centreA andPointB:centreB];
}
  

Поместите метод в последнюю строку обоих устройств распознавания жестов, как показано ниже

 - (void)panWasRecognized:(UIPanGestureRecognizer *)panner {
     //YOUR OLD CODE

     [self refreshLine];
}

- (void)panWasRecognized2:(UIPanGestureRecognizer *)panner {

     //YOUR OLD CODE

     [self refreshLine];
}
  

а также там, где вы добавляете UIImageViews, он сразу же нарисует линии. Создайте также IBOutlet свое UIView изображение с присвоенным новым классом.

Вот и все.

Приветствия.

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

1. Большое спасибо за ваш ответ. Я понимаю большую часть вашего кода, но у меня есть несколько вопросов — во-первых, после размещения кода в моих файлах .h и .m я получил сообщение об ошибке «нет видимого @интерфейса для … объявляет селектор …» как для initWithFrame, так и для setNeedsDisplay. Кроме того, я не уверен, что вы имеете в виду, назначая теги ImageViews и изменяя родительский класс UIView. Извините, если эти вопросы кажутся примитивными, я довольно новичок в программировании 🙂

2. на самом деле я, кажется, решил большинство ошибок. Единственное, что сейчас не работает, — это DrawView, и я не уверен насчет части IBOutlet.

3. Вам нужно создать выход представления, для которого вы изменили класс, чтобы получить доступ к методу DrawView. Смотрите здесь, что я имею в виду db.tt/TD5n3iYY

4. ах, я вижу, это то, что у меня есть на данный момент: oi61.tinypic.com/15yw7ys.jpg . Я предполагаю, что мне нужно создать подкласс UIView, так как же мне это сделать?

5. Вам просто нужно скопировать и вставить приведенный выше код для DrawView и изменить класс представления в раскадровке способом, описанным здесь 1.bp.blogspot.com/-cRzY33W3ofc/TzOfObr1rII/AAAAAAAAAaY /…

Ответ №2:

Например, вы можете сделать это, создав подкласс для UIView и переопределив drawRect пример кода метода, в subclassed UIView вы можете сделать что-то вроде приведенного ниже

 #import "MyView.h"

@implementation MyView

- (id)initWithFrame:(CGRect)frame
 {
    self = [super initWithFrame:frame];
    if (self) {
     // Initialization code
     UIImageView *imgViewOne = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
     imgViewOne.backgroundColor = [UIColor greenColor]; //imageview 1

     UIImageView *imgViewTwo = [[UIImageView alloc]initWithFrame:CGRectMake(200, 0, 100, 100)];
     imgViewTwo.backgroundColor = [UIColor redColor]; //imageview 2

     UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panWasRecognized:)];
     [imgViewOne addGestureRecognizer:panGesture];

     UIPanGestureRecognizer *panGesture2 = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panWasRecognized2:)];
     [imgViewTwo addGestureRecognizer:panGesture2];

     imgViewOne.tag = 100;
     imgViewTwo.tag = 200;

     imgViewTwo.userInteractionEnabled = YES;
     imgViewOne.userInteractionEnabled = YES;

     [self addSubview:imgViewOne];
     [self addSubview:imgViewTwo];

  }
  return self;
}


- (void)panWasRecognized:(UIPanGestureRecognizer *)panner
{
   UIView *draggedView = panner.view;
   CGPoint offset = [panner translationInView:draggedView.superview];
   CGPoint center = draggedView.center;
   draggedView.center = CGPointMake(center.x   offset.x, center.y   offset.y);
   [panner setTranslation:CGPointZero inView:draggedView.superview];
   [self setNeedsDisplay];//update the drawing
}

- (void)panWasRecognized2:(UIPanGestureRecognizer *)panner2
{
   UIView *draggedView = panner2.view;
   CGPoint offset = [panner2 translationInView:draggedView.superview];
   CGPoint center = draggedView.center;
   draggedView.center = CGPointMake(center.x   offset.x, center.y   offset.y);
   [panner2 setTranslation:CGPointZero inView:draggedView.superview];
   [self setNeedsDisplay]; //update the drawing

}

// Only override drawRect: if you perform custom drawing.  
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
 {
   CGContextRef context = UIGraphicsGetCurrentContext();
   CGContextClearRect(context, self.bounds);//clear drawing

   UIImageView *imgView1 = (UIImageView *)[self viewWithTag:100];
   UIImageView *imgView2 = (UIImageView *)[self viewWithTag:200];

   CGPoint center1 = imgView1.center;
   CGPoint center2 = imgView2.center;

   CGContextSetFillColorWithColor(context,[UIColor whiteColor].CGColor);//set background white color
   CGContextFillRect(context, self.bounds);


   CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); //set the color of the line
   CGContextSetLineWidth(context, 0.5); //set width of line

   CGContextMoveToPoint(context, center1.x,center1.y); //start at this point
   CGContextAddLineToPoint(context, center2.x,center2.y); //draw to this point

   CGContextClosePath(context);
   CGContextStrokePath(context);
 }


 @end
  

в контроллере представления просто добавьте этот вид

  #import "MyView.h" //import this custom view


 - (void)viewDidLoad
   {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    MyView *view = [[MyView alloc]initWithFrame:self.view.bounds];
    [self.view addSubview:view]; //add it to view controller's view
   }
  

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

1. Есть ли способ заставить это работать на уже установленном UIViewController вместо создания нового представления поверх него (например, используя UIImageViews в контроллере вместо их программной инициализации). Вот что у меня есть сейчас: oi60.tinypic.com/ezn7ev.jpg но мне это нужно для работы на одном слое с oi61.tinypic.com/15yw7ys.jpg