UIScrollView 不滚动 w/ 编程自动布局约束

Posted

技术标签:

【中文标题】UIScrollView 不滚动 w/ 编程自动布局约束【英文标题】:UIScrollView not scrolling w/ programmatic autolayout constraints 【发布时间】:2019-11-16 17:02:16 【问题描述】:

我正在尝试了解如何以编程方式使用 UIScrollView

当我给我的内容一个不适合屏幕的大小时,它不会滚动。


final class ProfileView: UIView 

    private var isIpad: Bool 
        return UIDevice.current.userInterfaceIdiom == .pad
    

    private lazy var headerImageView: UIImageView = 
        let iv = UIImageView(frame: .zero)
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.heightAnchor.constraint(equalToConstant: 600).isActive = true
        iv.backgroundColor = .purple
        return iv
    ()

    private lazy var profileImageView: UIImageView = 
        let iv = UIImageView(frame: .zero)
        iv.translatesAutoresizingMaskIntoConstraints = false
        [iv.heightAnchor, iv.widthAnchor].forEach  $0.constraint(equalToConstant: 170).isActive = true 
        iv.layer.cornerRadius = 170 / 2
        iv.layer.borderColor = .white
        iv.layer.borderWidth = 3
        iv.layer.masksToBounds = true
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = true
        iv.backgroundColor = .red

        return iv
    ()

    private(set) lazy var nameLabel: UILabel = 
        let label = UILabel(frame: .zero)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "Foo\nBar"
        label.numberOfLines = 2
        return label
    ()

    private lazy var contentScrollView: UIScrollView = 
        let sv = UIScrollView(frame: .zero)
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    ()

    override init(frame: CGRect) 
        super.init(frame: frame)

        configureLayout()
    

    required init?(coder: NSCoder) 
        return nil
    

    private func configureLayout() 

        addSubview(contentScrollView)
        [headerImageView, profileImageView, nameLabel].forEach  contentScrollView.addSubview($0) 

        let compactConstraints = [
            contentScrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
            contentScrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
            contentScrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
            contentScrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),

            headerImageView.topAnchor.constraint(equalTo: topAnchor),
            headerImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
            headerImageView.trailingAnchor.constraint(equalTo: trailingAnchor),

            profileImageView.centerYAnchor.constraint(equalTo: headerImageView.bottomAnchor),
            profileImageView.centerXAnchor.constraint(equalTo: centerXAnchor),

            nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16),
            nameLabel.centerXAnchor.constraint(equalTo: profileImageView.centerXAnchor),

        ]

        NSLayoutConstraint.activate(compactConstraints)
    

这给了我以下 -

标题图像将名称标签和头像推离屏幕并且滚动不起作用。

我读过一堆关于给滚动视图一个巨大的偏移量以便它滚动的文章,但这肯定是不正确的。

【问题讨论】:

看看这个我认为它对你有用 -> ***.com/questions/44931898/… 【参考方案1】:

您需要为 scrollView 创建所有子视图的约束,将宽度约束添加到标题 img = profileview 宽度,最后使标签底部 = 滚动视图底部以使其推断其高度

let compactConstraints = [

        contentScrollView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
        contentScrollView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
        contentScrollView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
        contentScrollView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),


        headerImageView.topAnchor.constraint(equalTo:contentScrollView.topAnchor),
        headerImageView.leadingAnchor.constraint(equalTo:contentScrollView.leadingAnchor),
        headerImageView.trailingAnchor.constraint(equalTo:contentScrollView.trailingAnchor),  
        headerImageView.widthAnchor.constraint(equalTo: self.widthAnchor) // add this 

        profileImageView.centerYAnchor.constraint(equalTo: headerImageView.bottomAnchor),
        profileImageView.centerXAnchor.constraint(equalTo: centerXAnchor),

        nameLabel.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16),
        nameLabel.centerXAnchor.constraint(equalTo: profileImageView.centerXAnchor),
        nameLabel.bottomAnchor.constraint(equalTo: contentScrollView.bottomAnchor)  // and this 
]

【讨论】:

我认为nameLabel.bottomAnchor 应该锚定到contentScrollView.bottomAnchor - 除了这是正确的答案??

以上是关于UIScrollView 不滚动 w/ 编程自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式布局 UIScrollView,并为其子视图添加了自动布局,但它不滚动

UIScrollView 不能使用情节提要垂直滚动(使用自动布局)?

自动滚动时 UIScrollView 触摸不起作用

以编程方式在 UITableViewCell 内创建 UIScrollView - ScrollView 不滚动

UIScrollView 不滚动自动布局问题

尽管添加了自动布局约束,但 UIScrollView 不滚动