Swiftui 当按钮文本也有图像时,如何将其居中?

Swiftui 当按钮文本也有图像时,如何将其居中?,swiftui,Swiftui,在下面的代码中,我试图生成一个布局,使按钮文本居中,同时在右侧有一个图像。当前,文本被图像的宽度偏移,而不是居中,我添加了一个。在标签中,以便可以看到其未居中。我期待着你的到来。位于按钮文本中B的上方 struct ContentView: View { var body: some View { VStack { Text(".") // Center point Button(action: {},

在下面的代码中,我试图生成一个布局,使按钮文本居中,同时在右侧有一个图像。当前,文本被图像的宽度偏移,而不是居中,我添加了一个。在标签中,以便可以看到其未居中。我期待着你的到来。位于按钮文本中B的上方

struct ContentView: View {
    var body: some View {
        VStack {
            Text(".") // Center point
            Button(action: {}, label: {
                HStack {
                    Spacer()
                    Text("ABC")
                    Spacer()
                    Image(systemName: "person.circle.fill")
                }
            })
        }
    }
}
您可以使用包含HStack{间隔符的ZStack

结果:


一种可能的方法是使用覆盖-默认情况下文本位于中心,但图像可以放在需要的地方

注意:当然,如果您的文本是动态的,并且可能很长,则需要一些更复杂的解决方案,但期望值可能会有所不同

因此,对于您的快照


一种解决方案,涉及前面提到的技术,但考虑到长字符串和大小可变的图像:

struct ContentView: View {
    
    @State private var imageWidth: CGFloat = 0
    
    var body: some View {
        VStack {
            Text(".")
            Button(action: {}, label: {
                ZStack {
                    HStack {
                        Spacer()
                        Image(systemName: "person.circle.fill")
                            .background(GeometryReader {
                                Color.clear.preference(key: ImageWidthPrefKey.self,
                                                       value: $0.frame(in: .local).size.width)
                            })
                            .onPreferenceChange(ImageWidthPrefKey.self) {
                                imageWidth = $0
                            }
                    }
                    Text("A long string that will probably wrap when it reaches the end and be a couple of lines long")
                       .multilineTextAlignment(.center)
                       .padding(.horizontal,imageWidth)
                }
            })
        }
    }
    
    struct ImageWidthPrefKey : PreferenceKey {
        static var defaultValue: CGFloat { 0 }
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value = value + nextValue()
        }
    }
}
悲伤但简单:

struct ContentView: View {
    var body: some View {
        VStack {
            Text(".") // Center point
            Button(action: {}, label: {
                HStack {
                    Image(systemName: "person.circle.fill")
                       .opacity(0)
                       .accessibility(hidden: true)
                    Spacer()
                    Text("ABC")
                    Spacer()
                    Image(systemName: "person.circle.fill")
                }
            })
        }
    }
}

我考虑过这个问题,但我认为两者在同一个HStack中意味着它们永远不会重叠-这是一种很好的行为,以防文本增长。将文本居中并保持这种行为将是非常棒的,我不确定是否可能不使事情极度复杂化!@user1636130是的,这将有点复杂。Sho文本是否一直延伸到左边,但仍然停留在图像处?还是应该停留在左边,就像那里有另一个图像一样?如果你想避免重叠,我会在另一侧粘贴一个图像的不可见副本。请参见我的答案。
struct ContentView: View {
    
    @State private var imageWidth: CGFloat = 0
    
    var body: some View {
        VStack {
            Text(".")
            Button(action: {}, label: {
                ZStack {
                    HStack {
                        Spacer()
                        Image(systemName: "person.circle.fill")
                            .background(GeometryReader {
                                Color.clear.preference(key: ImageWidthPrefKey.self,
                                                       value: $0.frame(in: .local).size.width)
                            })
                            .onPreferenceChange(ImageWidthPrefKey.self) {
                                imageWidth = $0
                            }
                    }
                    Text("A long string that will probably wrap when it reaches the end and be a couple of lines long")
                       .multilineTextAlignment(.center)
                       .padding(.horizontal,imageWidth)
                }
            })
        }
    }
    
    struct ImageWidthPrefKey : PreferenceKey {
        static var defaultValue: CGFloat { 0 }
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value = value + nextValue()
        }
    }
}
struct ContentView: View {
    var body: some View {
        VStack {
            Text(".") // Center point
            Button(action: {}, label: {
                HStack {
                    Image(systemName: "person.circle.fill")
                       .opacity(0)
                       .accessibility(hidden: true)
                    Spacer()
                    Text("ABC")
                    Spacer()
                    Image(systemName: "person.circle.fill")
                }
            })
        }
    }
}