繁体   English   中英

VStack中的SwiftUI不同对齐文本

[英]SwiftUI different alignment text in VStack

我有一个聊天示例,有 3 个文本,名称、文本和小时。 我想将前两个文本向左对齐,另一个文本向右对齐。

var body: some View {
            HStack {
                if self.cloudPosition == .dx {Spacer(minLength: 20)}
                VStack (alignment: .leading) {
                    Text("\(self.text.name)")
                        .font(.system(size: 15))
                        .foregroundColor(Self.getColor(index: self.text.colorIndex))
                        .padding(EdgeInsets(top: 3, leading: 15, bottom: 3, trailing: 10))
                    Text("\(self.text.text)")
                        .font(.system(size: 15))
                        .padding(EdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8))
                    HStack {
                        Spacer() //I remove this in example 3 
                        Text("\(self.text.date, formatter: Self.timeFormat) ")
                            .font(.system(size: 9))
                            .foregroundColor(.gray)
                            .padding(3)
                    }
                }
                .background(self.cloudColor)
                .cornerRadius(10)
                .padding(10)
                if self.cloudPosition == .sx {Spacer(minLength: 20)}
            }
    }

枚举:

enum CloudPosition {
    case dx,sx
}

如果文本是日志,则可以示例 1:

在此处输入图片说明

但如果它很短 示例 2:

在此处输入图片说明

如果我删除 Spacer() 示例 3,则聊天没问题,但时间不正确:

在此处输入图片说明

任何的想法? 谢谢

一种可能性......用Playground检查一下

没有太多解释,“技巧”是通过适当组合不同的堆栈、对齐、 .fixedSize(horizontal:, vertical:)Color.clear.frame(height:0)替换Spacer() 所有这些都基于消息文本实现了这种“自动”消息视图扩展。

import SwiftUI
import PlaygroundSupport

struct ContentView: View {

    var body: some View {

        VStack {

            HStack {
                Spacer()
                HStack {
                    VStack (alignment: .leading) {
                        Text("Lorem ipsum")
                            .font(.title)
                            .fixedSize()

                        Text("""
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
                        """)
                            .font(.system(size: 15))
                            .fixedSize(horizontal: false, vertical: true)

                        HStack {
                            Color.clear.frame(height: 0)
                            Text("22:13").fixedSize()
                        }
                    }
                    .padding()
                    .background(Color.yellow)
                    .cornerRadius(10)
                    .padding()

                }
                .scaledToFit()
            }
            .border(Color.red)

            HStack {
                Spacer()
                HStack {
                    VStack (alignment: .leading) {
                        Text("Lorem ipsum")
                            .font(.title)
                            .fixedSize()

                        Text("?")
                            .font(.system(size: 15))
                            .fixedSize(horizontal: false, vertical: true)

                        HStack {
                            Color.clear.frame(height: 0)
                            Text("22:13").fixedSize()
                        }
                    }
                    .padding()
                    .background(Color.yellow)
                    .cornerRadius(10)
                    .padding()

                }
                .scaledToFit()
            }
            .border(Color.red)

            HStack {
                Spacer()
                HStack {
                    VStack (alignment: .leading) {
                        Text("?")
                            .font(.title)
                            .fixedSize()

                        Text("Lorem ipsum")
                            .font(.system(size: 15))
                            .fixedSize(horizontal: false, vertical: true)

                        HStack {
                            Color.clear.frame(height: 0)
                            Text("22:13").fixedSize()
                        }
                    }
                    .padding()
                    .background(Color.yellow)
                    .cornerRadius(10)
                    .padding()

                }
                .scaledToFit()
            }
            .border(Color.red)

            Spacer()
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

结果:

在此处输入图片说明

相同的代码重复了 3 次,只是因为我很懒:-)

最后你可以使用类似的东西

struct Message<Header: View, Footer: View>: View {
    let header: Header
    let footer: Footer
    let message: String
    let color: Color

    var body: some View {
        HStack {
            Spacer()
            HStack {
                VStack (alignment: .leading) {
                    header.fixedSize()

                    Text(message)
                        .fixedSize(horizontal: false, vertical: true)

                    HStack {
                        color.frame(height: 0)
                        footer.fixedSize()
                    }
                }
                .padding()
                .background(color)
                .cornerRadius(10)
                .padding()

            }
            .scaledToFit()
        }
    }
}

使用@ViewBulder 作为页眉和页脚

struct MessageBuilder<Header, Footer>: View where Header: View, Footer: View {

    let header: () -> Header
    let footer: () -> Footer
    let message: String
    let color: Color

    init(@ViewBuilder header: @escaping () -> Header, @ViewBuilder footer: @escaping () -> Footer, message: String, color: Color) {
        self.header = header
        self.footer = footer
        self.message = message
        self.color = color
    }

    var body: some View {
        HStack {
            Spacer()
            HStack {
                VStack (alignment: .leading) {
                    header().fixedSize()

                    Text(message)
                        .fixedSize(horizontal: false, vertical: true)

                    HStack {
                        color.frame(height: 0)
                        footer().fixedSize()
                    }
                }
                .padding()
                .background(color)
                .cornerRadius(10)
                .padding()

            }
            .scaledToFit()
        }
    }

}

然后在你的代码中使用它

struct ContentView: View {

    var body: some View {

        VStack {

            Message(header: Text("Header").font(.title), footer: Text("22:13"), message: "long or short message text", color: Color.blue.opacity(0.2))

            MessageBuilder(header: {
                HStack {
                    Image(systemName: "square.and.arrow.down")
                    Text("Fred")
                }
            }, footer: {
                Image(systemName: "clock")
            }, message: "message text", color: Color.gray.opacity(0.2))

            Spacer()
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM