Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SwiftUI:如何找到图像的高度并使用它设置帧的大小_Swift_Image_Swiftui_Geometryreader - Fatal编程技术网

SwiftUI:如何找到图像的高度并使用它设置帧的大小

SwiftUI:如何找到图像的高度并使用它设置帧的大小,swift,image,swiftui,geometryreader,Swift,Image,Swiftui,Geometryreader,因此,我一直在试图找出如何在SwiftUI中找到图像的高度,但没有成功。基本上我有纵向/横向图像,纵向图像我想显示在大约600磅高,而横向图像我想显示,所以使用图像的宽度,所以高度是任意的。也就是说,我希望它在GeometryReader中,因为我使用的偏移量使用它,所以当你向下滚动时,图像不会滚动,但如果你向上滚动,它会滚动。我不相信我可以共享图像,但无论如何,这应该足够的代码来成功运行它 struct ContentView: View { @Environment(\.p

因此,我一直在试图找出如何在SwiftUI中找到图像的高度,但没有成功。基本上我有纵向/横向图像,纵向图像我想显示在大约600磅高,而横向图像我想显示,所以使用图像的宽度,所以高度是任意的。也就是说,我希望它在GeometryReader中,因为我使用的偏移量使用它,所以当你向下滚动时,图像不会滚动,但如果你向上滚动,它会滚动。我不相信我可以共享图像,但无论如何,这应该足够的代码来成功运行它

struct ContentView: View {
    
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
  
    var backButton: some View {
        Button(action: {
            withAnimation {
                self.mode.wrappedValue.dismiss()
            }
        }) {
            Image(systemName: "chevron.left.circle.fill")
                .opacity(0.8)
                .font(.system(size: 30))
                .foregroundColor(.black)
                .background(Color.gray.mask(Image(systemName: "chevron.left").offset(x: 9.4, y: 7.6)))
                
        }
    }

    var body: some View {
        ScrollView(showsIndicators: false) {
            
                GeometryReader { geometry in
                    Image("image1")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(maxWidth: UIScreen.main.bounds.width, minHeight: 350, maxHeight: 600, alignment: .top)
                        .clipped()
                        .overlay(
                            Rectangle()
                                .foregroundColor(.clear)
                                .background(LinearGradient(gradient: Gradient(colors: [.clear, .white]), startPoint: .center, endPoint: .bottom))
                        )
                       .offset(y: geometry.frame(in: .global).minY > 0 ? -geometry.frame(in: .global).minY : 0)

                }
                .frame(minWidth: UIScreen.main.bounds.width, maxWidth: UIScreen.main.bounds.width, minHeight: 350, idealHeight: 600, maxHeight: 600)

                //Message
                VStack(alignment: .leading) {
                    Text("\(07/22/20) - Day \(1)")
                        .font(.body)
                        .fontWeight(.light)
                        .foregroundColor(Color.gray)
                        .padding(.leading)
                    Text("what I Love)
                        .font(.title)
                        .fontWeight(.bold)
                        .padding([.leading, .bottom])

                    Text("paragraph")
                        .padding([.leading, .bottom, .trailing])
                }
   
        }
        .edgesIgnoringSafeArea(.all)
        .navigationBarBackButtonHidden(true)
        .navigationBarItems(leading: backButton)
    }
}
struct ContentView:View{
@环境(\.presentationMode)变量模式:绑定
var backButton:一些视图{
按钮(操作:{
动画片{
self.mode.wrappedValue.disclose()文件
}
}) {
图像(系统名称:“V形。左。圆。填充”)
.不透明度(0.8)
.font(.system(大小:30))
.foregroundColor(.黑色)
.背景(颜色.灰色.遮罩(图像(系统名称:“V形.左”).偏移量(x:9.4,y:7.6)))
}
}
var body:一些观点{
滚动视图(显示指示器:false){
GeometryReader{中的几何体
图像(“图像1”)
.可调整大小()
.aspectRatio(内容模式:.fill)
.frame(最大宽度:UIScreen.main.bounds.width,最小高度:350,最大高度:600,对齐方式:顶部)
.clipped()
.覆盖(
矩形()
.foregroundColor(.clear)
.background(LinearGradient(渐变:渐变(颜色:[.clear、.white]),起点:。中心,终点:。底部))
)
.offset(y:geometry.frame(in:.global).minY>0?-geometry.frame(in:.global).minY:0)
}
.frame(最小宽度:UIScreen.main.bounds.width,最大宽度:UIScreen.main.bounds.width,最小高度:350,理想高度:600,最大高度:600)
//信息
VStack(对齐:。前导){
正文(“\(07/22/20)-第\(1)天”)
.font(.body)
.fontWeight(.light)
.foregroundColor(颜色.灰色)
.padding(.leading)
文本(“我爱的东西”)
.font(.title)
.fontWeight(.粗体)
.padding([.leading,.bottom])
案文(“段落”)
.padding([.leading、.bottom、.training])
}
}
.edgesIgnoringSafeArea(.all)
.navigationBarBackButtonHidden(真)
.navigationBarItems(前导:backButton)
}
}
任何帮助都将不胜感激

编辑:这里有两张图片供参考-很抱歉,我没有意识到你能做到,尽管我本应该想到这一点


如果我理解正确,您需要图像的大小,以便可以在自己的帧中使用它的尺寸?您可以创建一个函数,该函数接收图像名称并返回所需图像,同时还可以为帧中可以使用的
宽度
高度
设置
@State
变量

    @State var width: CGFloat = 0
    @State var height: CGFloat = 0
    
    func image(_ name: String) -> UIImage {
        let image = UIImage(named: name)!
        let width = image.size.width
        let height = image.size.height

        DispatchQueue.main.async {
            if width > height {
                // Landscape image
                // Use screen width if < than image width
                self.width = width > UIScreen.main.bounds.width ? UIScreen.main.bounds.width : width
                // Scale height
                self.height = self.width/width * height
            } else {
                // Portrait
                // Use 600 if image height > 600
                self.height = height > 600 ? 600 : height
                // Scale width
                self.width = self.height/height * width
            }
        }
        return image
    }
编辑:添加了
DispatchQueue.main.async
块,作为“在视图更新期间修改状态”警告的快速修复。虽然有效,但可能不是解决此问题的最佳方法。最好将图像置于其自己的
@state
中,并在视图的
onAppear
方法中进行设置

编辑2:将图像移动到它自己的
@State
var中,我认为这是一个更好的解决方案,因为它将使视图更加可重用,因为您可以传递图像,而不是在视图中硬编码图像的名称

    @State var image: UIImage {
        didSet {
            let width = image.size.width
            let height = image.size.height
            DispatchQueue.main.async {
                if width > height {
                    // Landscape image
                    self.width = width > UIScreen.main.bounds.width ? UIScreen.main.bounds.width : width
                    self.height = self.width/width * height
                } else {
                    
                    self.height = height > 600 ? 600 : height
                    self.width = self.height/height * width
                }
            }
        }
    }
用法:

    GeometryReader { geometry in
        Image(uiImage: image("image1"))
            .resizable()
            .aspectRatio(contentMode: .fill)
            .frame(width: width, height: height)
            .overlay(
                Rectangle()
                    .foregroundColor(.clear)
                    .background(LinearGradient(gradient: Gradient(colors: [.clear, .white]), startPoint: .center, endPoint: .bottom))
            )
            .offset(y: geometry.frame(in: .global).minY > 0 ? -geometry.frame(in: .global).minY : 0)
    GeometryReader { geometry in
        Image(uiImage: image)
            .resizable()
            .aspectRatio(contentMode: .fill)
            .frame(width: width, height: height)
            .overlay(
                Rectangle()
                    .foregroundColor(.clear)
                    .background(LinearGradient(gradient: Gradient(colors: [.clear, .white]), startPoint: .center, endPoint: .bottom))
            )
            .offset(y: geometry.frame(in: .global).minY > 0 ? -geometry.frame(in: .global).minY : 0)
必须通过传入UIImage来更新ContentView的声明方式:

ContentView(image: UIImage(named: "image0")!)

你能插入一张图片来理解你想要的最终结果吗?否则很难帮助你。@Gius抱歉,我没有意识到我能!我还是新手哈哈!但我只是一张肖像和风景图片!如果我理解正确,你希望肖像图片显示的最大高度为600,而landscape图像您希望以最大宽度显示它们,对吗?是的,这非常有效!我唯一更改的是将语句中其他部分的self.width改为等于UiScreen.main.bounds.width,以便它适合我所有的肖像图像宽度!非常感谢!!尽管经过进一步测试-这似乎在预览,这很奇怪!我遇到了“在视图更新期间修改状态,这将导致未定义的行为”的问题。“由于我的图像没有加载到应用程序中,你知道如何修复吗?哎呀,我应该在sim卡中运行它,很抱歉!我会看一看,看看有什么需要更改。我更新了答案,以便在主线程上更新宽度和高度。这将修复
修改状态
警告,但可能有更好的方法。如果我提出更好的解决方案,将会更新。很高兴听到。我做了第二次更新,
图像
处于它自己的
@状态
变量,这使得它更易于重用,但在使用它时,您必须将UIImage传递到ContentView中。