我有一个LineView
类,显示两点之间的一条线。 LineView
基本上只是一个矩形视图,thickness
代表高度,其startPoint
和endPoint
的位置决定了矩形的宽度以及我的旋转将(使用CGAffineTransform
)应用于矩形。
@interface LineView : UIView
@property (nonatomic) float thickness;
@property (nonatomic, strong) (PointView *)startPoint;
@property (nonatomic, strong) (PointView *)endPoint;
PointView
类定义屏幕上的移动点。由于我希望始终在其起点和终点之间显示该行,因此我LineView
会观察center
和startPoint
的{{1}}属性},像这样:
endPoint
和- (void)setStartPoint:(PointView *)startPoint
{
// Un-observe previous startPoint
[_startPoint removeObserver:self forKeyPath:@"center"];
_startPoint = startPoint;
// Observe new startPoint
[_startPoint addObserver:self forKeyPath:@"center" options:0 context:nil];
[self updateLine];
}
的定义相似。因此,每当(void)setEndPoint:(PointView *)endPoint
属性发生更改时,我都要更新该行:
center
这里- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (![keyPath isEqualToString:@"center"])
{
return;
}
if (object == self.startPoint || object == self.endPoint)
{
[self updateLine];
}
}
(void)updateLine:
- (void)updateLine
{
CGPoint startPoint = self.startPoint.center;
CGPoint endPoint = self.endPoint.center;
// tangent vector
CGPoint tangent = cgpSubtract(endPoint, startPoint);
// determine the angle of the tangent vector
float angle = cgpAngle(tangent);
// determine the length of the tangent vector
float length = cgpLength(tangent);
// frame is undefined when transform is not identity
self.transform = CGAffineTransformIdentity;
// set frame.origin to startPoint, and frame.size to length and thickness
self.frame = CGRectMake(startPoint.x, startPoint.y, length, self.thickness);
// rotate the view so that the line properly connects startPoint and endPoint
self.transform = CGAffineTransformMakeRotation(angle);
[self setNeedsDisplay];
}
函数只是我定义为执行简单cgp
数学运算的静态方法。
因此,只要CGPoint
或startPoint
在屏幕上移动,endPoint
属性会更改移动点,center
会观察到此更改并调用{ {1}}更新自己。
现在让我们说随着时间的推移我们会在屏幕上移动LineView
和updateLine
。实际上,我们有一个startPoint
类,其中包含endPoint
属性:
Timeline
并且currentTime
类设置为观察此@interface Timeline : NSObject
@property (nonatomic) float currentTime;
...
属性,并在PointView
更改时更改其currentTime
位置。
通过这种方式,center
取决于currentTime
,而PointView
取决于两个Timeline
,但LineView
不依赖于PointView
1}}。它不需要知道LineView
是什么,它需要知道的是它的起点和终点Timeline
的位置。这是好设计,对吗?
那么,当currentTime
发生变化时,center
和currentTime
都会发生变化,然后startPoint.center
对象的endPoint.center
被调用两次。理想情况下,我只想要updateLine
一次被调用,因为我真的只需要更新一次线来反映所做的更改"同时"两点。有没有办法做到这一点?
在这个示例中,两次调用LineView
似乎并不是什么大不了的事。但是如果我定义某种由{100}定义的updateLine
怎么办?然后,当我更新updateLine
时,所有100个PolygonView
中的所有100个PointView
都会更新,而这会依次调用currentTime
100次,设置center
}和PointView
属性100次,这似乎效率很低。
所以这里的主要问题是,对于一个观察多个其他对象的对象,当updatePolygon
观察到的对象被更改时,我怎样才能让这个对象更新一次"同时"而不是{ {1}}次?
我意识到"同时"因为这些变化不是同时处理的,所以在这里并不完全合适;每个frame
在运行时按顺序更新。但是,我找不到更好的词来描述这种情况。