作为学习新技术的一部分,我试图在SwiftUI中实现我正在开发的应用程序的屏幕之一。我的布局很粗糙:
此元素应伸展以适应容器的大小(不同宽度的设备),并将在ScrollView中使用。
这是经过一番摸索之后我想到的初步解决方案:
这对于第一次尝试来说已经足够好了,但是我想通过将所有相关部分移动到单独的View中来重构View。除此之外,我希望新视图能够自动考虑到填充和以后可能添加的其他尺寸修改。
所以,这是一个幼稚的重写:
您可以很容易地发现,ScrollView中的GeometryReader假定了父级提供的大小,有效地隐藏了大多数View。
有几种针对这种情况的“肮脏”解决方案:为View设置固定的框架高度,设置近似于正确大小的纵横比(考虑到存在具有固定高度的Text视图,这有点棘手),保留GeometryReader作为主视图的最外层元素,并将宽度作为初始化参数传递给子视图。
我正在为这种特定的布局寻找一种“干净”的解决方案,也许是为了更深入地了解Views SwiftUI如何调节其尺寸–在WWDC视频中,据说父级View提出了尺寸,然后是子级视图返回它自己的大小;是否有办法以某种方式干扰该过程,或者全部通过私有API完成?
谢谢!
–Baglan
p.s。我以为UI预览之外的代码屏幕截图将是最具说明性的,但是请告诉我是否也应该提供代码段!
答案 0 :(得分:2)
我相信我的答案应该是评论,但是由于篇幅太长,我将其发布为答案。我回答similar question是否可以带来更多的启发。
使用 string baseUrl = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath+ "ExcelReports\\ReportLogo.png";
string data_1 = string.Empty;
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
// HttpContext.Current.Response.Write(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">");
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + reportname + ".xls");
HttpContext.Current.Response.Charset = "utf-8";
data_1 = "<font style='font-size:10.0pt; font-family:Calibri;'><BR><BR><BR><Table><tr><td><img src="+baseUrl+" alt='Red dot' /></td></tr></Table><BR><BR><BR><BR><Table><tr><td>Created By : " + createdby + "</td><td></td><td></td><td></td><td>Created DateTime : " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "</td></Table><BR><Table border='1' bgColor='#ffffff' " + "borderColor='#000000' cellSpacing='0' cellPadding='0' " + "style='font-size:10.0pt; font-family:Calibri; background:white;'> <TR>";
int columnscount = table.Columns.Count;
string data_2 = string.Empty;
for (int j = 0; j < columnscount; j++)
{
data_2 += "<Td>";
data_2 += "<B>";
data_2 += table.Columns[j].ToString();
data_2 += "<B>";
data_2 += "</Td>";
}
的哪个View
组件很重要。
如果您位于跨过屏幕尺寸的典型GeometryReader
内,则会得到屏幕本身的View
和width
。
如果您处于height
环境中,则会得到
ScrollView
的容器,以进行height
对齐.horizontal
的容器,以进行width
对齐通常,.vertical
未明确指定对齐方式默认为ScrollView
。
我想,设计决定是正确的。因为如果您从.vertical
中调用UIScrollView
,则在滚动视图中有一个 Content View 。在添加一些内容之前,您不会事先知道内容视图的大小。在UIKit
中,SwiftUI
内部的GeometryReader
模仿了ScrollView
中 Content View 的数学原理。这就是原因,您没有从几何读取器获得实际尺寸。
答案 1 :(得分:0)
此代码可以正常工作:
struct GeometryReaderExperiment: View {
var body: some View {
GeometryReader { geometry in
ScrollView {
Text("First")
DesignedFancy(parentGeometry: geometry, rectangleColor: .red)
Text("Second")
DesignedFancy(parentGeometry: geometry, rectangleColor: .green)
Text("Third")
DesignedFancy(parentGeometry: geometry, rectangleColor: .blue)
}
}
}
}
struct DesignedFancy: View {
var parentGeometry: GeometryProxy
var rectangleColor: Color
var body: some View {
HStack(alignment: .bottom) {
VStack {
Rectangle()
.aspectRatio(1, contentMode: .fit)
.foregroundColor(rectangleColor)
Text("One")
}
.frame(width: parentGeometry.size.width * 2/3)
VStack {
Rectangle()
.aspectRatio(contentMode: .fit)
.foregroundColor(rectangleColor)
Text("Two")
}
}
}
}
我认为问题在于DesignedFancy
不知道它有多少空间。因此,您必须通过变量提供此信息。结果是: