iOS在拖动端点时调整或重新定位直线

iOS在拖动端点时调整或重新定位直线,ios,objective-c,Ios,Objective C,我试图通过触摸红色圆圈点来调整线的大小。比方说,我想把这条线移到下图中嘴唇上方,我如何才能做到这一点。线没有从该位置移动。我刚刚开始做这件事,找不到太多相关的资源来完成这件事。尽最大努力…请给我指引正确的方向。下面是我的代码和参考图片 目标c代码: - (void)viewDidLoad { [super viewDidLoad]; UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100

我试图通过触摸红色圆圈点来调整线的大小。比方说,我想把这条线移到下图中嘴唇上方,我如何才能做到这一点。线没有从该位置移动。我刚刚开始做这件事,找不到太多相关的资源来完成这件事。尽最大努力…请给我指引正确的方向。下面是我的代码和参考图片

目标c代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:10 startAngle:0 endAngle:6.2831853 clockwise:TRUE];
    
    //Add second circle
    [path moveToPoint:CGPointMake(100.0, 100.0)];
    [path addLineToPoint:CGPointMake(200, 200)];
    [path moveToPoint:CGPointMake(200, 200)];
    
    [path addArcWithCenter:CGPointMake(200, 200) radius:10 startAngle:0 endAngle:6.2831853 clockwise:TRUE];

    
    [path closePath];
    [[UIColor redColor] setStroke];
    [[UIColor redColor] setFill];
    [path stroke];
    [path fill];
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = [path CGPath];
    shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
    shapeLayer.lineWidth = 2.0;
    shapeLayer.fillColor = [[UIColor redColor] CGColor];
    
    [self.view.layer addSublayer:shapeLayer];
    
}

我将添加多条像这样的线,我的最终目标是在图像中的任何位置移动单独的线,并使用线大小测量该区域

编辑: 场景是,在任何给定的时间,屏幕上都会出现一些灵活的行。比如说,点击按钮,屏幕上会增加一行新内容。用户只需拖动任意端点即可在任意方向上调整线的大小。我不能让这东西正常工作。。不走运

这是我的要点文件链接, 它基本上添加了一个UIView来创建图像上的线条。gist中的代码允许我通过上下移动触摸点来调整线条高度,但不允许我旋转线条角度并在中心添加文本。 谢谢


谢谢

在imageView中添加两个按钮

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(imageTouch:withEvent:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[button setImage:[UIImage imageNamed:@"circle.png"] forState:UIControlStateNormal];
[self.view addSubview:button];
采取行动

    - (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
    {
        CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
        UIControl *control = sender;
        control.center = point;
        // redraw line on movement
        [self drawLine];
    }
在这两个按钮之间画一条线。这种方法可以很容易地帮助您计算接触点和线路长度

- (void)drawLine
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]);
    CGContextSetLineWidth(context, 3.0);
    CGContextMoveToPoint(context, button1.frame.origin.x, button1.frame.origin.y);
    CGContextAddLineToPoint(context, button2.frame.origin.x, button2.frame.origin.y);
    CGContextDrawPath(context, kCGPathStroke);
}
可以扩展以包括您尝试实现的功能。您需要实现两个类:
LineView
LineImageView

在我们开始之前,看一下这个动画gif的完成演示。

请注意,“添加线”按钮是在情节提要中添加的,不是图像视图的子视图。创建按钮,设置其样式,然后将其连接到调用
[self.lineImageView addLineView]
iAction

UIViewController子类实现 LineView界面
是否希望每次移动一个端点?或者两者同时进行?不幸的是,它必须通过在线上触摸任何端点来一次移动一个。。。这篇帖子很老,也没有人回复。。仍然坚持使用此功能。。它不应该使用多点触摸,因为要求:)听起来不错。我看看明天能做些什么。你们正在寻找一种方法,使每张图片上有多行,对吗?是的,图片上有多行。。每条线只有两个点。Thnx。。我正在朝着这个方向努力,如果我成功了,我也会把答案贴在这里:)这条线需要弯曲吗?
#import "ViewController.h"
#import "LineImageView.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet LineImageView *lineImageView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)addLineTapped:(UIButton *)sender
{
    [self.lineImageView addLineView];
}

@end
#import <UIKit/UIKit.h>

@interface LineView : UIView

@property (nonatomic) CGPoint startPoint;
@property (nonatomic) CGPoint endPoint;
@property (nonatomic) CGFloat circleRadius; // defaults to 30.0

@end
#import "LineView.h"

@interface LineView ()

@property (nonatomic) BOOL startPointTracking;
@property (nonatomic) BOOL endPointTracking;

@end

@implementation LineView

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
        self.startPoint = [self randomPointInBounds];
        self.endPoint = [self randomPointInBounds];
        [self setNeedsDisplay];
    }
    return self;
}

- (void)setup
{
    self.backgroundColor = [UIColor clearColor];
    self.multipleTouchEnabled = false; // multi-touch is not allowed
    self.circleRadius = 30.0;
}

#pragma mark - Touch handling

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];

    if ([self pointIsOnStartCircle:location]) {
        self.startPointTracking = YES;
        self.endPointTracking = NO;
    } else if ([self pointIsOnEndCircle:location]) {
        self.startPointTracking = NO;
        self.endPointTracking = YES;
    }

    [self updatePointsWithTouches:touches];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self updatePointsWithTouches:touches];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.startPointTracking = NO;
    self.endPointTracking = NO;
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.startPointTracking = NO;
    self.endPointTracking = NO;
}

- (void)updatePointsWithTouches:(NSSet *)touches
{
    UITouch *touch = [touches anyObject];

    if (self.startPointTracking) {
        self.startPoint = [touch locationInView:self];
        [self setNeedsDisplay];

    } else if (self.endPointTracking) {
        self.endPoint = [touch locationInView:self];
        [self setNeedsDisplay];
    }
}

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event
{
    return [self pointIsOnStartCircle:point] || [self pointIsOnEndCircle:point];
}

#pragma mark - Drawing

- (void)drawRect:(CGRect)rect
{
    if ([self isHidden]) { return; }

    [self drawTouchCircleAtPoint:self.startPoint];
    [self drawTouchCircleAtPoint:self.endPoint];
    [self drawLineBetweenFirstPoint:self.startPoint end:self.endPoint];
    [self drawDistanceText];
}

- (void)drawLineBetweenFirstPoint:(CGPoint)startPoint end:(CGPoint)endPoint
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetStrokeColorWithColor(context, [[[UIColor whiteColor] colorWithAlphaComponent:0.6] CGColor]);
    CGContextSetLineWidth(context, 1.0);

    CGContextMoveToPoint(context, startPoint.x, startPoint.y);
    CGContextAddLineToPoint(context, endPoint.x, endPoint.y);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
}

- (void)drawTouchCircleAtPoint:(CGPoint)CirclePoint
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetLineWidth(context, 2.0);
    CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.6);

    CGContextAddArc(context, CirclePoint.x, CirclePoint.y, self.circleRadius, 30.0,  M_PI * 2, YES);
    CGContextFillPath(context);
    CGContextRestoreGState(context);
}

- (void)drawDistanceText
{
    CGPoint midpoint = [self midpointBetweenFirstPoint:self.startPoint secondPoint:self.endPoint];

    UIFont *font = [UIFont boldSystemFontOfSize:18.0];
    UIColor *textColor = [UIColor whiteColor];
    NSDictionary *attributes = @{NSFontAttributeName : font, NSForegroundColorAttributeName : textColor};
    NSString *distanceString = [self formattedDistanceString];

    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:distanceString attributes:attributes];

    [attributedString drawAtPoint:midpoint];
}

#pragma mark - Helper methods

- (CGPoint)randomPointInBounds
{
    int x = arc4random() % (int)CGRectGetWidth(self.bounds);
    int y = arc4random() % (int)CGRectGetHeight(self.bounds);
    return CGPointMake(x, y);
}

- (CGFloat)distanceFromPoint:(CGPoint)p1 toPoint:(CGPoint)p2
{
    CGFloat xDist = p2.x - p1.x;
    CGFloat yDist = p2.y - p1.y;
    return sqrt((xDist * xDist) + (yDist * yDist));
}

- (CGPoint)midpointBetweenFirstPoint:(CGPoint)p1 secondPoint:(CGPoint)p2
{
    CGFloat x = (p1.x + p2.x) / 2.0;
    CGFloat y = (p1.y + p2.y) / 2.0;
    return CGPointMake(x, y);
}

- (BOOL)pointIsOnStartCircle:(CGPoint)point
{
    CGFloat distance = [self distanceFromPoint:point toPoint:self.startPoint];
    return distance <= self.circleRadius;
}

- (BOOL)pointIsOnEndCircle:(CGPoint)point
{
    CGFloat distance = [self distanceFromPoint:point toPoint:self.endPoint];
    return distance <= self.circleRadius;
}

- (NSString *)formattedDistanceString
{
    CGFloat distance = [self distanceFromPoint:self.startPoint toPoint:self.endPoint];
    NSNumberFormatter *formatter = [[self class] sharedFormatter];
    return [formatter stringFromNumber:@(distance)];
}

+ (NSNumberFormatter *)sharedFormatter
{
    static NSNumberFormatter *sharedFormatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedFormatter = [[NSNumberFormatter alloc] init];
    });
    return sharedFormatter;
}
#import <UIKit/UIKit.h>

@interface LineImageView : UIImageView

- (void)addLineView;

@end
#import "LineImageView.h"
#import "LineView.h"

@interface LineImageView ()

@property (nonatomic, strong) NSMutableArray *lineViews; // of LineView

@end

@implementation LineImageView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup
{
    self.userInteractionEnabled = YES;
}

- (void)addLineView
{
    LineView *lineView = [[LineView alloc] initWithFrame:self.bounds];
    [self addSubview:lineView];
    [self.lineViews addObject:lineView];
}