我需要根据设备的尺寸和屏幕的宽度进行计算。
struct TranslatorView: View {
@ObservedObject var settings = TranslationViewModel(spacing: 4, charSize: 20)
var body: some View {
GeometryReader { geometry in
VStack{
TextField("Enter your name", text:self.$settings.translateString)
}
}
}
}
我的ObservableObject
可以在下面看到
class TranslationViewModel: ObservableObject {
@Published var translateString = ""
var ScreenSize : CGFloat = 0
var spacing : CGFloat = 4
var charSize : CGFloat = 20
init(spacing: CGFloat, charSize : CGFloat) {
self.spacing = spacing
self.charSize = charSize
}
}
我需要一种方法将geometry.size.width
传递到我的ScreenSize
属性,但不知道如何执行此操作。
答案 0 :(得分:2)
最简单的方法是在ObservableObject
中包含setter方法,该方法将返回EmptyView
。
import SwiftUI
struct TranslatorView: View {
@ObservedObject var settings = TranslationViewModel(spacing: 4, charSize: 20)
var body: some View {
GeometryReader { geometry in
VStack{
self.settings.passWidth(geometry: geometry)
TextField("Enter your name", text:self.$settings.translateString)
}
}
}
}
class TranslationViewModel: ObservableObject {
@Published var translateString = ""
var ScreenSize : CGFloat = 0
var spacing : CGFloat = 4
var charSize : CGFloat = 20
init(spacing: CGFloat, charSize : CGFloat) {
self.spacing = spacing
self.charSize = charSize
}
func passWidth(geometry: GeometryProxy) -> EmptyView {
self.ScreenSize = geometry.size.width
return EmptyView()
}
}
然后,您可以使用GeometryReader
来实现content: () -> Content
的包装,并在每次GeometryReader
重新呈现时执行一个闭包,以便您可以更新所需的内容。
import SwiftUI
struct TranslatorView: View {
@ObservedObject var settings = TranslationViewModel(spacing: 4, charSize: 20)
var body: some View {
GeometryReaderEasy(callback: {
self.settings.ScreenSize = $0.size.width
}) { geometry in
TextField("Enter your name", text:self.$settings.translateString)
}
}
}
struct GeometryReaderEasy<Content: View>: View {
var callback: (GeometryProxy) -> ()
var content: (GeometryProxy) -> (Content)
private func setGeometry(geometry: GeometryProxy) -> EmptyView {
callback(geometry)
return EmptyView()
}
var body: some View {
GeometryReader { geometry in
VStack{
self.setGeometry(geometry: geometry)
self.content(geometry)
}
}
}
}
答案 1 :(得分:1)
您可以在View
上使用一个简单的扩展名,以在构建视图时允许任意代码执行。
extension View {
func execute(_ closure: () -> Void) -> Self {
closure()
return self
}
}
然后
var body: some View {
GeometryReader { proxy
Color.clear.execute {
self.myObject.useProxy(proxy)
}
}
}