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

Swift使用ios-charts库如何调整BarChart柱状图上方的自定义图标尺寸

解决方案

问题根源

  • 你使用的BrandView固有尺寸intrinsicContentSize固定为72x72且无法修改,圆角也基于固有尺寸计算,直接修改视图frame会导致内容变形、圆角异常
  • 生成的72x72尺寸图片大于柱子宽度,直接硬改尺寸没有做居中适配导致出现偏移

具体修改步骤

步骤1:计算目标图标尺寸

你设置了data.barWidth = 0.3(相对宽度),首先需要计算出柱子的实际像素宽度,作为图标目标尺寸:

// 计算单个柱子的实际宽度,注意要在BarChartView布局完成后调用,否则bounds不准
let barActualWidth = (self.bounds.width / CGFloat(values.count)) * 0.3
let targetIconSize = CGSize(width: barActualWidth, height: barActualWidth)

如果你的柱子宽度是固定值,也可以直接给targetIconSize赋值固定值(比如你测试过的52)。

步骤2:缩放自定义视图生成适配尺寸的图片

通过transform缩放BrandView,不需要修改它的固有属性,同时做居中适配避免偏移,替换你原来生成dataEntry的代码:

let dataEntries = values.enumerated().map({ (index, value) -> BarChartDataEntry in
    let brandView = BrandView()
    brandView.model = BrandViewModel(name: value.name, image: nil)
    // 计算缩放比例
    let scaleRatio = targetIconSize.width / 72
    brandView.transform = CGAffineTransform(scaleX: scaleRatio, y: scaleRatio)
    
    // 生成对应大小的容器视图
    let containerView = UIView(frame: CGRect(origin: .zero, size: targetIconSize))
    containerView.backgroundColor = .clear
    containerView.addSubview(brandView)
    // 缩放后的视图居中,避免偏移
    brandView.center = containerView.center
    
    guard let iconImage = self.image(with: containerView) else {
        return BarChartDataEntry(x: Double(index), y: value.value ?? 0)
    }
    return BarChartDataEntry(x: Double(index), y: value.value ?? 0, icon: iconImage)
})

步骤3:调整图标偏移,对齐柱子顶部

默认图标会居中对齐数据点,你需要调整数据集的iconsOffset属性,让图标刚好贴在柱子顶部:

set = BarChartDataSet(entries: dataEntries)
// 向上偏移半个图标高度,让图标底部刚好对齐柱子顶部,可根据实际效果微调
set.iconsOffset = CGPoint(x: 0, y: targetIconSize.height / 2)
// 其余原有配置保持不变
set.colors = values.map({ (model) -> NSUIColor in
    return (model.color ?? silverPlaceholder)
})
set.drawValuesEnabled = false

可选优化

如果你的CorporateBarChartView使用自动布局,第一次赋值values时可能还没完成布局,拿不到正确的bounds,可以重写layoutSubviews方法,布局完成后再刷新数据:

public override func layoutSubviews() {
    super.layoutSubviews()
    // 布局完成后刷新数据,保证计算的柱子宽度正确
    if let values = self.values {
        self.setDataCount(withValues: values)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:18:03