标签: geometryreader

iOS 14 无效的帧尺寸(负或非有限)

我的应用程序使用 GeometryReader 和一些填充来设置 NavigationView 内的视图框架尺寸。

从 iOS 14 开始,我收到以下错误消息:

无效的框架尺寸(负或非有限)

下面是一些要测试的示例代码:

import SwiftUI

struct ContentView: View {

    let padding:CGFloat = 16.0

    var body: some View {
        NavigationView {
            GeometryReader { p in
        Text("Hello, world!")
            .frame(width: p.size.width - padding)
            .padding()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

删除 NavigationView 解决了这个问题,但我需要 NavigationView 中容器视图的当前宽度和高度。

有什么建议吗?

swiftui geometryreader ios14

18
推荐指数
2
解决办法
6988
查看次数

SwiftUI GeometryReader 不会在中心布局自定义子视图

我有一个自定义视图:

struct ImageContent: View {
    var body: some View {
        Image("smile")
            .resizable()
            .scaledToFit()
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个被放置到另一个视图中GeometryReader

var body: some View {
    GeometryReader { geometry in
        ImageContent()
        //Image("smile").resizable().scaledToFit()
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,ImageContent视图不是在屏幕上居中,而是被放置在顶部,但是,通过删除ImageContent子视图并将视图的内容直接添加到几何阅读器中将解决这个问题(见图)。

此外,删除GeometryReader也可以解决问题。

我需要子视图,因为我将实现一些额外的逻辑,还需要 ,GeometryReader因为有一个手势添加到Image使用它的 。

任何的想法?

截屏

swiftui geometryreader

13
推荐指数
4
解决办法
4342
查看次数

如何缩放图像以填充父视图而不影响 SwiftUI 中的布局?

目标

我经常遇到这样的情况:我想要缩放图像,以便它按比例填充其容器而不修改其框架。下面的第一个屏幕截图中显示了一个示例。容器视图具有固定框架,如红色边框所示。图像本身具有不同的长宽比。它被缩放以填充整个容器,但它仍然具有与容器相同的框架,因此不会影响容器的布局(大小)。

我的解决方案

我使用以下代码来完成此操作:

struct ContentView: View {
    var body: some View {
        ImageContainerView()
            .frame(width: 300, height: 140)
            .border(.red, width: 2)
    }
}

struct ImageContainerView: View {
    var body: some View {
        GeometryReader { geometry in
            Image("image")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .border(.blue, width: 2)
                .frame(width: geometry.size.width, height: geometry.size.height)
                .clipped()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题

如您所见,我使用几何读取器手动设置图像的框架以匹配父视图的框架。这感觉有点多余,因为图像已经从其父视图隐式接收到此信息作为建议的大小。但是,如果我不以这种方式使用几何读取器,则图像不会被剪切,并且其框架与完整缩放的图像匹配,而不是父视图的框架。下面的第二个屏幕截图显示了这一点。

问题

SwiftUI 中是否有一种(更“原生”)的方法可以在不使用几何读取器的情况下实现所需的行为?

剪裁的 未修剪的

image clipping aspect-ratio swiftui geometryreader

8
推荐指数
1
解决办法
5108
查看次数

在geometryReader中设置@State var

如何在 GeometryReader 中设置 @State var?

这是我的代码:

@State var isTest:Int = 0

var body: some View {
    VStack{
        ForEach(self.test, id: \.id) { Test in
            VStack{
                GeometryReader { geometry in
                    self.isTest = 1
Run Code Online (Sandbox Code Playgroud)

我尝试使用一个函数,但它不起作用。

@State var isTest: Int = 0

func testValue() {
    self.isTest = 1
}

var body: some View {
    VStack{
        ForEach(self.test, id: \.id) { Test in
            VStack{
                GeometryReader { geometry in
                    testValue()

Run Code Online (Sandbox Code Playgroud)

任何想法?谢谢!

swiftui geometryreader

7
推荐指数
2
解决办法
4523
查看次数

GeometryReader 在 SwiftUI 中折叠我的列表

我想使用 GeometryReader 来使用一些计算。没有我的设计看起来应该:

var body: some View {
    ZStack {
        Color(#colorLiteral(red: 0.117543973, green: 0.2897527516, blue: 0.4028342962, alpha: 1)).edgesIgnoringSafeArea(.all)
        VStack {
            HStack(spacing: self.spacing) { // todo auch berechnen?
                ForEach(self.chartValues, id: \.self) { point in
                    DataPoint(width: 200)
                }
            }.animation(.default)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

添加后,每条线的高度都相互重叠,我做错了什么:

var body: some View {
    ZStack {
        Color(#colorLiteral(red: 0.117543973, green: 0.2897527516, blue: 0.4028342962, alpha: 1)).edgesIgnoringSafeArea(.all)
        VStack {
            GeometryReader { geo in
                HStack(spacing: self.spacing) { // todo auch berechnen?
                    ForEach(self.chartValues, id: \.self) { point in
                        DataPoint(width: geo.size.width)
                    }
                }.animation(.default)
            } …
Run Code Online (Sandbox Code Playgroud)

swift swiftui geometryreader

6
推荐指数
0
解决办法
1491
查看次数

设置 Text().frame(maxWidth: .infinity) 后如何保持 Text 作为前导对齐

这可能是一个简单的情况,但我找不到解决方案。

\n\n

这是我的代码,使用 GeometryReader 设置 SwiftUI 视图大小的相对布局,如图像。问题出现在最后一个VStack上,我希望文本的背景转到VStack的右端。因此,我将其设置为,Text("Haibo: asdasd").frame(maxWidth: .infinity)但之后我发现文本变为水平居中并且不遵循 VStack 对齐方式:.leading。

\n\n
import SwiftUI\n\nstruct ContentView: View {\n    var body: some View {\n\n        GeometryReader { geo in\n            HStack(alignment: .top, spacing: 12) {\n                Image("Alan shore").resizable().frame(width: geo.size.width / 6, height: geo.size.width / 6).cornerRadius(4)\n\n                VStack(alignment: .leading, spacing: 10) {\n\n                   // name\n                   Text("Haibo")\n                   // content\n                   Text("Think ThinkThink ThinkThink ThinkThink ThinkThink ThinkThink ThinkThink ThinkThink Think")\n                   // \xe4\xb9\x9d\xe5\xae\xab\xe6\xa0\xbc\n                   VStack(spacing: 6) {\n\n                       HStack(spacing: 6) {\n                           Image("Little girl").resizable().frame(width: geo.size.width / 4.7, height: geo.size.width / 4.7)\n                           Image("Little …
Run Code Online (Sandbox Code Playgroud)

layout ios swiftui geometryreader

6
推荐指数
2
解决办法
1337
查看次数

SwiftUI:如何查找图像的高度并使用它来设置框架的大小

因此,我一段时间以来一直在尝试找出如何在 SwiftUI 中查找图像的高度,但没有成功。本质上,我有纵向/横向图像,我想要以大约 600 pt 高显示纵向图像,而我想要显示横向图像,因此使用图像的宽度,因此高度是任意的。话虽这么说,我希望它位于 GeometryReader 内部,因为我使用的偏移量使用它,这样当您向下滚动时,图像不会滚动,但如果您向上滚动,它就会滚动。我不相信我可以共享图像,但无论如何,这应该足以成功运行它!

struct ContentView: View {
    
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
  
    var backButton: some View {
        Button(action: {
            withAnimation {
                self.mode.wrappedValue.dismiss()
            }
        }) {
            Image(systemName: "chevron.left.circle.fill")
                .opacity(0.8)
                .font(.system(size: 30))
                .foregroundColor(.black)
                .background(Color.gray.mask(Image(systemName: "chevron.left").offset(x: 9.4, y: 7.6)))
                
        }
    }

    var body: some View {
        ScrollView(showsIndicators: false) {
            
                GeometryReader { geometry in
                    Image("image1")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(maxWidth: UIScreen.main.bounds.width, minHeight: 350, maxHeight: 600, alignment: .top)
                        .clipped()
                        .overlay(
                            Rectangle()
                                .foregroundColor(.clear)
                                .background(LinearGradient(gradient: Gradient(colors: [.clear, .white]), startPoint: .center, endPoint: .bottom))
                        )
                       .offset(y: …
Run Code Online (Sandbox Code Playgroud)

image swift swiftui geometryreader

6
推荐指数
1
解决办法
1万
查看次数

如何正确地将“单元格项目”从 SwiftUI LazyVGrid 传递到 .sheet?

这是我的例子,我无法判断这是否是一个错误。我的所有单元格都正确加载,但是当我尝试将其作为工作表打开时DetailView(),传入的项目始终是网格中首先显示的项目(在我的情况下位于左上角),而不是原来的“单元格”被点击。那么,为什么 ForEach 循环中的项目正确填充单元格,但没有通过按钮传递到 .sheet ?

    import SwiftUI

    let columnCount: Int = 11
    let gridSpacing: CGFloat = 1

    struct GridView: View {
        
        @State var showingDetail = false
        
        let data = (1...755).map { "\($0)" }
        let columns: [GridItem] = Array(repeating: .init(.flexible(), spacing: gridSpacing), count: columnCount)
        let colCount: CGFloat = CGFloat(columnCount)
        var body: some View {
            GeometryReader { geo in
                ScrollView (showsIndicators: false) {
                    LazyVGrid(columns: columns, spacing: gridSpacing) {
                        ForEach(data, id: \.self) { item in
                            
                            Button(action: {
                                self.showingDetail.toggle()
                            }) {
                                GridCell(item: …
Run Code Online (Sandbox Code Playgroud)

scroll popover swiftui geometryreader lazyvgrid

6
推荐指数
1
解决办法
3297
查看次数

如何在 SwiftUI 中相对于不同坐标系中的其他视图定位视图

我正在尝试使用 SwiftUI 在我的应用程序中实现拖放功能。

我创建了两个圆圈,它们位于两个不同的HStacks. 它们不共享相同的坐标空间。

带有描边的圆圈是目标,绿色实心圆圈是要拖动的对象。

我能够使用GeometryReaderinside an来获得他们的绝对位置.overlay。我用它来检测当对象圆被拖动到目标圆上时它们是否重叠。这有效。

当它们不重叠时,对象圆将移回其原始位置。当它们重叠时,对象圆应该卡入目标圆的位置。这是我似乎有问题的地方。

我试图通过以下方式设置对象圆的新 X 和 Y 位置:对象圆本地位置 - 对象圆全局位置 + 目标圆全局位置。

    objectPosition = CGPoint(
        x: objectPosition.x - objectFrame.midX + targetFrame.midX,
        y: objectPosition.y - objectFrame.midY + targetFrame.midY
   )
Run Code Online (Sandbox Code Playgroud)

我假设这会将我带到目标圆的坐标空间。但不知怎的,它不起作用。

到目前为止,我一直无法找到一种可靠且简单的方法来转换 SwiftUI 中的坐标空间。使用覆盖内部的解决方法GeometryReader至少给了我正确的全局位置。但我还没有找到一种方法来使用这些位置将视图放置在.global坐标空间中。

如果有人知道为什么我对坐标空间的计算是错误的,或者甚至知道一种更容易地相对于彼此转换和定位视图的方法,我将非常感激。

这是我的 SwiftUI 单视图 iOS 应用程序的代码:

import SwiftUI

struct ContentView: View {
    
    @State private var isDragging: Bool = false
    
    @State private var objectDragOffset: CGSize = .zero
    @State private var objectPosition: CGPoint = …
Run Code Online (Sandbox Code Playgroud)

drag-and-drop coordinates swift swiftui geometryreader

5
推荐指数
1
解决办法
2061
查看次数

SwiftUI ScrollView:查找当前在屏幕中心可见的子视图。子视图在 ScrollView 中的位置。偏好键。滚动视图代理

挑战:我想跟踪 ScrollView 的哪个子视图位于该 ScrollView 可见区域的中间。

问题:据我了解,没有原生 SwiftUI 方法可以确定 ScrollView 的子视图当前在屏幕上是否可见。或者我想念这里的什么吗?

我的解决方案:我使用 PreferenceKey 来收集子视图位置,并在 ScrollView 滚动时连续发生的 PreferenceChange 上执行操作:检查最接近屏幕中心的视图。

问题:基于 PreferenceKey 的解决方案适用于一些子视图。但我需要跟踪最多 3000 个子视图(从数据库构建的大型结构化文档的视图)。即使在实施了我能够提出的一些优化之后,大量视图的性能也是不可接受的。

我的问题是:有吗

  • 提高下面所示解决方案性能的方法,或者
  • 应对这一挑战的不同方式

(iOS 14.4 / Xcode 12.4)

SwiftUI 跟踪屏幕中心的子视图

private struct ViewOffsetsKey: PreferenceKey {
    static var defaultValue: [Int: CGFloat] = [:]
    static func reduce(value: inout [Int: CGFloat], nextValue: () -> [Int: CGFloat]) {
        value.merge(nextValue(), uniquingKeysWith: { $1 })
    }
}

struct ContentView: View {
    @State private var offsets: [Int: CGFloat] = [:]
    @State private var …
Run Code Online (Sandbox Code Playgroud)

position scrollview ios swiftui geometryreader

5
推荐指数
1
解决办法
2263
查看次数