scrollView 中图像的自动布局

Posted

技术标签:

【中文标题】scrollView 中图像的自动布局【英文标题】:Autolayout of the images in scrollView 【发布时间】:2018-10-11 12:47:00 【问题描述】:

我以编程方式将图像放入 UIScrollview。当我在 iPhone 8 上运行模拟器时,每个图像的宽度都非常适合屏幕。但是,当我在 iPhone 8 Plus 上运行它时,图像的宽度比屏幕的宽度要短。我认为自动布局有问题。这背后的可能原因是什么?我将以下代码放在 ViewDidLoad 中。

scrollViewData = [scrollViewDataStruct.init(title: nil, image: #imageLiteral(resourceName: "promotion test 1")), scrollViewDataStruct.init(title: nil, image: #imageLiteral(resourceName: "promotion test 2")), scrollViewDataStruct.init(title: nil, image: #imageLiteral(resourceName: "promotion test 3")), scrollViewDataStruct.init(title: nil, image: #imageLiteral(resourceName: "promotion test 4")), scrollViewDataStruct.init(title: nil, image: #imageLiteral(resourceName: "promotion test 5")), scrollViewDataStruct.init(title: nil, image: #imageLiteral(resourceName: "promotion test 6"))]

scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(scrollViewData.count)

var i = 0
for data in scrollViewData 
    let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: self.scrollView.frame.width, height: self.scrollView.frame.height))
    view.imageView.image = data.image
    self.scrollView.addSubview(view)



    i += 1

我把下面的代码单独放了

class CustomView: UIView 

    let imageView: UIImageView = 
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = UIColor.clear
        imageView.contentMode = .scaleToFill
        return imageView
    ()

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

        self.addSubview(imageView)
        imageView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        imageView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true

    

    required init?(coder aDecoder: NSCoder)
        fatalError("init(coder:) has not been implemented")
    

【问题讨论】:

您没有为 CustomView 相对于 ScrollView 设置任何约束 你的滚动视图框架是什么? 所以我应该删除'let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: self.scrollView.frame.宽度,高度:self.scrollView.frame.height)) view.imageView.image = data.image?' ? 我没有放置滚动视图框架,因为我认为 imageView 约束会相应地增加图像的大小。不是吗? 【参考方案1】:

您的滚动视图可能在 viewDidLoad 中有错误的框架,因为此时尚未触发布局。尝试将代码移动到 viewWillAppear 或 viewDidLayoutSubviews(并确保它不会被多次调用),或者在设置框架之前添加一个 view.layoutIfNeeded() 调用。

【讨论】:

感谢您的回答,但您所说的“它没有被多次调用”是什么意思? viewDidLoad 仅在屏幕加载时调用一次。 viewWillAppear 可以被调用更多次(例如,如果您将另一个屏幕推到当前屏幕上然后将其关闭)并且 viewDidLayoutSubviews 将在任何时候触发布局更新时被调用。 您可能只想将自定义视图添加为滚动视图的子视图一次。如果布局发生变化(在 viewDidLayoutSubviews 中),则设置相对于滚动视图的框架 很抱歉,我是一个真正的初学者。你能给我一个示例代码吗?【参考方案2】:
imageView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
imageView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
imageView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor , constant: 0).isActive = true
imageView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor , constant: 0).isActive = true

【讨论】:

以上是关于scrollView 中图像的自动布局的主要内容,如果未能解决你的问题,请参考以下文章

ios中图像的ScrollView

iOS scrollView自动布局技巧之二 - 纯代码自动布局

ScrollView 自动布局约束打破设备旋转

scrollview xcode4.5 自动布局

如何在 ScrollView 中为 ImageView 设置自动布局约束?

ScrollView 宽度的自动布局问题(错误值)