我有一个“ ScrollView ”,其中包含可以拖动的节点 (UIViews)。我正在尝试使用“calayer”在选定的 UIViews 之间绘制边缘,但我不知道如何在 View 位置发生变化时重新绘制线条。
在我的 viewController 类中,我在节点数组中添加了第一个和第二个之间的边:
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 方法。我的猜测是我在错误的地方添加了观察者。
最佳答案
问题不在于您添加观察者的位置,而在于您要观察什么——您将 endNode 用作 endNode 上的 keyPath,这是行不通的(endNode 不会随着您的拖动而改变)。您要观察的 endNode 的属性是中心。
然后您只需要将您正在观察的 keyPath 更改为“中心”,并像这样更改 observeValueForKeyPath:ofObject:change:context: 的实现,
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"center"] ) [self setNeedsDisplay];
}
我通过向其中一个节点 View 添加平移手势识别器来对此进行测试,并且在我拖动时连接两个节点的线会适当更新。
关于ios - 在两个可移动的 uiview 之间画线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23748451/
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里