LoginSignup
0
2

【SwiftUI】ScrollView内のコンテンツがスクロールを必要とするまでスクロールを制限する(iOS16.4)

Posted at

はじめに

iOS16.4からscrollBounceBehaviorが使用できるようになりました。
これはScrollViewだけでなく、Listにも使用できるようです。

サンプルアプリ

ScrollView内のコンテンツが少ない時はスクロールできません。
Simulator Screen Recording - iPhone 15 Pro - 2024-02-14 at 22.33.47.gif

実装

import SwiftUI

struct ContentView: View {
    struct Item {
        let id = UUID()
        let color: Color
    }
    
    @State private var items = [Item]()

    var body: some View {
        ScrollView {
            VStack {
                Button {
                    addItem()
                } label: {
                    Text("要素追加")
                }
                .buttonStyle(.borderedProminent)
                .frame(maxWidth: .infinity)

                ForEach(items, id: \.id) { item in
                    Text(item.id.uuidString)
                        .frame(maxWidth: .infinity)
                        .frame(height: 60)
                        .background(item.color)
                }
            }
        }
        .scrollBounceBehavior(.basedOnSize)
    }
    
    private func addItem() {
        items.append(.init(color: .init(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))))
    }
}

ドキュメントコメント

scrollBounceBehavior

/// Configures the bounce behavior of scrollable views along the specified
/// axis.
///
/// Use this modifier to indicate whether scrollable views bounce when
/// people scroll to the end of the view's content, taking into account the
/// relative sizes of the view and its content. For example, the following
/// ``ScrollView`` only enables bounce behavior if its content is large
/// enough to require scrolling:
///
///     ScrollView {
///         Text("Small")
///         Text("Content")
///     }
///     .scrollBounceBehavior(.basedOnSize)
///
/// The modifier passes the scroll bounce mode through the ``Environment``,
/// which means that the mode affects any scrollable views in the modified
/// view hierarchy. Provide an axis to the modifier to constrain the kinds
/// of scrollable views that the mode affects. For example, all the scroll
/// views in the following example can access the mode value, but
/// only the two nested scroll views are affected, because only they use
/// horizontal scrolling:
///
///     ScrollView { // Defaults to vertical scrolling.
///         ScrollView(.horizontal) {
///             ShelfContent()
///         }
///         ScrollView(.horizontal) {
///             ShelfContent()
///         }
///     }
///     .scrollBounceBehavior(.basedOnSize, axes: .horizontal)
///
/// You can use this modifier to configure any kind of scrollable view,
/// including ``ScrollView``, ``List``, ``Table``, and ``TextEditor``:
///
///     List {
///         Text("Hello")
///         Text("World")
///     }
///     .scrollBounceBehavior(.basedOnSize)
///
/// - Parameters:
///   - behavior: The bounce behavior to apply to any scrollable views
///     within the configured view. Use one of the ``ScrollBounceBehavior``
///     values.
///   - axes: The set of axes to apply `behavior` to. The default is
///     ``Axis/vertical``.
///
/// - Returns: A view that's configured with the specified scroll bounce
///   behavior.
@available(iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4, *)
public func scrollBounceBehavior(_ behavior: ScrollBounceBehavior, axes: Axis.Set = [.vertical]) -> some View

basedOnSize

/// The scrollable view bounces when its content is large enough to require
/// scrolling.
///
/// The scrollable view bounces along the specified axis if the size of
/// the content exceeeds the size of the scrollable view in that axis.
public static var basedOnSize: ScrollBounceBehavior { get }

おわり

iOS16.4より前に同じことをやろうとするとGeometryReaderが登場してきてちょっとめんどそうですね

公式ドキュメント

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2