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

UITextView插入文本前返回原点坐标不准确问题求助

解决UITextView正上方添加线条的问题

看你的代码,应该是想给UITextView顶部加一条蓝色线条,但现有代码里有几个小细节需要调整,我帮你梳理并修正一下:

1. 修正CAShapeLayer的使用逻辑

CAShapeLayer并不适合用backgroundColor来设置线条颜色,它更适合通过路径(Path)来绘制线条,同时你已经考虑到了屏幕分辨率适配的1/UIScreen.main.scale,这点很到位。

2. 完善布局时的线条处理

如果每次布局都重新创建线条会导致重复添加,所以我们需要保证线条只初始化一次,同时在布局变化(比如屏幕旋转)时更新线条的宽度。

这里是调整后的完整代码:

// 先定义成员变量存储顶部线条
private var topLine: CAShapeLayer?

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    // 线条不存在则创建,存在则更新位置宽度
    if topLine == nil {
        addTopBorder()
    } else {
        updateTopBorderFrame()
    }
}

private func addTopBorder() {
    let pixelWidth = 1 / UIScreen.main.scale
    topLine = CAShapeLayer()
    
    // 设置线条颜色和宽度
    topLine?.strokeColor = UIColor.blue.cgColor
    topLine?.lineWidth = pixelWidth
    
    // 绘制顶部线条路径:从UITextView左上角到右上角
    let startPoint = CGPoint(x: 0, y: 0)
    let endPoint = CGPoint(x: self.bounds.width, y: 0)
    let linePath = UIBezierPath()
    linePath.move(to: startPoint)
    linePath.addLine(to: endPoint)
    
    topLine?.path = linePath.cgPath
    // 将线条添加到UITextView的图层上
    self.layer.addSublayer(topLine!)
}

private func updateTopBorderFrame() {
    guard let line = topLine else { return }
    // 布局变化时更新线条的终点位置
    let endPoint = CGPoint(x: self.bounds.width, y: 0)
    let updatedPath = UIBezierPath()
    updatedPath.move(to: CGPoint(x: 0, y: 0))
    updatedPath.addLine(to: endPoint)
    line.path = updatedPath.cgPath
}

额外小提示

  • 如果你的UITextView设置了内边距(textContainerInset),可以把线条的起始x坐标改成self.textContainerInset.left,让线条和文本内容对齐;
  • 如果需要添加底部线条,逻辑和顶部完全一致,只需要把y坐标改成self.bounds.height即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:30:20