介绍
在 iOS 26 中,UIScrollView 迎来了两个重要增强,主要聚焦于滚动边缘的视觉效果和与浮动容器的交互体验。这些改进不仅让滚动过渡更自然,还提升了在复杂界面中内容的可读性。
UIScrollEdgeEffect
过去,当内容滚动到边缘时,系统会使用回弹(bounce)或发光(glow)效果来提示用户。但在 iOS 26 中,Apple 增加了类型为UIScrollEdgeEffect
的属性topEdgeEffect
、leftEdgeEffect
、bottomEdgeEffect
与rightEdgeEffect
,用于设置滚动边缘的效果。
UIScrollEdgeElementContainerInteraction
除了边缘效果,Apple 还引入新的交互UIScrollEdgeElementContainerInteraction
,可以将导航栏、标签栏、工具栏或者自定义浮动视图标记为边缘元素容器,当内容滚动到该容器下方时,系统会自动添加一个渐变模糊效果,从而保证叠加内容的可读性。
案例
代码
swift
import UIKit
class ViewController: UIViewController {
lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(contentView)
scrollView.contentSize = contentView.frame.size
// iOS26新增
// scrollView.bottomEdgeEffect.style = .hard
return scrollView
}()
lazy var contentView: UIView = {
let view = UIView()
view.backgroundColor = .black
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var stackView: UIStackView = {
var config = UIButton.Configuration.clearGlass()
config.title = "Action"
let button1 = UIButton(type: .system)
button1.configuration = config
let button2 = UIButton(type: .system)
config.title = "More"
button2.configuration = config
let stackView = UIStackView(arrangedSubviews: [button1, button2])
stackView.axis = .horizontal
stackView.spacing = 16
stackView.translatesAutoresizingMaskIntoConstraints = false
// iOS26新增
let interaction = UIScrollEdgeElementContainerInteraction()
interaction.scrollView = scrollView
interaction.edge = .bottom
// 关联视图
stackView.addInteraction(interaction)
return stackView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
view.addSubview(stackView)
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
contentView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
contentView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
contentView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
contentView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
contentView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
contentView.heightAnchor.constraint(equalToConstant: 1000),
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20)
])
}
}
效果
