Skip to content

Instantly share code, notes, and snippets.

@yannxou
Last active June 12, 2025 15:01
Show Gist options
  • Select an option

  • Save yannxou/0ef0c0e1f8218db2b84902ad73a9c9c7 to your computer and use it in GitHub Desktop.

Select an option

Save yannxou/0ef0c0e1f8218db2b84902ad73a9c9c7 to your computer and use it in GitHub Desktop.
SwiftUI: OverflowScrollViewModifier (add scrollview automatically when view does not fit)
import SwiftUI
struct OverflowScrollViewModifier: ViewModifier {
let maxHeight: CGFloat
@State private var contentHeight: CGFloat = 0
private var isContentOverflown: Bool {
contentHeight > maxHeight
}
private func wrapped(_ content: Content, maxHeight: CGFloat) -> some View {
content
.fixedSize(horizontal: false, vertical: true)
.onGeometryChange(for: CGFloat.self, of: \.size.height) {
contentHeight = $0
}
}
func body(content: Content) -> some View {
Group {
if isContentOverflown {
ScrollView {
wrapped(content, maxHeight: maxHeight)
}
.frame(maxHeight: maxHeight)
} else {
wrapped(content, maxHeight: maxHeight)
}
}
}
}
extension View {
func scrollOnOverflow(maxHeight: CGFloat) -> some View {
modifier(OverflowScrollViewModifier(maxHeight: maxHeight))
}
func scrollOnOverflow() -> some View {
self
.hidden()
.overlay(
GeometryReader { proxy in
modifier(OverflowScrollViewModifier(maxHeight: proxy.size.height))
.frame(maxHeight: proxy.size.height)
}
)
}
}
#Preview {
VStack {
Spacer()
Text("Hello, World! This is a very long text to test how it behaves when the content is very long so the size is adapted and the scroll is added automatically only when needed.")
// .background(.red)
.scrollOnOverflow()
Rectangle()
.frame(maxWidth: .infinity, maxHeight: 1)
Text("Hello, World! This is a very long text to test how it behaves when the content is very long and there's no autoscroll modifier added so it truncates the text.")
// .background(.red)
Spacer()
}
}
#Preview {
VStack {
Text("Hello, World! This is a very long text to test the popup and see how it behaves when the content is very long so the size is adapted and the scroll is added automatically only when needed.")
.padding(20)
.scrollOnOverflow(maxHeight: 200)
Text("Something else")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment