Як керувати міжрядковим інтервалом в UILabel


273

Чи можливо зменшити розрив між текстом, якщо його розмістити в декількох рядках у UILabel? Ми можемо встановити рамку, розмір шрифту та кількість рядків. Я хочу зменшити розрив між двома рядками в цій мітці.



2
Чи можу я запропонувати прийняти один із відповідей, правильний для iOS 6.0 та новіших версій? На даний момент прийнята відповідь застаріла.
Марк Амері

Для кожного рядка використовуйте новий UILabel, а потім вставляйте всі мітки в a StackView. Нарешті налаштувати spacingз StackView. Не забудьте укладати їх вертикально.
Мед

Перейдіть за наступним посиланням на рішення у Swift 2. stackoverflow.com/a/39158698/6602495
Sneha,

Зверніться до сторінки stackoverflow.com/a/44325650/342794, щоб дізнатись про перегляд історій та інших деталей.
lal

Відповіді:


261

Я думав про те, щоб додати щось нове до цієї відповіді, тому я не відчуваю себе так погано ... Ось відповідь Швидкого :

import Cocoa

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 40

let attrString = NSMutableAttributedString(string: "Swift Answer")
attrString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

var tableViewCell = NSTableCellView()
tableViewCell.textField.attributedStringValue = attrString

"Коротка відповідь: ви не можете. Щоб змінити інтервал між рядками тексту, вам доведеться підкласити UILabel і прокатати власний малюнокTextInRect або створити кілька міток."

Див.: Встановлення міжрядкових інтервалів UILabel


Це дійсно стара відповідь, а інші вже додали новий і кращий спосіб вирішити це питання. Будь ласка, дивіться оновлені відповіді, подані нижче.


23
Оскільки iOS 6.0, ви можете керувати ним за допомогою NSAttributedString(також доступний у властивостях UILable в конструкторі інтерфейсів Xcode).
ıɾuǝʞ

13
Цікаво, що, наскільки я можу сказати, ви можете додати додатковий проміжок між рядками, але не зменшити його за NSParagraphStyleдопомогою значка NSAttributedString. (Можливо, мені доведеться зробити більше тестування інших модифікованих властивостей, але lineSpacingвластивість дозволяє лише збільшувати його.)
livingtech

дивіться мою відповідь, щоб побачити спосіб використання NSAttributedString
d.ennis

2
@livingtech Це гніває, і я вважаю, що ви правильні. Ви знайшли якісь обхідні шляхи?
Dom Vinyard

7
Просто для уточнення чогось у цій темі. Якщо ви хочете зменшити інтервал між рядками, встановіть висоту рядка на 1,0, а потім встановітьLineHeightMultiple до нижчого значення <1,0, як-от: [paragraphStyle setLineHeightMultiple: 0.8] або
stavkaStyle.lineHeightMultiple

401

У Xcode 6 ви можете це зробити на дошці:

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


1
Скористайтеся більшими перевагами розкадров!
Аллен

22
@PaperThick має те саме питання в 6.1.1. Це "струшувати харлем" протягом декількох хвилин. Не знає, як це виправити :) Xcode Shaking
Антон Гаєнко

8
Чи є спосіб встановити власні шрифти таким чином? Я, здається, не можу змінити цю helvetica на будь-який інший шрифт.
Маркос Кервелло,

2
Якщо ввімкнути "Attributed", а потім відкрити файл у якості вихідного коду, ви можете відредагувати "lineHeightMultiple" вручну і, таким чином, обійти помилку Harlem Shake
ED-209

2
@azdev для тих, хто все ще дивиться на це, я довше отримую потрясіння в Xcode 7.3, але я думаю, що це перша версія, де це не було проблемою
LulzCow

103

Починаючи з iOS 6, ви можете встановити атрибутивний рядок до UILabel. Перевірте наступне:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:label.text];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = spacing;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.text.length)];

label.attributedText = attributedString;

1
attributedStringПовинно бути NSMutableAttributedString(НЕ NSAttributedString)
Mike S

14
Першим кодом рядка має бутиNSMutableAttributedString *attributedString = [NSMutableAttributedString alloc]initWithString:@"sample text"];
Аллен

lineSpacingВласність NSMutableParagraphStyleніколи не буває негативна, тому висота лінії не може бути зменшена з цим підходом. Щоб відповісти на запитання, вам потрібно скористатися іншою властивістю, див. Відповідь @ d.ennis.
Тео

81

Викладені тут рішення не працювали для мене. Я знайшов дещо інший спосіб зробити це за допомогою iOS 6 NSAttributeString:

myLabel.numberOfLines = 0; 
NSString* string = @"String with line one. \n Line two. \n Line three.";
NSMutableParagraphStyle *style  = [[NSMutableParagraphStyle alloc] init];
style.minimumLineHeight = 30.f;
style.maximumLineHeight = 30.f;
NSDictionary *attributtes = @{NSParagraphStyleAttributeName : style,};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:string
                                                         attributes:attributtes];   
[myLabel sizeToFit];

1
Висота рядка залежить від розміру шрифту. Міжрядковий інтервал - це саме те, що міжрядковий інтервал. Ви можете вирішити проблеми, встановивши лише мінімальну / максимальну висоту рядка, але це лише тому, що поточні розміри шрифту, які ви використовуєте, не перевищують межі висоти рядка. Згідно з документацією: "... гліфи та графіки, що перевищують цю висоту, будуть перекривати сусідні лінії ... Хоча ця межа застосовується до самої лінії, міжрядковий інтервал додає додатковий простір між сусідніми лініями."
Арі Брагінський

+1, Якщо ви хочете зменшити інтервал між рядками, це те, що ви хочете зробити. Реальний інтервал між рядками за замовчуванням, найімовірніше, становить 0, тому люди повідомляють, що ви можете лише збільшувати його. Проблема з тим, що відстань буде занадто великою, виникає через занадто велику висоту лінії, тому це призведе до виконання роботи 99% часу.
lawicko

1
Це єдина відповідь, яку я міг знайти, що використовує фактичне значення висоти лінії (замість співвідношення), загальне для таких дизайнерських програм, як Photoshop, Sketch, CSS тощо.
Альберт Борі,

35

Я зробив це просте розширення, яке дуже добре працює для мене:

extension UILabel {
    func setLineHeight(lineHeight: CGFloat) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = lineHeight
        paragraphStyle.alignment = self.textAlignment

        let attrString = NSMutableAttributedString()
        if (self.attributedText != nil) {
            attrString.append( self.attributedText!)
        } else {
            attrString.append( NSMutableAttributedString(string: self.text!))
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
        }
        attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

Скопіюйте це у файл, щоб потім ви могли його використовувати так

myLabel.setLineHeight(0.7)

пам’ятайте, якщо ви робите це, поки ви також використовуєте дошку розгортки для цієї мітки, тоді обов’язково встановіть лінії мітки на 0
Honey

Чому ви просто не встановите безпосередньо lineSpacingта не забудете про налаштування lineHeightMultiple?
Мед

Оскільки ключовим фактором для зменшення висоти лінії є "lineHeightMultiple", немає lineSpacing
Agustin Meriles

скажіть, що ви хочете, щоб висота вашої лінії була 1,4, чому ви не можете просто написати .lineSpacing = 1.4і забути про все .lineHeightMultiple...
Мед

Га! Я спробував, і мені не вийшло, але мені цікаво, чому я не бачу інших відповідей тут, не використовуючи ваш механізм, я маю на увазі, що вони просто встановлюють лініюSpacing. Дивіться прийняту відповідь ...
Мед

33

Від Builder інтерфейсу (сценарій / XIB):

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

Програмно:

SWift 4

Використання розширення міток

extension UILabel {

    // Pass value for any one of both parameters and see result
    func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {

        guard let labelText = self.text else { return }

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple

        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }

        // Line spacing attribute
        attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

Тепер функція розширення виклику

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"

// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) .  // try values 1.0 to 5.0

// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0

Або за допомогою екземпляра мітки (просто скопіюйте та виконайте цей код, щоб побачити результат)

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40

// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))

label.attributedText = attrString

Швидкий 3

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString

2
Додайте рядок "paragraphStyle.alignment = self.textAlignment", щоб зберегти початкове вирівнювання. В іншому випадку текст залишиться вирівняним.
Нітін Майкл

Для тих, хто втрачає еліпсис на великих текстах, тоді використовуйте: paragraphStyle.lineBreakMode = .byTruncatingTail
christostsang

19

В iOS 6 є альтернативна відповідь, яка полягає у встановленні attributedText на етикетці, використовуючи NSAttributedString з відповідними стилями абзацу. Детальну інформацію про висоту рядка за допомогою NSAttributedString див. У цій відповіді про переповнення стека:

Основний текст - висота рядка NSAttributedString виконана правильно?



11

У Swift і як функція, натхненна DarkDust

// Usage: setTextWithLineSpacing(myEpicUILabel,text:"Hello",lineSpacing:20)
func setTextWithLineSpacing(label:UILabel,text:String,lineSpacing:CGFloat)
{
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = lineSpacing

    let attrString = NSMutableAttributedString(string: text)
    attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

    label.attributedText = attrString
}

7

Відповідно до відповіді @Mike, lineHeightMultipleключовим моментом є зменшення рівня . Приклад нижче, він добре працює для мене:

    NSString* text = label.text;
    CGFloat textWidth = [text sizeWithAttributes:@{NSFontAttributeName: label.font}].width;
    if (textWidth > label.frame.size.width) {
        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
        paragraph.alignment = NSTextAlignmentCenter;
        paragraph.lineSpacing = 1.0f;
        paragraph.lineHeightMultiple = 0.75;     // Reduce this value !!!
        NSMutableAttributedString* attrText = [[NSMutableAttributedString alloc] initWithString:text];
        [attrText addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, text.length)];
        label.attributedText = attrText;
    }

6

SWIFT 3 корисне розширення для простішого простору між рядками :)

extension UILabel
{
    func setLineHeight(lineHeight: CGFloat)
    {
        let text = self.text
        if let text = text 
        {

            let attributeString = NSMutableAttributedString(string: text)
            let style = NSMutableParagraphStyle()

           style.lineSpacing = lineHeight
           attributeString.addAttribute(NSParagraphStyleAttributeName,
                                        value: style,
                                        range: NSMakeRange(0, text.characters.count))

           self.attributedText = attributeString
        }
    }
}

5

Я знайшов спосіб, коли можна встановити реальну висоту лінії (не коефіцієнт), і вона навіть відображається в Інтерфейсі . Просто дотримуйтесь інструкцій нижче. Код написаний у Swift 4 .


Крок №1: Створіть файл з назвою DesignableLabel.swiftта вставте наступний код:

import UIKit

@IBDesignable
class DesignableLabel: UILabel {
    @IBInspectable var lineHeight: CGFloat = 20 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.minimumLineHeight = lineHeight
            paragraphStyle.maximumLineHeight = lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: font, range: NSRange(location: 0, length: attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attrString.length))
            attributedText = attrString
        }
    }
}

Крок №2: Помістіть UILabelклавіатуру в аркуш розгортки / XIB і встановіть її клас DesignableLabel. Зачекайте, поки ваш проект буде розроблений (побудова повинна успішно!).

Вказання класу на ваш UILabel


Крок 3: Тепер ви повинні побачити нову властивість на панелі властивостей під назвою "Висота лінії". Просто встановіть значення, яке вам подобається, і ви повинні побачити результати негайно!

Встановіть висоту лінії у властивостях


2

Ось підклас UILabel, який встановлює lineHeightMultipleта гарантує, що внутрішня висота є достатньо великою, щоб не відрізати текст.

@IBDesignable
class Label: UILabel {
    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        let padding = (1.0 - lineHeightMultiple) * font.pointSize
        size.height += padding
        return size
    }

    override var text: String? {
        didSet {
            updateAttributedText()
        }
    }

    @IBInspectable var lineHeightMultiple: CGFloat = 1.0 {
        didSet {
            updateAttributedText()
        }
    }

    private func updateAttributedText() {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        attributedText = NSAttributedString(string: text ?? "", attributes: [
            .font: font,
            .paragraphStyle: paragraphStyle,
            .foregroundColor: textColor
        ])
        invalidateIntrinsicContentSize()
    }
}

додаткові накладки повинні бути (lineHeightMultiple - 1,0) * font.pointSize, правда?
Павло Алексєєв

Код, вказаний вище, як-здається, працює для мене. Але, можливо, ти маєш рацію. Ви спробували зміни? @PavelAlexeev
phatmann

Ні, я дотримуюся лініїSpacing замість lineHeightMultiple :)
Павло Алексєєв

1

У Swift 2.0 ...

Додати розширення:

extension UIView {
    func attributesWithLineHeight(font: String, color: UIColor, fontSize: CGFloat, kern: Double, lineHeightMultiple: CGFloat) -> [String: NSObject] {
        let titleParagraphStyle = NSMutableParagraphStyle()
        titleParagraphStyle.lineHeightMultiple = lineHeightMultiple

        let attribute = [
            NSForegroundColorAttributeName: color,
            NSKernAttributeName: kern,
            NSFontAttributeName : UIFont(name: font, size: fontSize)!,
            NSParagraphStyleAttributeName: titleParagraphStyle
        ]
        return attribute
    }
}

Тепер просто встановіть свій UILabel як приписуванийText:

self.label.attributedText = NSMutableAttributedString(string: "SwiftExample", attributes: attributesWithLineHeight("SourceSans-Regular", color: UIColor.whiteColor(), fontSize: 20, kern: 2.0, lineHeightMultiple: 0.5))    

Очевидно, я додав купу параметрів, які вам можуть не знадобитися. Пограйте - не соромтесь переписувати метод - я шукав це на купі різних відповідей, тому подумав, що опублікую все розширення, якщо це допоможе комусь там ... -rab


1

Swift3 - У розширення UITextView або UILabel додайте цю функцію:

Я додав код, щоб зберегти поточний атрибутивний текст, якщо ви вже використовуєте атрибутивні рядки з видом (замість того, щоб перезаписати їх).

func setLineHeight(_ lineHeight: CGFloat) {
    guard let text = self.text, let font = self.font else { return }

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 1.0
    paragraphStyle.lineHeightMultiple = lineHeight
    paragraphStyle.alignment = self.textAlignment

    var attrString:NSMutableAttributedString
    if let attributed = self.attributedText {
        attrString = NSMutableAttributedString(attributedString: attributed)
    } else {
        attrString = NSMutableAttributedString(string: text)
        attrString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, attrString.length))
    }
    attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
    self.attributedText = attrString
}

1

Ще одна відповідь ... Якщо ви передаєте рядок програмно, вам потрібно передати атрибутивну рядок замість звичайної рядки та змінити її стиль. (IOS10)

NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:@"Your \nregular \nstring"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:4];
[attrString addAttribute:NSParagraphStyleAttributeName
                   value:style
                   range:NSMakeRange(0, attrString.length)];
_label.attributedText = attrString;

1

Розширення Swift 3:

    import UIKit

extension UILabel {
    func setTextWithLineSpacing(text: String, lineHeightMultiply: CGFloat = 1.3) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiply
        paragraphStyle.alignment = .center
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
        self.attributedText = attributedString
    }
}

1

Це має допомогти в цьому. Потім ви можете призначити свою мітку цьому користувальницькому класу на дошці та використовувати параметри безпосередньо у властивостях:

open class SpacingLabel : UILabel {

    @IBInspectable open var lineHeight:CGFloat = 1 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = 1.0
            paragraphStyle.lineHeightMultiple = self.lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: self.text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
            self.attributedText = attrString
        }
    } 
}

Це має допомогти в цьому. Потім ви можете призначити свою мітку цьому користувальницькому класу на дошці розкадрування та використовувати її параметри безпосередньо у властивостях.
Рассел Уорвік

будь ласка, не залишайте у коментарях вміст, пов’язаний з вашою відповіддю. Ваша відповідь має бути корисною, не читаючи коментарів
Нейрон

1

Розширення етикетки Swift 4. Створення NSMutableAttributedString перед переходом у функцію, якщо для атрибутованого тексту є додаткові атрибути.

extension UILabel {

    func setLineHeightMultiple(to height: CGFloat, withAttributedText attributedText: NSMutableAttributedString) {

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = height
        paragraphStyle.alignment = textAlignment

        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length - 1))

        self.attributedText = attributedText
    }
}

0

Цей код працював для мене (ios 7 & ios 8 точно).

_label.numberOfLines=2;
_label.textColor=[UIColor whiteColor];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple=0.5;
paragraphStyle.alignment = NSTextAlignmentCenter;
paragraphStyle.lineSpacing = 1.0;

NSDictionary *nameAttributes=@{
                               NSParagraphStyleAttributeName : paragraphStyle,
                               NSBaselineOffsetAttributeName:@2.0
                               };


NSAttributedString *string=[[NSAttributedString alloc] initWithString:@"22m\nago" attributes:nameAttributes];
_label.attributedText=string;

0

Ось таке швидке рішення. Підклас повинен працювати як для attributedText та властивості тексту, так і для characterSpacing + lineSpacing. Він зберігає інтервал, якщо встановлено новий рядок або attributedString.

open class UHBCustomLabel : UILabel {
    @IBInspectable open var characterSpacing:CGFloat = 1 {
        didSet {
            updateWithSpacing()
        }

    }
    @IBInspectable open var lines_spacing:CGFloat = -1 {
        didSet {
            updateWithSpacing()
        }

    }
    open override var text: String? {
        set {
            super.text = newValue
            updateWithSpacing()
        }
        get {
            return super.text
        }
    }
    open override var attributedText: NSAttributedString? {
        set {
            super.attributedText = newValue
            updateWithSpacing() 
        }
        get {
            return super.attributedText
        }
    }
    func updateWithSpacing() {
        let attributedString = self.attributedText == nil ? NSMutableAttributedString(string: self.text ?? "") : NSMutableAttributedString(attributedString: attributedText!)
        attributedString.addAttribute(NSKernAttributeName, value: self.characterSpacing, range: NSRange(location: 0, length: attributedString.length))
        if lines_spacing >= 0 {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = lines_spacing
            paragraphStyle.alignment = textAlignment
            attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        }
        super.attributedText = attributedString
    }
}

-5

Як швидко забруднити розумний простий спосіб вирішення:

Для UILabels, у яких не так багато рядків, ви можете замість цього використовувати stackViews.

  1. Для кожного рядка напишіть нову мітку.
  2. Вставте їх у StackView. (Виберіть обидві мітки -> Редактор -> Вставити -> StackView
  3. Відрегулюйте Spacingвміст StackView до потрібної кількості

Обов’язково укладайте їх вертикально . Це рішення також працює для користувацьких шрифтів.

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


FWIW - це жахливе, але дієве рішення. Отже, я це зберігаю.
Мед

Я також бачив, як iOS розробник використовує stackviews для створення графіків. Огляд стека дуже потужний
Мед
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.