ios - 尝试使用几何阅读器和导航栏获得全宽视图 - SwiftUI
问题描述
我有 2HStack
使用几何阅读器将它们均匀地分成 2 个部分,这些部分嵌入到 aVStack
中,我正在尝试创建类似于下图第一张的布局(iPad 上的横向模式)。
但是,我正在努力让HStack
's 像中间的网格会议一样排列。我还有一个NavigationView
侧边栏,它可以与HStack
s 一起呈现,因此理想情况下 2 个图像会改变宽度但保持它们的高度,而不会挤压或拉伸图像。我曾尝试使用clipped()
.
下面的第二张图片是我运行代码时得到的。我已将此示例中的图像替换为 SFSymbol 以使其更易于调试。
这是NavigationView
我的侧边栏ContentView
:
struct SideBar: View {
var body: some View {
NavigationView {
List {
NavigationLink(destination: DetailView()) {
Label("Products", systemImage: "printer")
}
Label("Comparison", systemImage: "simcard.2")
Label("Search", systemImage: "magnifyingglass")
}
.listStyle(SidebarListStyle())
.navigationTitle("Navigation")
DetailView()
}
}
}
这是包含内容的主视图:
struct DetailView: View {
let title = "This is a title"
let paragraph = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
let image = "dot.squareshape.fill"
let intPadding: CGFloat = 10
let extPadding: CGFloat = 40
var body: some View {
VStack(spacing: 0){
GeometryReader { geometry in
HStack(alignment: .top, spacing: 0){
Image(systemName:image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width / 2)
.clipped()
VStack(alignment: .leading) {
Text(title)
.font(.custom("Avenir-Heavy", size: 30))
.multilineTextAlignment(.leading)
.padding(.leading, intPadding)
Text(paragraph)
.font(.custom("Avenir", size: 16))
.multilineTextAlignment(.leading)
.lineSpacing(10)
.padding(.leading, intPadding)
.padding(.trailing, extPadding)
}
.frame(width: geometry.size.width / 2)
}
}
GeometryReader { geometry in
HStack(alignment: .top, spacing: 0){
Text(paragraph)
.font(.custom("Avenir", size: 16))
.multilineTextAlignment(.leading)
.lineSpacing(10)
.frame(width: geometry.size.width / 2)
.padding(.top, intPadding)
.padding(.trailing, intPadding)
.padding(.leading, extPadding)
Image(systemName:image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width / 2)
.offset(x: -intPadding)
.clipped()
}
}
}
}
}
编辑:
黑色方块代表图像要去的地方,我没有放黑色方块。所以上面提到的挤压和拉伸的想法应该看起来像下面的图像,所以它实际上并没有拉伸或挤压图像只是边界框:
解决方案
这是一个可能的方法的演示 - 使用Color.clear
,因为它可以平等地填充所有可用的内容,并在叠加层中包含内容。
使用 Xcode 12.1 / iOS 14.1 准备
var body: some View {
VStack(spacing: 0) {
Color.clear.overlay(
HStack(spacing: 0) {
Color.clear.overlay(
Image(systemName:image)
.resizable()
.aspectRatio(contentMode: .fit)
)
Color.clear.overlay(
VStack(alignment: .leading) {
Text(title)
.font(.custom("Avenir-Heavy", size: 30))
.multilineTextAlignment(.leading)
.padding(.leading, intPadding)
Text(paragraph)
.font(.custom("Avenir", size: 16))
.multilineTextAlignment(.leading)
.lineSpacing(10)
.padding(.leading, intPadding)
.padding(.trailing, extPadding)
}
, alignment: .top)
},
alignment: .top)
Color.clear.overlay(
HStack(spacing: 0) {
Color.clear.overlay(
Text(paragraph)
.font(.custom("Avenir", size: 16))
.multilineTextAlignment(.leading)
.lineSpacing(10)
.padding(.top, intPadding)
.padding(.trailing, intPadding)
.padding(.leading, extPadding)
, alignment: .top)
Color.clear.overlay(
Image(systemName:image)
.resizable()
.aspectRatio(contentMode: .fit)
.clipped()
, alignment: .top)
}
)
}
}
更新:全屏变体
VStack(spacing: 0) {
Color.clear.overlay(
HStack(spacing: 0) {
Color.black
// .overlay(
// Image(systemName:image)
// .resizable()
// .aspectRatio(contentMode: .fit)
// )
Color.clear.overlay(
VStack(alignment: .leading) {
Text(title)
.font(.custom("Avenir-Heavy", size: 30))
.multilineTextAlignment(.leading)
.padding(.leading, intPadding)
Text(paragraph)
.font(.custom("Avenir", size: 16))
.multilineTextAlignment(.leading)
.lineSpacing(10)
.padding(.leading, intPadding)
.padding(.trailing, extPadding)
}
, alignment: .top)
},
alignment: .top)
Color.clear.overlay(
HStack(spacing: 0) {
Color.clear.overlay(
Text(paragraph)
.font(.custom("Avenir", size: 16))
.multilineTextAlignment(.leading)
.lineSpacing(10)
.padding(.top, intPadding)
.padding(.trailing, intPadding)
.padding(.leading, extPadding)
, alignment: .top)
Color.black
// .overlay(
// Image(systemName:image)
// .resizable()
// .aspectRatio(contentMode: .fit)
// .clipped()
// , alignment: .top)
}
)
}
.navigationBarHidden(true)
.edgesIgnoringSafeArea(.all)
}
推荐阅读
- oracle - 我们如何通过 PLSQL 逐行拆分 CLOB(有些行超过 32K 个字符)?
- flutter - Flutter Build 问题:突然为 Flutter App 构建 APK 失败
- json - 这是名为 'abc' 的 json 文件。我想访问文件之后我想访问 a,b,c,d,e,f 的值。如何以 groovy 语言访问?
- crystal-reports - 水晶报表:如何将子报表组中的总金额按货币带入主报表?以及如何按货币计算总和?
- java - 将用户分配到会议。字符串与集合类型不匹配的问题
- python - CatBoostClassifier 静态特征顺序
- rust - 实现迭代器特征时如何修复生命周期不匹配?
- android - 我无法设置 Safe Args 默认值
- gpu - 如何使用 icc 编译 gpu 卸载代码
- java - 胶水作业失败,随机出现“未找到 JohnSnowLabs spark-nlp 依赖项”错误