一种解决方案:您可以将背景视图设置为蓝色框所示,并确保此视图是不透明的。定义一个新的UIView子类并将其放置在我称之为背景视图上方 - 此视图将是非不透明的 - 让我们称之为标记视图。
标记视图将随时知道要绘制线条的x偏移量。它将提供一个drawRect方法,该方法将将rect参数设置为清晰的颜色(alpha = 0)。然后,您将使用Quartz调用绘制单个垂直线条(如果某个布尔值表示要执行此操作)。
当控制器启动时,它会告诉此视图不要绘制线条。当您启动时,将布尔值更改为YES,给出x坐标,然后告诉该视图setNeedsDisplayInRect:CGRectMake(theXoffset, 0, 1, heightOfView)];
即使存在一些延迟,当视图最终绘制x值时,它也应该是当前的,因为您正在“实时”更新它。
编辑:
所谓的标记,是指垂直线 - 它“标记”了位置,对吧?
alpha 0 意味着(在这种情况下)大多数叠加视图,即“标记”视图,将是清晰的颜色,意味着每个像素都是透明的(alpha=0),以便不会阻挡其下方的视图。此视图绘制的唯一像素是垂直线。
BOOL,“x”等 - 视图的区域属性。您可能需要更多,但不需要太多。然后,这些属性会在调用“drawRect:”时指示视图应该执行什么操作。
您需要学习一些关于 Quartz 的知识(这是 Apple 用于实际绘制的技术)。在 drawRect 中,您将获得当前的 CGContextRef,并在几乎所有调用中使用它,设置要绘制的线条宽度(默认为1),设置线条颜色,移动到某个点,将线条绘制到其他某个点(这将是一个“路径”),然后描边路径。与大多数其他解决方案相比,这将非常快速(但本身可以加速)。
如果这一切似乎太令人生畏,那么也许其他人会有一个更简单的解决方案,或者您可以提供赏金,看看是否有人(比如我)会为您编写整个代码。
编辑2:
这是执行指示器线的视图的代码(我使用了红线来更好地看到它,这个数组设置了颜色:{1,0,0,在R/G/B空间中)
#import "SlideLine.h"
#define LINE_WIDTH 1.0f
@implementation SlideLine
@synthesize showLine, x;
- (void)drawRect:(CGRect)rect
{
if(!showLine) return;
CGRect bounds = self.bounds;
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, LINE_WIDTH);
for(int i=0; i<3; ++i) {
CGFloat val[4] = { 1, 0, 0, i==1 ? 1 : 0.5f};
CGContextSetStrokeColor(c, val);
CGFloat xx = x - LINE_WIDTH/2 - 1 + i;
CGContextMoveToPoint(c, xx, 0);
CGContextAddLineToPoint(c, xx, bounds.size.height);
CGContextStrokePath(c);
}
}
- (void)setShowLine:(BOOL)val
{
showLine = val;
[self setNeedsDisplay];
}
@end
我创建了一个
Xcode项目,向您展示如何使用它,并提供控件以调整速度等参数:
![enter image description here](https://istack.dev59.com/ZdCIq.webp)
编辑3:我开始修改使用动画,但不幸的是它还没有完全完成。想法是将标记线(3像素宽)变成单个视图(3像素宽)。一个新的SlidingLineController从其所有者那里获得更新(由音频回调驱动),告诉控制器在什么时间x应该在哪里(因此它是一个速率)。然后,控制器使用该速率来动画化标记,以便在指定的时间它在应该在的位置。随着更新的到来,动画速率可能会略微加快或减慢,以使绝对位置始终接近您想要的位置。
虽然这似乎比原来更好的技术,但实际上看起来比原来更“断断续续”。最优解可能是使用一个层(而不是视图),然后对其进行动画处理,并在其移动时更新其目标和速率,而不是启动和重新启动。可能这个第二个项目可以使用第一个项目的技术,以每秒30帧的速率简单地重新绘制自己,使用管理速率的相同概念。不幸的是,我现在看到这很快就会过期,所以没有时间去追求这个方案。
编辑:4 好的,我又更新了一下,以每秒30帧的速度重新绘制,使用上述控制器,效果相当不错——虽然还没有完成,但你可以在第三个旋转中看到它非常流畅。