自定义视图在SwiftUI中无法忽略.frame()修饰符。

huangapple go评论56阅读模式
英文:

Custom View cannot ignores .frame() modifier in SwiftUI

问题

我试图在SwiftUI中创建一个自定义视图,它看起来像这样:

struct CanvasRowView: View {
    
    var body: some View {
        HStack(alignment: .center) {
            ForEach(viewModel.canvasElements) { canvasElement in
                switch canvasElement.type {
                case .image:
                    Image(systemName: "photo")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .font(.largeTitle)
                    
                case .spacer:
                    Spacer()
                    
                case .placeholder:
                    Color.blue
                        .frame(width: 3, height: 10)
                }
            }
        }        
    }
}

到目前为止一切顺利,但当我尝试在上面的`View`中添加`.frame(100, 100)`时,该修饰符被忽略,视图的大小为0
此外,我尝试将代码包装在`GeometryReader`中,但似乎它设置了最大可用大小,这也不是我想要的。

更具体地说,我希望我的自定义`View`具有内在内容大小(就像`HStack`的行为一样)。

编辑:我使用它的方式(例如,在预览中或在另一个预览中)

CanvasRowView()
    .frame(width: 100, height: 100)

还值得一提的是,当我在`viewModel.canvasElements`中有元素时(该属性被`ForEach`循环),一切都按预期工作。问题仅在HStack为空时出现
英文:

I am trying to create a custom view in SwiftUI that looks like this:

struct CanvasRowView: View {
	
var body: some View {
	HStack(alignment: .center) {
		ForEach(viewModel.canvasElements) { canvasElement in
			switch canvasElement.type {
			case .image:
				Image(systemName: "photo")
					.resizable()
					.aspectRatio(contentMode: .fit)
					.font(.largeTitle)
					
			case .spacer:
				Spacer()
					
			case .placeholder:
				Color.blue
					.frame(width: 3, height: 10)
			}
		}
	}		
}

So far so good, but when I'm trying to add .frame(100, 100) to the above View, the modifier is ignored and the view has a size of 0.
Also, I tried to wrap the code inside of GeometryReader but it seems that it sets the size of maximum available and this is also something I am not looking for.

To be more specific I am looking for my my custom View to have a intrinsic content size (much like HStack behaves)

Edit: The way I use it (e.g in a Preview or in another preview)

CanvasRowView()
		.frame(width: 100, height: 100)

Also worth mentioning is that when I have elements in viewModel.canvasElements (the property is ForEached) everything is working as expected. The problem only comes when HStack is empty.

答案1

得分: 1

如果您在CanvasRowView.body的末尾放置.frame(width: 100, height: 100),那么CanvasRowView的大小将为100x100。如果没有元素,HStack的大小仍然为零。HStack始终是其元素的大小(加上间距)。您无法改变HStack的大小,除非改变其内容的大小。但如果您希望CanvasRowView具有特定的大小,您可以将HStack包装在一个frame中来设置它,因为Frames根据其参数确定其大小。

您可能误解了frame的工作原理。它不会设置视图的大小。它一个视图。它有一个大小,并将该大小提供给其内容(然后内容选择自己的大小),然后Frame将内容定位在自身内部。没有通用的方法来设置视图的大小。每个视图都根据其父视图提供的大小自行设置其大小,通常是基于其父视图提供的大小。

英文:

If you put .frame(width: 100, height: 100) at the end of CanvasRowView.body, then CanvasRowView will have a size of 100x100. The HStack will still have a size of zero if there are no elements. An HStack is always the size of its elements (plus spacing). You cannot change the size of an HStack other than by changing the size of its content. But if you want CanvasRowView to be a particular size, you would wrap the HStack in a frame to set that, since Frames determine their size based on their parameters.

You may be misunderstanding how frame works. It does not set the size of a View. It is a View. It has a size, and it offers that size to its content (which then chooses its own size), and then the Frame positions the content inside itself. There is no general way to set a View's size. Every View sets its own size, often based on the size its parent offered.

huangapple
  • 本文由 发表于 2023年6月1日 02:17:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76376302.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定