ios - 使用 For 循环在 UISlider 上绘制线条

标签 ios objective-c

我有一个用于播放视频的 UISlider,我想在我的 UISlider 中放置红色“中断指示”线,以直观地向用户显示何时休息即将到来,如下图所示。我的 slider 有一个设置的 .duration 属性,并且我有一个充满时间戳的数组,其中包含视频需要暂停休息的时间。我仍在掌握 iOS 的窍门,所以我不知道如何在 UISlider 上绘制线条。我希望它看起来与此类似:

enter image description here

在我的研究中,我在 Apple Docs 中读到,UISlider 幸运地提供了一种基于浮点值的 slider 坐标方法。这是完美的,因为现在我可以根据数组中的时间戳确定 slider 中的哪个位置可以绘制黄线,对吗?

因此,我创建了一个 for 循环来调用该方法,并(尝试)画一条线。

绘制线条部分是我遇到的问题。我一直在阅读苹果的文档和该网站上的其他问题,但我似乎无法弄清楚绘图逻辑。它画得很好,问题是它的坐标都是错误的。它在一个特定位置(我 View 的左上角)绘制并重叠了大部分线条。这就是我尝试做的事情:

更新代码与@Bannings答案相关(非常感谢您)。

    - (void)breakStarted:(NSNotification *)notification {

        self.lines = [NSMutableArray new];

        for (int i = 0; i < myArray.count; i++) {
            long long nanoSeconds = [[myArray.adMarkerTimes objectAtIndex:i] floatValue];
            float minutes = nanoSeconds / 60000000000;

            [self sliderThumbCenter:self.scrubberSliderView forValue:minutes];

            NSLog(@"Minute Readings: %f", minutes);
        }
    }

    - (float)sliderThumbCenter:(UISlider *)slider forValue:(float)value {

    CGRect trackRect = [slider trackRectForBounds:slider.bounds];
    CGRect thumbRect = [slider thumbRectForBounds:slider.bounds trackRect:trackRect value:value];
    CGFloat centerThumb = CGRectGetMidX(thumbRect);

    NSLog(@"Center Thumb / Line Placements on slider are: %f", centerThumb);

    [self.lines addObject:@(centerThumb)]; // Added the rect values to an array which we will loop through to draw the lines over the slider

    [self setNeedsDisplay];

    return centerThumb;
}
- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextSetLineWidth(context, 2);

    for (NSNumber *x in self.lines) {
        CGContextMoveToPoint(context, x.floatValue, 0);
        CGContextAddLineToPoint(context, x.floatValue, rect.size.height);
        CGContextStrokePath(context);
    }
}

我忘记添加:我在循环中手动将 CMTimeValue 转换为秒。这就是myArray.adMarkerTimes。也许我做错了......

最佳答案

您可以覆盖UISlider的drawRect

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextSetLineWidth(context, 2);


    CGContextMoveToPoint(context, 20, 0);
    CGContextAddLineToPoint(context, 20, rect.size.height);

    CGContextStrokePath(context);
}

或将 UIView 插入 UISlider。

- (UIView *)lineViewForRect:(CGRect)rect {
    UIView *lineView = [[UIView alloc] initWithFrame:rect];
    lineView.backgroundColor = [UIColor redColor];
    return lineView;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [slider addSubview:[self lineViewForRect:CGRectMake(20, 0, 2, slider.bounds.size.height)]];
}

您还可以设置lineView.layer.zPosition = 1:

之前:

enter image description here

之后:

enter image description here


编辑: 您可以将线条存储在数组中,并在上下文中绘制每条线条。
看起来像这样:

// YourSlider.m
- (void)addLineToX:(CGFloat)x {
    [self.lines addObject:@(x)];

    // This will cause drawRect to be called
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
    CGContextSetLineWidth(context, 2);

    for (NSNumber *x in self.lines) {
        CGContextMoveToPoint(context, x.floatValue, 0);
        CGContextAddLineToPoint(context, x.floatValue, rect.size.height);
    }

    CGContextStrokePath(context);
}

关于ios - 使用 For 循环在 UISlider 上绘制线条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30471169/

相关文章:

ios - 应用程序在 runTransitionForCurrentState 上崩溃,但不知道为什么

带有 Rails 后端的 iOS 应用程序

ios - UICollectionView - 在横向模式下重新设计

ios - 使用 GPUImage 将两个视频与色度键混合

ios - 神奇的记录 - 即使删除数据库文件也会出现重复记录

objective-c - KVO 与 NSMutableArray

objective-c - 我怎样才能拥有一个同时包含图像和文本的 UIBarButtonItem?

ios - 将 NSString 分成两部分(最后一个斜线之前和之后)

ios - 断点条件错误

ios - 如何在没有xcode的情况下在iPhone本身上进行调试? UISearchBar/DisplayController 崩溃