Instantly share code, notes, and snippets.
Last active
July 23, 2020 16:01
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save mattyoung/399c9844be0b260149c7968344525c29 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // PlayButtonOffsetProblem.swift | |
| // NewWorld12 | |
| // | |
| // Created by Matthew on 7/21/20. | |
| // | |
| import SwiftUI | |
| /// A ViewModifier to offset a view by x, y computed from the view's GeometryProxy | |
| /// | |
| /// Example: to optically center align Image(systemName: "play") by centering on | |
| /// the enclosing circle of the equilateral triangle, the diameter of the circle | |
| /// is 4/3 * triagle-width, shift amount (4/3 - 1)/2/2 = 1/12 | |
| /// | |
| /// Image(systemName: "play") | |
| /// .foregroundColor(.white) | |
| /// .font(.system(size: 80)) | |
| /// .modifier(Offset(by: { CGSize(width: $0.size.width / 12, height: 0.0) })) // shift right 1/12 the width | |
| struct Offset: PreferenceKey, ViewModifier { | |
| // caller calculate offset x, y value giving the view's GeometryProxy | |
| let by: (GeometryProxy) -> CGSize | |
| static var defaultValue = CGSize(width: 0.0, height: 0.0) | |
| static func reduce(value: inout Value, nextValue: () -> Value) { | |
| value = nextValue() | |
| } | |
| @State private var offset = CGSize(width: 0.0, height: 0.0) | |
| func body(content: Content) -> some View { | |
| content | |
| .background( | |
| GeometryReader { | |
| Color.clear | |
| .preference(key: Self.self, value: by($0)) | |
| } | |
| ) | |
| .offset(offset) | |
| .onPreferenceChange(Self.self) { offset = $0 } | |
| } | |
| } | |
| extension View { | |
| func offset(by: @escaping (GeometryProxy) -> CGSize) -> some View { | |
| self.modifier(Offset(by: by)) | |
| } | |
| } | |
| struct PlayButtonOffsetProblem: View { | |
| static private let buttonSize: CGFloat = 55 | |
| var body: some View { | |
| ZStack { | |
| VStack { | |
| Button { } | |
| label: { | |
| Circle() | |
| .frame(width: Self.buttonSize, height: Self.buttonSize) | |
| .overlay( | |
| Image(systemName: "play") | |
| .foregroundColor(.white) | |
| .font(.largeTitle) | |
| // .border(Color.black, width: 1) | |
| ) | |
| } | |
| Button { } | |
| label: { | |
| Circle() | |
| .frame(width: Self.buttonSize, height: Self.buttonSize) | |
| .overlay( | |
| Image(systemName: "play") | |
| .foregroundColor(.white) | |
| .font(.largeTitle) | |
| .offset(by: { CGSize(width: $0.size.width / 12, height: 0.0) }) | |
| // .border(Color.black, width: 1) | |
| ) | |
| } | |
| Button { } | |
| label: { | |
| Circle() | |
| .frame(width: Self.buttonSize * 2, height: Self.buttonSize * 2) | |
| .overlay( | |
| Image(systemName: "play") | |
| .foregroundColor(.white) | |
| .font(.system(size: 80)) | |
| // .border(Color.black, width: 1) | |
| ) | |
| } | |
| Button { } | |
| label: { | |
| Circle() | |
| .frame(width: Self.buttonSize * 2, height: Self.buttonSize * 2) | |
| .overlay( | |
| Image(systemName: "play") | |
| .foregroundColor(.white) | |
| .font(.system(size: 80)) | |
| .offset(by: { CGSize(width: $0.size.width / 12, height: 0.0) }) | |
| // .border(Color.black, width: 1) | |
| ) | |
| } | |
| Button { } | |
| label: { | |
| Circle() | |
| .frame(width: Self.buttonSize, height: Self.buttonSize) | |
| .overlay( | |
| Image(systemName: "stop") | |
| .foregroundColor(.white) | |
| .font(.largeTitle) | |
| ) | |
| } | |
| Button { } | |
| label: { | |
| Circle() | |
| .frame(width: Self.buttonSize, height: Self.buttonSize) | |
| .overlay( | |
| Image(systemName: "play.circle") | |
| .foregroundColor(.white) | |
| .font(.largeTitle) | |
| ) | |
| } | |
| } | |
| Color.green | |
| .frame(width: 1, height: 600, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) | |
| } | |
| } | |
| } | |
| struct PlayButtonOffsetProblem_Previews: PreviewProvider { | |
| static var previews: some View { | |
| PlayButtonOffsetProblem() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment