Правый якорь UIScrollView не применяется - PullRequest
0 голосов
/ 22 сентября 2018

У меня есть UIViewController? SingleEventController , отображающий события.Поскольку он имеет динамическую информацию для отображения, я решил создать новый класс UIScrollView EventScrollView .Я пытался осознать, что на основе этого очень хорошо объясненного ответа. я пытался применить подход Pure Auto Layout: создайте в нем другой UIView contentView , который содержит всю информацию ипривязан ко всем четырем якорям scrollView.

contentSize scrollView определяется в функции viewDidLayoutSubviews в SingleEventController.

Моя проблема в том, что rightAnchor кажется неисправным.Все информационные элементы пересекают границу представления, перенос слов для больших UILabels не работает, и все элементы, расположенные на правом якоре, исчезли.(Например, имена пользователей в UITableView nopePeopleTV , который является подпредставлением contentView.)

Это выглядит так: Problem-Image


Код в SingleEventController:

view.addSubview(scrollView)
scrollView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: buttonViewDividerView.topAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

override func viewDidLayoutSubviews() {
    let heightOfAllObjects = scrollView.calculateHeightOfAllObjects()
    scrollView.contentSize = CGSize(width: self.view.frame.width, height: heightOfAllObjects + scrollView.heightOfAllPaddings)
}

Код в EventScrollView :

addSubview(contentView)
contentView.addSubview(titleLabel)
contentView.addSubview(locationLabel)
...
contentView.addSubview(nopePeopleTV)

contentView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
titleLabel.anchor(top: contentView.topAnchor, left: contentView.leftAnchor, bottom: nil, right: contentView.rightAnchor, paddingTop: 10, paddingLeft: padding, paddingBottom: 0, paddingRight: padding, width: 0, height: 0)
locationLabel.anchor(top: titleLabel.bottomAnchor, left: contentView.leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: padding, paddingBottom: 0, paddingRight: 0, width: 200, height: 0)
nopePeopleTV.anchor(top: maybePeopleTV.bottomAnchor, left: contentView.leftAnchor, bottom: nil, right: contentView.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)

layoutIfNeeded()
contentView.layoutIfNeeded()

Что я делаю не так?


Моя функция привязки выглядит так:

func anchor(top: NSLayoutYAxisAnchor?, left: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, right: NSLayoutXAxisAnchor?,  paddingTop: CGFloat, paddingLeft: CGFloat, paddingBottom: CGFloat, paddingRight: CGFloat, width: CGFloat, height: CGFloat) {

    translatesAutoresizingMaskIntoConstraints = false

    if let top = top {
        topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true
    }

    if let left = left {
        leftAnchor.constraint(equalTo: left, constant: paddingLeft).isActive = true
    }

    if let bottom = bottom {
        bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true
    }

    if let right = right {
        rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true
    }

    if width != 0 {
        widthAnchor.constraint(equalToConstant: width).isActive = true
    }

    if height != 0 {
        heightAnchor.constraint(equalToConstant: height).isActive = true
    }
}

1 Ответ

0 голосов
/ 22 сентября 2018

Проблема в том, что вы позволяете ширине представления контента диктоваться изнутри на ширину подпредставлений.Вы должны дать представлению содержимого ограничение ширины, соответствующее ширине самого представления прокрутки.

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

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let sv = UIScrollView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(sv)
        NSLayoutConstraint.activate([
            sv.topAnchor.constraint(equalTo: self.view.topAnchor),
            sv.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
            sv.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
            sv.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
        ])
        let cv = UIView() // content view
        cv.translatesAutoresizingMaskIntoConstraints = false
        sv.addSubview(cv)
        NSLayoutConstraint.activate([
            sv.topAnchor.constraint(equalTo: cv.topAnchor),
            sv.leadingAnchor.constraint(equalTo: cv.leadingAnchor),
            sv.trailingAnchor.constraint(equalTo: cv.trailingAnchor),
            sv.bottomAnchor.constraint(equalTo: cv.bottomAnchor),
        ])
        let lab = UILabel()
        lab.translatesAutoresizingMaskIntoConstraints = false
        lab.numberOfLines = 0
        lab.text = Array(repeating: "xxx", count: 100).joined(separator: " ")
        cv.addSubview(lab)
        NSLayoutConstraint.activate([
            lab.topAnchor.constraint(equalTo: cv.topAnchor, constant:30),
            lab.leadingAnchor.constraint(equalTo: cv.leadingAnchor),
            lab.trailingAnchor.constraint(equalTo: cv.trailingAnchor),
        ])
    }
}

Вот результат:

enter image description here

У нас очень длинный ярлык, но он не переносится: он продолжает расширяться вправо, за пределы экрана.Это потому, что само представление контента имеет свой правый край за пределами экрана.Это потому, что мы ничего не сделали для предотвращения этого.Длинная метка сама по себе делает представление содержимого таким же широким, как весь текст метки.

Теперь я добавляю одну заключительную строку кода к viewDidLoad:

    cv.widthAnchor.constraint(
        equalTo:sv.frameLayoutGuide.widthAnchor).isActive = true

В результате получается следующее:

enter image description here

Представление содержимого теперь является шириной представления прокрутки, поэтому метка переносится в представление прокрутки.

Мы делаемоднако, нельзя делать то же самое с высотой представления содержимого;мы хотим , чтобы он рос вертикально в соответствии с его подпредставлениями.Таким образом, мы сможем прокручивать по вертикали (что вам нужно), а не по горизонтали (что вам тоже нужно).

...