Skip to content

Instantly share code, notes, and snippets.

@timothycosta
Last active February 18, 2020 21:08
Show Gist options
  • Save timothycosta/2caf5f1a1c175ffa966f098e3299581b to your computer and use it in GitHub Desktop.
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
//
// 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