Refactor frame reader API (#2016)

This commit is contained in:
Alfonso Grillo
2023-11-02 15:15:57 +01:00
committed by GitHub
parent 14badab01f
commit 4012aca661
9 changed files with 23 additions and 42 deletions
@@ -32,6 +32,6 @@ struct AlignedScrollView<Content: View>: View {
.frame(minWidth: scrollViewFrame.width,
alignment: Alignment(horizontal: alignment, vertical: .center))
}
.background(ViewFrameReader(frame: $scrollViewFrame))
.readFrame($scrollViewFrame)
}
}
@@ -1,26 +0,0 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
/// A SwiftUI `PreferenceKey` for `CGRect` values such as a view's frame.
struct FramePreferenceKey: PreferenceKey {
static var defaultValue: CGRect = .zero
static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
value = nextValue()
}
}
@@ -17,6 +17,16 @@
import Foundation
import SwiftUI
extension View {
/// Reads the frame of the view and store it in `frame` binding.
/// - Parameters:
/// - frame: a `CGRect` binding
/// - coordinateSpace: the coordinate space of the frame.
func readFrame(_ frame: Binding<CGRect>, in coordinateSpace: CoordinateSpace = .local) -> some View {
background(ViewFrameReader(frame: frame, coordinateSpace: coordinateSpace))
}
}
/// Used to calculate the frame of a view.
///
/// Useful in situations as with `ZStack` where you might want to layout views using alignment guides.
@@ -26,7 +36,7 @@ import SwiftUI
/// SomeView()
/// .background(ViewFrameReader(frame: $frame))
/// ```
struct ViewFrameReader: View {
private struct ViewFrameReader: View {
@Binding var frame: CGRect
var coordinateSpace: CoordinateSpace = .local
@@ -43,8 +53,11 @@ struct ViewFrameReader: View {
}
}
extension View {
func readFrame(_ frame: Binding<CGRect>, in coordinateSpace: CoordinateSpace = .local) -> some View {
background(ViewFrameReader(frame: frame, coordinateSpace: coordinateSpace))
/// A SwiftUI `PreferenceKey` for `CGRect` values such as a view's frame.
private struct FramePreferenceKey: PreferenceKey {
static var defaultValue: CGRect = .zero
static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
value = nextValue()
}
}