#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