Last active
February 18, 2020 21:08
-
-
Save timothycosta/2caf5f1a1c175ffa966f098e3299581b to your computer and use it in GitHub Desktop.
Get the position of a child View by wrapping it in a UIView
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
// | |
// UIViewWrapper.swift | |
// lingq-5 | |
// | |
// Created by Timothy Costa on 2019/06/14. | |
// Copyright © 2019 timothycosta.com. All rights reserved. | |
// | |
import SwiftUI | |
import UIKit | |
struct UIViewWrapper<V: UIView> : UIViewRepresentable { | |
var update: ((V, Context) -> Void)? = nil | |
var make: () -> V | |
func makeCoordinator() -> NSObject { | |
return NSObject() | |
} | |
func makeUIView(context: Context) -> V { | |
self.make() | |
} | |
func updateUIView(_ view: V, context: Context) { | |
self.update?(view, context) | |
} | |
} | |
struct PositionFinder<Content: View>: View { | |
var alignment: Alignment = .center | |
var fixedWidth = true | |
var fixedHeight = true | |
@Binding var view: UIView? | |
let builder: () -> Content | |
var body: some View { | |
ZStack(alignment: self.alignment) { | |
UIViewWrapper(update: { (view, _) in | |
print(view.convert(view.bounds, to: nil)) | |
}) { () -> UIView in | |
let v = UIView() | |
v.backgroundColor = .red //.clear | |
DispatchQueue.main.asyncAfter(deadline: .now()) { | |
self.view = v | |
} | |
return v | |
} | |
self.builder() | |
}.fixedSize(horizontal: self.fixedWidth, vertical: self.fixedHeight) | |
} | |
} | |
struct FinderTester: View { | |
@State var position: CGPoint = .zero | |
@State var view: UIView? | |
var dragGesture: some Gesture { | |
DragGesture().onChanged { (value) in | |
self.position = value.location | |
}.onEnded { _ in | |
} | |
} | |
var text: String { | |
guard let v = self.view else { return "" } | |
return "frame: \(v.convert(v.bounds, to: nil))" | |
} | |
var body: some View { | |
VStack { | |
Text(self.text) | |
PositionFinder(view: self.$view) { | |
Image(systemName: "xmark") | |
.resizable() | |
.frame(width: 44.0, height: 44.0) | |
} | |
.position(self.position) | |
.gesture(self.dragGesture) | |
} | |
} | |
} | |
#if DEBUG | |
struct UIViewWrapper_Previews : PreviewProvider { | |
static var previews: some View { | |
VStack { | |
HStack { | |
UIViewWrapper { | |
let label = UILabel() | |
label.text = "Hello world" | |
label.setContentHuggingPriority(.defaultHigh, for: .vertical) | |
return label | |
} | |
UIViewWrapper { | |
return UISwitch() | |
} | |
} | |
VStack { | |
FinderTester() | |
} | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment