Skip to content

Instantly share code, notes, and snippets.

@CodeSlicing
Last active October 8, 2021 09:22
Show Gist options
  • Save CodeSlicing/8c1711d618ea2154176d5bd093060fe9 to your computer and use it in GitHub Desktop.
Save CodeSlicing/8c1711d618ea2154176d5bd093060fe9 to your computer and use it in GitHub Desktop.
A version of GeometryReader that behaves like a greedy ZStack with a default alignment of center.
//
// GeometryReaderStack.swift
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
// AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright © 2020 Adam Fordyce. All rights reserved.
//
import SwiftUI
/**
A version of GeometryReader that behaves like a greedy ZStack with a default alignment of center.
*/
public struct GeometryReaderStack<Content>: View where Content: View {
public var content: (GeometryProxy) -> Content
private let alignment: Alignment
public init(alignment: Alignment = .center, @ViewBuilder content: @escaping (GeometryProxy) -> Content) {
self.alignment = alignment
self.content = content
}
public var body: some View {
GeometryReader { (geo: GeometryProxy) in
Color.clear
.overlay(content(geo), alignment: alignment)
}
}
}
struct CenteredGeometryReader_Previews: PreviewProvider {
struct CenteredGeometryReader_Harness: View {
var body: some View {
VStack {
Group {
GeometryReader { (geo: GeometryProxy) in
VStack {
Text("In a GeometryReader,")
Text("I'm not centered")
Text("by default 😭")
}
.padding()
.background(Color.blue.opacity(0.5))
}
GeometryReaderStack { (geo: GeometryProxy) in
VStack {
Text("I'm centered by default")
Text("in a GeometryReaderStack! 🥳")
}
.padding()
.background(Color.blue.opacity(0.5))
}
GeometryReaderStack(alignment: .trailing) { (geo: GeometryProxy) in
VStack {
Text("I'm trailing edge aligned")
Text("in a GeometryReaderStack! 😎")
}
.padding()
.background(Color.blue.opacity(0.5))
}
GeometryReaderStack(alignment: .bottomTrailing) { (geo: GeometryProxy) in
VStack {
Text("I'm bottom trailing edge aligned")
Text("with content larger than the bounds of the frame").fixedSize()
Text("in a GeometryReaderStack! 🤔")
}
.padding()
.background(Color.blue.opacity(0.5))
}
}
.frame(350, 200)
.border(Color.black)
}
.edgesIgnoringSafeArea(.all)
}
}
static var previews: some View {
CenteredGeometryReader_Harness()
.padding(100)
.previewSizeThatFits()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment