Swift 3 程序化布局ScrollView:求助用VFL实现横向滚动图片布局
嘿,别愁啦!我来帮你搞定这个横向滚动的图片布局问题~
用VFL实现横向滚动图片布局方案
首先得明确核心逻辑:ScrollView的contentSize是靠内部子视图的约束自动撑开的,所以我们要给4张图搭好水平连续约束链,再把垂直方向和ScrollView对齐,这样就不用手动计算contentSize啦!
具体实现步骤
1. 前期准备
确保你已经在Storyboard里给ScrollView设置好了父视图约束(比如和父视图上下左右对齐,或者固定宽高),然后在代码里拿到这个ScrollView的引用(比如命名为scrollView)。
2. 创建并添加图片视图
先循环创建4个UIImageView,记得关闭系统自动约束,不然会和我们的VFL约束冲突:
// 替换成你自己的图片资源名数组 let imageNames = ["pic1", "pic2", "pic3", "pic4"] var imageViews: [UIImageView] = [] for name in imageNames { let imgView = UIImageView(image: UIImage(named: name)) imgView.contentMode = .scaleAspectFit // 必须关闭这个,否则约束会冲突 imgView.translatesAutoresizingMaskIntoConstraints = false scrollView.addSubview(imgView) imageViews.append(imgView) }
3. 用VFL设置约束
我们分垂直方向和水平方向来设置约束:
垂直方向约束
让图片高度固定为240,同时和ScrollView的顶部、底部对齐,这样ScrollView的contentHeight就会自动等于图片高度:
// 给第一张图设置垂直VFL:top/bottom和scrollView对齐,高度240 let verticalVFL = "V:|[img0(240)]|" var verticalConstraints = NSLayoutConstraint.constraints( withVisualFormat: verticalVFL, options: [], metrics: nil, views: ["img0": imageViews[0]] ) // 给剩下的图片同步高度+垂直对齐约束 for (index, imgView) in imageViews.enumerated() where index > 0 { // 和第一张图高度一致 let heightConstraint = NSLayoutConstraint( item: imgView, attribute: .height, relatedBy: .equal, toItem: imageViews[0], attribute: .height, multiplier: 1.0, constant: 0 ) // 和scrollView顶部对齐 let topConstraint = NSLayoutConstraint( item: imgView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0 ) // 和scrollView底部对齐 let bottomConstraint = NSLayoutConstraint( item: imgView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0 ) verticalConstraints.append(contentsOf: [heightConstraint, topConstraint, bottomConstraint]) } // 激活所有垂直约束 NSLayoutConstraint.activate(verticalConstraints)
水平方向约束
构建一个连续的水平约束链:scrollView左侧 -> 第一张图(240) -> 间距20 -> 第二张图(240) -> ... -> 第四张图(240) -> scrollView右侧,这样ScrollView会自动计算出正确的contentWidth:
// 拼接水平VFL字符串 var horizontalVFL = "H:|-(0)-[img0(240)]" for index in 1..<imageViews.count { horizontalVFL += "-(20)-[img\(index)(240)]" } horizontalVFL += "-(0)-|" // 准备VFL需要的视图字典:key对应VFL里的命名,value是图片视图 var viewsDict: [String: UIView] = [:] for (index, imgView) in imageViews.enumerated() { viewsDict["img\(index)"] = imgView } // 创建并激活水平约束 let horizontalConstraints = NSLayoutConstraint.constraints( withVisualFormat: horizontalVFL, options: .alignAllTop, // 确保所有图片顶部对齐 metrics: nil, views: viewsDict ) NSLayoutConstraint.activate(horizontalConstraints)
4. 关键注意点
- 必须给每个图片视图设置
translatesAutoresizingMaskIntoConstraints = false,否则系统自动生成的约束会和我们的VFL约束冲突。 - 水平VFL里的
|代表ScrollView的leading和trailing,最后一张图和trailing对齐是让ScrollView自动计算contentWidth的核心。 - 垂直方向通过固定图片高度+和ScrollView上下对齐,确保contentHeight正确。
这样做完之后,你的ScrollView就会自动拥有正确的contentSize,能横向滚动展示4张240×240的图片,每张之间保持20的间距啦~
内容的提问来源于stack exchange,提问作者acidosulfurico50
相关产品推荐
相关产品推荐

