【问题标题】:Swift with ios-charts library,How to set the size of icons above bars in BarChart?带有 ios-charts 库的 Swift,如何在 BarChart 中设置条形上方图标的大小?
【发布时间】:2021-12-02 20:37:01
【问题描述】:

使用图表库,我有一个视图,其中显示图像或名称的首字母直到插入的数据。我想将此视图用作条形顶部的图像。由于它不是一个时代,我必须通过自定义方法将其转换为 UIImage,因为 Icon 不接受 Views bu only images。

如果我尝试更改帧值,我无法理解我想要的原因,圆形视图会更小一些,在这种情况下,条的大小相同,而不是“偏心”。

left:起始情况(圆圈略大于条的宽度) 右:更改 I.E. 后宽高52

我的自定义视图有这段代码,我认为这里可能有用(给定内在内容大小,无法更改):

public var model: BrandViewModel! { didSet { self.updateOutlets() } }
open override var intrinsicContentSize: CGSize { CGSize(width: 72, height: 72) }


open override func configure() {
    
    super.configure()
    
    self.backgroundColor = .white
    self.layer.cornerRadius = self.intrinsicContentSize.width / 2
    self.imageView.layer.cornerRadius = self.imageView.bounds.width / 2
    self.initialsContainer.layer.cornerRadius = self.imageView.layer.cornerRadius
    
    self.setupShadow()
}

我的图表类:

public struct BarChartValue {
    public var value: Double?
    public var name: String?
    public var color: UIColor?
    
    public init(value: Double?, name: String?, color: UIColor?) {
        self.value = value
        self.name = name
        self.color = color
    }
}

public class CorporateBarChartView: BarChartView {
    
    public override func awakeFromNib() {
        super.awakeFromNib()
        self.setup()
    }
    
    public var values: [BarChartValue]? {
        willSet {
            self.setDataCount(withValues: newValue)
        }
    }
    
    private func setup() {
        self.chartDescription.enabled = false
        self.highlightPerTapEnabled = false
        self.legend.enabled = false
        self.drawBarShadowEnabled = false
        self.drawValueAboveBarEnabled = false
        self.leftAxis.enabled = false
        self.rightAxis.enabled = false
        self.xAxis.enabled = false
        self.pinchZoomEnabled = false
        self.doubleTapToZoomEnabled = false
        self.leftAxis.axisMinimum = 0
        self.isUserInteractionEnabled = false
    }
    
    func setDataCount(withValues values: [BarChartValue]?) {
        guard let values = values else { return }
        let silverPlaceholder = UIColor.gray.withAlphaComponent(0.2)
        
        let dataEntries = values.enumerated().map({ (index, value) -> BarChartDataEntry in
            let brandView = BrandView()
            brandView.model = BrandViewModel(name: value.name, image: nil)
            let view = UIView(frame: CGRect(x: 0, y: 0, width: 72, height: 72))
            view.addSubview(brandView)
            view.backgroundColor = .red//.clear
            brandView.backgroundColor = .green//.clear
            let image = self.image(with: view)
            return BarChartDataEntry(x: Double(index), y: value.value ?? 0, icon: image)
        })
        var set: BarChartDataSet! = nil
        set = BarChartDataSet(entries: dataEntries)
        set.colors = values.map({ (model) -> NSUIColor in
            return (model.color ?? silverPlaceholder)
        })
        set.drawValuesEnabled = false
        
        let data = BarChartData(dataSet: set)
        data.barWidth = 0.3
        self.data = data
    }
    
    func image(with view: UIView) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0)
        defer { UIGraphicsEndImageContext() }
        if let context = UIGraphicsGetCurrentContext() {
            view.layer.render(in: context)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            return image
        }
        return nil
    }
}

【问题讨论】:

    标签: ios swift user-interface ios-charts


    【解决方案1】:
    1. 为什么必须将brandView 包装到另一个view 中?如果你这样做,那么你必须确保它的布局正确或设置了正确的框架。我还建议重用视图的一个实例,这意味着我会在 dataEntries 之前创建一次,然后用新数据重新配置它以生成新图像。
    2. 我想您必须将图像调整为所需的大小,以便图表可以正确绘制它。为此,您可以使用以下扩展:
    
    extension UIImage {
    
        func scaled(toWidth width: CGFloat) -> UIImage? {
    
            guard width > 0.0, self.size.width > 0.0 else {
                return nil
            }
    
            return self.redrawnImage(with: self.size.scaled(toWidth: width))
        }
    
        func scaled(toHeight height: CGFloat) -> UIImage? {
    
            guard height > 0.0, self.size.height > 0.0 else {
                return nil
            }
    
            return self.redrawnImage(with: self.size.scaled(toHeight: height))
        }
    
        private func redrawnImage(with size: CGSize) -> UIImage {
    
            UIGraphicsImageRenderer(size: size).image { _ in
                draw(in: .init(origin: .zero, size: size))
            }
        }
    }
    
    extension CGSize {
    
        func scaled(toWidth width: CGFloat) -> CGSize {
            CGSize(width: width, height: (self.height / self.width) * width)
        }
    
        func scaled(toHeight height: CGFloat) -> CGSize {
            CGSize(width: (self.width / self.height) * height, height: height)
        }
    }
    

    【讨论】:

    • 嗨,对不起,代码不是我自己的,不知道如何使用你的方法,也许是这样? '让图像 = self.image(with: view)?.scaled(toWidth: 50)?.scaled(toHeight: 50)'
    • 测试了这个解决方案,但不能动态适应屏幕尺寸。有没有办法在栏上方设置图标大小?
    • let image = self.image(with: view)?.scaled(toWidth: 50) 将返回一个宽度和高度为 50pt 的图像,该图像将与图像的比例相匹配。您从未说过要动态调整它以适应屏幕尺寸。查看图表库内部,也许有一种方法可以获取条形的宽度。然后根据这个宽度你可以重新缩放你的图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多