Опции для вывода данных


#1

Добрый день. Подскажите, каким образом лучше прописать передачу свойств для прорисовки данных? Есть массив значений [Double], которые я наношу на свой кастомный UIView. По дефолту рисую черным с толщиной линии 1.0. Как эти свойства можно изменить (данном примере только цвет и толщина линии)? При этом если ничего не указывать, то оставался бы черный и 1.0? Наткнулся на протокол OptionSet, но там, насколько я понял, можно устанавливать опцию (что она есть) без указания значения.


#2
func drawLine(color: UIColor = .black, width: CGFloat = 1.0) {
   ...
}

Если вы это имели в виду.


#3

Да, про такую возможность я знаю, но применить ее не знаю как. Вот часть моего кода

class ChartView: UIView {
    var draw: [[Double]] = []
//...
}

class MainViewController: UIViewController {
    @IBOutlet weak var chartView: ChartView!

override func viewDidLoad() {
        super.viewDidLoad()
chartView.draw = [[1.1, 2.2, 3.3], [4.5, 5.6, 7.8]]
}
}

Рисуется у меня 2 секции, в каждой выводится линия с данными из массива. Использую chartView.setNeedsDisplay() для обновления. Вот как в моем случае лучше устанавливать свойства? Использовать кортежи, типа var draw: [([Double], [Settings])] ?


#4

Если ваши settings нужно применить ко всем секциям, то можно так же создать 2 свойства в ChartView

var color: UIColor = .black
var width: CGFloat = 1.0

Если же для каждой секции нужно будет задавать свои параметры, то тогда как-то так
var settings: [(UIColor, CGFloat)?] = []

И в месте где у вас по идеи должен быть цикл, достаете для каждой секции свои параметры, и если там nil, рисуете черным и 1.0, иначе подставляете параметры.

Использовать примерно так
chartView.settings = [nil, (.red, 1.5)] // первая секция с дефолтными параметрами, вторая с указанными

P.S. хотя вот вроде способ по лучше
var draw: [([Double], UIColor?, CGFloat?)] = []

Для передачи

chartView.draw.append(([1.1, 2.2, 3.3], nil, nil))
chartView.draw.append(([1.1, 2.2, 3.3], .red, 1.5))

При рисовании так же проверяете цвет и толщину.


#5

Да, как вариант.

Сейчас смотрю как сделано в NSAttributedString, вот пример из сети:

let label = UILabel()
let labelText = "String Text"

let strokeTextAttributes: [NSAttributedStringKey : Any] = [
    NSAttributedStringKey.strokeColor : UIColor.black,
    NSAttributedStringKey.foregroundColor : UIColor.white,
    NSAttributedStringKey.strokeWidth : -2.0,
    NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 18)
    ]

label.attributedText = NSAttributedString(string: labelText, attributes: strokeTextAttributes)

Было бы неплохо аналогичным образом сделать. Смотрю определение и не совсем понимаю как свойство ссылается на сам объект, например:

extension NSAttributedStringKey {
    public static let font: NSAttributedStringKey
}

#6
struct Name: Hashable, RawRepresentable {
    var rawValue: String
    init?(rawValue: String) {
        self.rawValue = rawValue
    }
}

extension Name {
    static let first = Name(rawValue: "first")!
    static let second = Name(rawValue: "second")!
}

func test(options: [Name: Any]) {
    for (key, value) in options {
        switch key {
        case .first:
            print("FIRST: \(value)")
        case .second:
            print("SECOND: \(value)")
        default:
            break
        }
    }
}

test(options: [.first: 1, .second: "Hello"])

#7

только сегодня видел похожую реализацию по сегвеям, через RawRepresentable :slight_smile: