Skip to content

Instantly share code, notes, and snippets.

@MojtabaHs
Created April 14, 2022 12:18
Show Gist options
  • Select an option

  • Save MojtabaHs/836f752d5d04d4786eeb4452af6a9db5 to your computer and use it in GitHub Desktop.

Select an option

Save MojtabaHs/836f752d5d04d4786eeb4452af6a9db5 to your computer and use it in GitHub Desktop.

Revisions

  1. MojtabaHs created this gist Apr 14, 2022.
    58 changes: 58 additions & 0 deletions FlexibleViewModifier.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    extension View {
    func flexible(width: Bool, height: Bool) -> some View {
    self.modifier(MatchingParentModifier(width: width, height: height))
    }
    }

    struct MatchingParentModifier: ViewModifier {
    @State private var intrinsicSize: CGSize = UIScreen.main.bounds.size
    private let intrinsicWidth: Bool
    private let intrinsicHeight: Bool

    init(width: Bool, height: Bool) {
    intrinsicWidth = !width
    intrinsicHeight = !height
    }

    func body(content: Content) -> some View {
    GeometryReader { _ in
    content.modifier(intrinsicSizeModifier(intrinsicSize: $intrinsicSize))
    }
    .frame(
    maxWidth: intrinsicWidth ? intrinsicSize.width : nil,
    maxHeight: intrinsicHeight ? intrinsicSize.height : nil
    )
    }
    }

    struct intrinsicSizeModifier: ViewModifier {
    @Binding var intrinsicSize: CGSize

    func body(content: Content) -> some View {
    content.readIntrinsicContentSize(to: $intrinsicSize)
    }
    }

    struct IntrinsicContentSizePreferenceKey: PreferenceKey {
    static let defaultValue: CGSize = .zero

    static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
    value = nextValue()
    }
    }

    extension View {
    func readIntrinsicContentSize(to size: Binding<CGSize>) -> some View {
    background(
    GeometryReader {
    Color.clear.preference(
    key: IntrinsicContentSizePreferenceKey.self,
    value: $0.size
    )
    }
    )
    .onPreferenceChange(IntrinsicContentSizePreferenceKey.self) {
    size.wrappedValue = $0
    }
    }
    }