Swift с библиотекой диаграмм ios,как установить размер значков над столбцами на диаграмме?

#ios #swift #user-interface #ios-charts

Вопрос:

используя библиотеку диаграмм, у меня есть представление с изображением или инициалами имени до вставки данных. Я хотел бы использовать этот вид в качестве изображения поверх полос. Поскольку это не возраст, я должен преобразовать его в UIImage с помощью пользовательского метода, так как значок не принимает представления, а только изображения.

Если я попытаюсь изменить значения кадров, я не смогу понять, почему я этого хочу, так как круглый вид немного меньше, в данном случае тот же размер баров, а не «децентрированный».

слева: начальная ситуация (круг немного больше ширины бара) справа: после изменения ширины и высоты на 52

введите описание изображения здесь

в моем пользовательском представлении есть этот код, который, я думаю, может быть полезен здесь (не может быть изменен с учетом intrinsicContentSize):

 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
    }
}
 

Ответ №1:

  1. Почему ты должен заворачивать свое brandView в другое view ? Если вы это сделаете, то вам нужно убедиться, что он правильно выложен или установлена правильная рамка. Я также рекомендовал бы повторно использовать один экземпляр представления, то есть я бы создал его один раз до сбора данных и перенастроил его с помощью новых данных для создания нового изображения.
  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)
    }
}
 

Комментарии:

1. привет, извините, но код не полностью мой, не уверен, как я мог бы использовать ваши методы, может быть, таким образом? ‘пусть изображение = self.изображение(с: вид)?.масштабировано(ширина: 50)?.масштабировано(высота: 50)’

2. протестировал это решение, но оно не является динамически адаптивным к размерам экрана. есть ли способ установить размеры значков над полосами?

3. let image = self.image(with: view)?.scaled(toWidth: 50) вернет вам изображение с шириной и высотой 50pt, которые будут соответствовать соотношению изображения. Вы никогда ничего не говорили о динамической адаптации его к размеру экрана. Загляните в библиотеку диаграмм, может быть, есть способ узнать ширину полосы. А затем в соответствии с этой шириной вы можете масштабировать свое изображение.