我有一个聊天示例,其中包含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
}
如果文本是log,就可以了示例1:
但是如果很短,示例2:
如果我删除了Spacer()示例3,则可以进行聊天,但是该聊天时间不在右侧:
有什么主意吗?谢谢
答案 0 :(得分:4)
一种可能性...与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()
}
}
}