UIStackView и усеченные многострочные UILabels

Я хочу добавить несколько многострочных меток к UIStackView.

Но я всегда заканчиваю тем, что мои ярлыки обрезаются. Как видно на этом снимке экрана,  как есть усеченный

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

Вот мой код. Сначала я создаю родительский / главный StackView, помещаю его в ScrollView (который прикреплен к экрану)

    stackView = UIStackView()
    stackView.axis = .Vertical
    stackView.distribution = .Fill
    stackView.spacing = 2
    stackView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(stackView)
    NSLayoutConstraint.activateConstraints(stackConstraints)


    let s1 = createHeaderStackView()
    stackView.insertArrangedSubview(s1, atIndex: 0)

    let lbl2 = makeLabel()
    lbl2.text = "Second One"
    stackView.insertArrangedSubview(lbl2, atIndex: 1)

    scrollView.setNeedsLayout()

а makeLabel и makeButton - просто вспомогательные функции

func makeButton() -> UIButton {
    let btn = UIButton(type: .Custom)
    btn.backgroundColor = UIColor.lightGrayColor()
    return btn
}

func makeLabel() -> UILabel {
    let lbl = UILabel()
    lbl.font = UIFont.systemFontOfSize(18)
    lbl.setContentCompressionResistancePriority(1000, forAxis: .Vertical)
    lbl.setContentHuggingPriority(10, forAxis: .Vertical)
    lbl.preferredMaxLayoutWidth = scrollView.frame.width
    lbl.numberOfLines = 0
    lbl.textColor = UIColor.blackColor()
    lbl.backgroundColor = UIColor.redColor()
    return lbl
}

createHeaderStackViewmethod - настроить мой StackView для помещения в StackView всех моих заголовков.

func createHeaderStackView() -> UIStackView {
    let lblHeader = makeLabel()
    lblHeader.text = "UIStackView"
    lblHeader.textAlignment = .Center

    let lblInfo = makeLabel()
    lblInfo.text = "This is a long text, over several Lines. Because why not and am able to to so, unfortunaltey Stackview thinks I'm not allowed."
    lblInfo.textAlignment = .Natural
    lblInfo.layoutIfNeeded()

    let lblInfo2 = makeLabel()
    lblInfo2.text = "This is a seconds long text, over several Lines. Because why not and am able to to so, unfortunaltey Stackview thinks I'm not allowed."
    lblInfo2.textAlignment = .Natural
    lblInfo2.layoutIfNeeded()

    let btnPortal = makeButton()
    btnPortal.setTitle("My Button", forState: .Normal)
    btnPortal.addTarget(self, action: "gotoPushWebPortalAction", forControlEvents: .TouchUpInside)

    let headerStackView = UIStackView(arrangedSubviews: [lblHeader, btnPortal, lblInfo, lblInfo2])
    headerStackView.axis = .Vertical
    headerStackView.alignment = .Center
    headerStackView.distribution = .Fill
    headerStackView.spacing = 2
    headerStackView.setContentCompressionResistancePriority(1000, forAxis: .Vertical)
    headerStackView.setContentHuggingPriority(10, forAxis: .Vertical)
    headerStackView.setNeedsUpdateConstraints()
    headerStackView.setNeedsLayout()
    //headerStackView.layoutMarginsRelativeArrangement = true
    return headerStackView
}

Короче говоря: что нужно для настройки моих стеков, чтобы каждый стек и, следовательно, метка отображались в полном великолепном размере? Я пыталась все сжать и обнять, но вроде не вышло. И поиск в googling uistackview uilabel multiline truncated тоже кажется тупиком

Я ценю любую помощь, с уважением, Флори


person Flori    schedule 02.11.2015    source источник
comment
Как показано в stackoverflow.com/questions/34386528/, ключ состоит в том, чтобы установить фиксированную ширину для вашего представления стека, чтобы дать вашей многострочной метке что-то, с чем можно столкнуться и стать многострочным.   -  person GlennRay    schedule 19.01.2016
comment
@SpaceDog imho они не плохо спланированы, но у них другая логика, чем у других элементов управления, что требует другого мышления для более сложных макетов, особенно из-за их правил заполнения   -  person Zoltán Matók    schedule 17.09.2016


Ответы (3)


Вы должны указать размеры представления стека. Метка не будет «перетекать» в следующую строку, если размеры представления стека неоднозначны.

Этот код не совсем тот, который вам нужен, но вы поймете идею:

override func viewDidLoad() {
    super.viewDidLoad()
    let stackView = UIStackView()
    stackView.axis = .Vertical
    stackView.distribution = .Fill
    stackView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(stackView)
    let views = ["stackView" : stackView]
    let h = NSLayoutConstraint.constraintsWithVisualFormat("H:|-50-[stackView]-50-|", options: [], metrics: nil, views: views)
    let w = NSLayoutConstraint.constraintsWithVisualFormat("V:|-100-[stackView]-50-|", options: [], metrics: nil, views: views)
    view.addConstraints(h)
    view.addConstraints(w)
    let lbl = UILabel()
    lbl.preferredMaxLayoutWidth = stackView.frame.width
    lbl.numberOfLines = 0
    lbl.text = "asddf  jk;v ijdor vlb otid jkd;io dfbi djior dijt ioure f i;or dfuu;nfg ior mf;drt asddf  jk;v ijdor vlb otid jkd;io dfbi djior dijt ioure f infg ior mf;drt asddf  jk;v ijdor vlb otid jkd;io dfbi djior dijt ioure f i;or dfuu;nfg ior mf;drt "
    dispatch_async(dispatch_get_main_queue(), {
        stackView.insertArrangedSubview(lbl, atIndex: 0)
    })
}
person Ajil O.    schedule 02.11.2016

Насколько я знаю, если вы используете это внутри UITableViewCell, то при каждом повороте вам нужно перезагружать tableView. Вы можете использовать stackView.distribution = .fill, пропорционально он будет работать нормально.

person Sagar Daundkar    schedule 30.11.2017

Вы должны попробовать это на раскадровке. сделайте высоту просмотра стека равной 60% или 70% вашего обзора.

Сделайте множитель 0,6 или 0,7.

См. Здесь

person ahmed    schedule 24.10.2017