Swift中如何添加Button与ScrollView并实现按钮固定不随滚动?
解决Swift中ScrollView滚动时按钮固定且不被遮挡的问题
嘿,这个场景我经常碰到,其实核心就是搞定视图层级和布局约束这两点就行,给你分两种常用实现方式讲:
一、用Storyboard/Xib实现的步骤
- 确保你的ScrollView和按钮都放在同一个父容器里(比如ViewController的根view),处于同一层级。
- 关键操作:在Storyboard左侧的文档大纲里,把按钮拖到ScrollView的上方(iOS的视图层级是“后添加/层级靠上的视图会覆盖下层”,这样按钮就不会被ScrollView里的图片挡住了)。
- 给按钮设置固定位置的约束:比如底部距离父视图安全区20pt、水平居中、宽高固定(比如60x60),这样它就不会跟着ScrollView滚动。
- 正常给ScrollView设置约束(比如上下左右和父视图对齐),同时确保ScrollView内部的图片约束正确(比如图片的宽高、和ScrollView的边缘约束,让系统能算出正确的contentSize)。
二、用纯代码实现的步骤
直接看代码示例,注释里讲得很清楚:
class LevelMenuVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupUI() } private func setupUI() { // 1. 创建并配置ScrollView let scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(scrollView) // 2. 创建ScrollView内部的图片 let levelImage = UIImageView(image: UIImage(named: "level_list")) levelImage.translatesAutoresizingMaskIntoConstraints = false levelImage.contentMode = .scaleAspectFit scrollView.addSubview(levelImage) // 3. 创建固定按钮 let fixedButton = UIButton(type: .system) fixedButton.translatesAutoresizingMaskIntoConstraints = false fixedButton.setTitle("返回主页", for: .normal) fixedButton.backgroundColor = .systemBlue fixedButton.setTitleColor(.white, for: .normal) fixedButton.layer.cornerRadius = 8 // 注意:按钮要在ScrollView之后添加到父视图,这样层级更高 view.addSubview(fixedButton) // 4. 设置约束 NSLayoutConstraint.activate([ // ScrollView约束:铺满父视图 scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), // 图片约束:让ScrollView能计算contentSize levelImage.topAnchor.constraint(equalTo: scrollView.topAnchor), levelImage.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), levelImage.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), levelImage.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), // 如果图片是固定宽高,也可以直接设置width和height约束 levelImage.widthAnchor.constraint(equalTo: view.widthAnchor), levelImage.heightAnchor.constraint(equalToConstant: 1200), // 模拟长图 // 固定按钮约束:底部居中,不随滚动动 fixedButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20), fixedButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), fixedButton.widthAnchor.constraint(equalToConstant: 120), fixedButton.heightAnchor.constraint(equalToConstant: 44) ]) // 万一你不小心先加了按钮再加ScrollView,用这个代码手动提升按钮层级 // fixedButton.layer.zPosition = scrollView.layer.zPosition + 1 } }
关键原理总结
- 视图层级:同一父容器下,后添加的视图层级更高,或者在Storyboard里把按钮拖到ScrollView上方,就能避免被遮挡。
- 布局约束:按钮的约束是和**父视图(比如ViewController的view)**绑定,而不是和ScrollView绑定,这样就不会跟着ScrollView滚动。
内容的提问来源于stack exchange,提问作者B.Ticca
相关产品推荐
相关产品推荐

