在两个可移动uiview之间画线 [英] Draw line between two movable uiviews

查看:70
本文介绍了在两个可移动uiview之间画线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个滚动视图",其中的节点(UIViews)可以拖动.我正在尝试使用"calayer"在选定的UIViews之间绘制边缘,但是当视图位置更改时,我无法弄清楚如何重绘该线.

I have a "scrollview" with nodes (UIViews) that can be dragged around. I am trying to draw edges between selected UIViews with a "calayer", but I can't figure out how to redraw the line when a views position have changed.

在我的viewController类中,我将节点数组的第一条和第二条之间的边添加为:

In my viewController class I add the edge between first and second in the nodes array as:

EdgeLayer *edge = [[EdgeLayer alloc]init];
edge.delegate = self;
edge.strokeColor = [UIColor colorWithWhite:0.25 alpha:1.0];
edge.strokeWidth = 0.5;
edge.startNode = [nodes objectAtIndex:0];
edge.endNode = [nodes objectAtIndex:1];
edge.frame = scrollView.bounds;
[scrollView.layer addSublayer:edge];
[edge setNeedsDisplay];

EdgeLayer.h:

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface EdgeLayer : CALayer
@property (nonatomic, strong) UIColor *fillColor;
@property (nonatomic) CGFloat strokeWidth;
@property (nonatomic, strong) UIColor *strokeColor;
@property (nonatomic) UIView *startNode;
@property (nonatomic) UIView *endNode;
@end

EdgeLayer.m:

#import "EdgeLayer.h"
#import "NodeView.h"

@implementation EdgeLayer

@synthesize fillColor, strokeColor, strokeWidth;
- (id)init {
    self = [super init];
    if (self) {
    self.fillColor = [UIColor grayColor];
    self.strokeColor = [UIColor blackColor];
    self.strokeWidth = 1.0;
    [self setNeedsDisplay];
}

return self;
}

- (void) setStartNode:(NodeView*)startNode
{
     _startNode = startNode;
     [self setNeedsDisplay];
}

- (void) setEndNode:(NodeView*)endNode
{
    _endNode = endNode;
    [endNode addObserver:self forKeyPath:@"endNode" options:NSKeyValueObservingOptionNew context:nil];
    [self setNeedsDisplay];
 }

-(id)initWithLayer:(id)layer
{
    self = [super initWithLayer:layer];
    return self;
}

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:    (NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"endNode"] )
    {
    // process here
    }
    NSLog(@"View changed its geometry");
}

- (void)drawInContext:(CGContextRef)ctx
{
    NSLog(@"DRAW");

    CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(ctx, 2);
    CGContextMoveToPoint(ctx, _startNode.center.x, _startNode.center.y);
    CGContextAddLineToPoint(ctx, _endNode.center.x, _endNode.center.y);
    CGContextStrokePath(ctx);
}
@end

这将从第一和第二节点的中心位置开始添加一条线.我试图为终端节点添加观察者,但是我认为我做的不正确.我无法触发observeValueForKeyPath方法.我的猜测是我在错误的位置添加了观察者.

This adds a line from the first and second nodes center position. I have tried to add an observer for the end node, but I don't think that I'm doing it right. I can't trigger the observeValueForKeyPath method. My guess is that I added the observer in the wrong place.

推荐答案

问题不在于您添加观察者的位置,而是您想要观察的东西-您将endNode用作endNode上的keyPath,这将不会无法正常工作(无论如何拖动,endNode都不会改变).您要观察的endNode属性是中心.

The problem is not where you add the observer, but what you're tying to observe -- you're using endNode as the keyPath on endNode which won't work (endNode isn't changing as you drag anyway). The property of endNode that you want to observe is the center.

然后您只需要将要观察的keyPath更改为居中",并像这样就更改您对watchValueForKeyPath:ofObject:change:context:的实现,

You only then need to change the keyPath you're observing to "center", and change your implementation of observeValueForKeyPath:ofObject:change:context: like so,

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"center"] ) [self setNeedsDisplay];
}

我通过向其中一个nodeViews中添加一个摇摄手势识别器进行了测试,并在拖动时适当地更新了连接两个节点的线.

I tested this by adding a pan gesture recognizer to one of the nodeViews, and the line connecting the two nodes was updated appropriately as I dragged.

这篇关于在两个可移动uiview之间画线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆