iOS在触摸端点上调整大小或重新定位线

Dav*_*ave 4 objective-c ios

我试图通过触摸红色圆点来调整线条的大小.让我们说,我想在下图中将这条线移到嘴唇上方,我怎样才能实现这一点.线路没有从位置移动.我刚刚开始使用这个东西,找不到相关的资源来完成这个任务.尽力而为......请指导我正确的方向.下面是我的代码和参考图像.

目标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];

}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

编辑: 场景是,在任何给定时间屏幕上都会有一些灵活的线路.让我们说点击按钮,屏幕上会添加一行新线.用户可以拖动任何端点以在任何方向上调整线的大小.我无法正常工作......没有运气.

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

谢谢!

ndm*_*iri 6

我之前的一个答案可以扩展到包括您尝试实现的功能.您需要实现两个类:LineViewLineImageView.

在我们开始之前,先看一下完成的演示的动画GIF.

请注意,"添加行"按钮已添加到故事板中,而不是图像视图的子视图.创建您的按钮,设置它的样式,然后将其连接到IBAction该调用[self.lineImageView addLineView].

UIViewController子类实现

#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
Run Code Online (Sandbox Code Playgroud)

LineView接口

#import <UIKit/UIKit.h>

@interface LineView : UIView

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

@end
Run Code Online (Sandbox Code Playgroud)

LineView实现

#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;
}
Run Code Online (Sandbox Code Playgroud)

LineImageView接口

#import <UIKit/UIKit.h>

@interface LineImageView : UIImageView

- (void)addLineView;

@end
Run Code Online (Sandbox Code Playgroud)

LineImageView实现

#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];
}
Run Code Online (Sandbox Code Playgroud)