You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iPhone X设备绘图功能异常:线条随操作变淡上移问题排查求助

iPhone X 绘图线条偏移且变淡的问题修复方案

嘿,这个问题我之前适配iPhone X的时候也踩过坑!核心原因其实是iPhone X的**安全区域(Safe Area)**和Retina屏幕适配没做好,导致触摸坐标和绘图上下文的坐标不匹配,加上反复绘制时的像素损耗,才出现了线条偏移、逐渐变淡的情况。咱们一步步来解决:

问题根源拆解

  1. Retina屏幕适配缺失:你用的UIGraphicsBeginImageContext没有考虑屏幕缩放因子,生成的是低分辨率图片,反复叠加绘制就会越来越模糊变淡;
  2. 坐标错位:iPhone X的状态栏+刘海占了顶部空间,如果视图布局没适配安全区域,触摸事件的坐标(previousPoint/currentPoint)和视图本地坐标会有偏移,导致线条往上跑;
  3. 反复绘制的损耗:每次把旧图重新画到上下文再叠加新线条,相当于不断压缩图片,自然会越来越淡。

具体修复步骤

1. 替换绘图上下文,适配Retina屏幕

把UIGraphicsBeginImageContext换成带屏幕缩放因子的方法,保证图片清晰度:

- (void)drawLineNew{
    // 使用带屏幕scale的上下文,NO表示透明背景
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
    [self.viewImage drawInRect:self.bounds];
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetStrokeColorWithColor(context, self.selectedColor.CGColor);
    CGContextSetLineWidth(context, _lineWidth);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, previousPoint.x, previousPoint.y);
    CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y);
    CGContextStrokePath(context);
    self.viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self setNeedsDisplay];
}

2. 修正触摸坐标的转换逻辑

确保在处理触摸事件(比如touchesBegan:/touchesMoved:)时,把触摸点转换到当前视图的本地坐标系:

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = touches.anyObject;
    // 关键:用locationInView:self获取视图本地坐标,而非基于window的坐标
    currentPoint = [touch locationInView:self];
    [self drawLineNew];
    previousPoint = currentPoint;
}

3. 检查视图布局,适配安全区域

如果用Auto Layout布局绘图视图,一定要把顶部约束绑定到safeAreaLayoutGuide.topAnchor,避免视图可绘制区域和触摸区域错位:

// 假设你的绘图视图是drawView
[drawView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
[drawView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
[drawView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
[drawView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;

4. 优化绘图逻辑,彻底避免叠加损耗

如果想从根源解决线条变淡问题,推荐用CAShapeLayer绘制,不用每次重新渲染整张图片:

// 初始化时创建shapeLayer(比如在viewDidLoad里)
- (void)setupDrawLayer {
    CAShapeLayer *drawLayer = [CAShapeLayer layer];
    drawLayer.lineCap = kCALineCapRound;
    drawLayer.strokeColor = self.selectedColor.CGColor;
    drawLayer.lineWidth = _lineWidth;
    drawLayer.fillColor = [UIColor clearColor].CGColor;
    drawLayer.name = @"DrawLayer";
    [self.layer addSublayer:drawLayer];
    
    // 缓存所有路径,方便后续保存图片
    self.pathArray = [NSMutableArray array];
}

// 触摸移动时更新路径
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = touches.anyObject;
    CGPoint current = [touch locationInView:self];
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:previousPoint];
    [path addLineToPoint:current];
    [self.pathArray addObject:path];
    
    CAShapeLayer *drawLayer = (CAShapeLayer *)[self.layer layerNamed:@"DrawLayer"];
    // 合并所有历史路径
    UIBezierPath *totalPath = [UIBezierPath bezierPath];
    for (UIBezierPath *p in self.pathArray) {
        [totalPath appendPath:p];
    }
    drawLayer.path = totalPath.CGPath;
    
    previousPoint = current;
}

这种方式直接在图层上绘制路径,没有图片叠加的损耗,线条始终清晰,性能也更好。

效果验证

做完这些修改后,iPhone X上的触摸点和线条应该完全对应,线条也不会再变淡了。如果还有问题,可以检查视图的clipsToBounds是否开启,或者有没有其他视图遮挡了绘图区域。

内容的提问来源于stack exchange,提问作者iEngineer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:45:50