按下按钮时是什么导致我的视图调整大小?

问题描述 投票:0回答:1

我的 iOS 应用程序具有可自定义的用户颜色设置。我制作了一个用于颜色选择的视图。该视图具有标题按钮,用于在用户要更改的颜色设置和可选颜色选项网格之间进行选择。 普通颜色选择器
当我按下 在所选颜色设置之间切换时,视图大小会调整。 [更改颜色选择后拉伸的颜色选择器](https://i.sstatic.net/26nFPR5M.png 我无法弄清楚是什么原因造成的,希望外部/更有经验的观点能够抓住它。

import SwiftUI

struct ColorSelect: View {
    
    //either 1 or 2 to represent which of the User's 2 colors is to be changed
    @State var colorSelection: Int = 1
    //Bool for the parent view
    @Binding var windowVisible: Bool
    //Color 1 Binding so parent view can update it's Colors
    @Binding var color1Link: Color
    //Color 2 Binding so parent view can update it's Colors
    @Binding var color2Link: Color

    //list of rgb values for displayed colors that is interpreted by func convertColor
    let colors = [144012063, //dark red
                  255049049, //red
                  255092000, //orange
                  255195000, //dark orange
                  255240031, //yellow
                  170255000, //dark green
                  057255020, //green
                  188237250, //very light blue
                  004217255, //blue
                  031081255, //dark blue
                  125018255, //dark purple
                  176038255, //purple
                  255016240, //pink
                  255189186, //peach
                  255255255, //white
                  170170170 //gray
                  ]
    
    var body: some View {
        
        //array for colorLinks
        var colorSlots = [color1Link, color2Link]
        //labels for User color setting selection buttons
        let col1Label = Text("Color 1")
            .font(.system(.title2,
                          design: .rounded))
            .fontWeight(.heavy)
            .foregroundStyle(.white)
        
        let col2Label = Text("Color 2")
            .font(.system(.title2,
                          design: .rounded))
            .fontWeight(.heavy)
            .foregroundStyle(.white)
        
        ZStack {
            //background visuals
            RoundedRectangle(cornerRadius: 34.0)
                .foregroundStyle(.white)
                .padding(10)
            
            RoundedRectangle(cornerRadius: 30.0)
                .foregroundStyle(.black)
                .padding(14)
            
            VStack {
                //User Color slot selection banner
                HStack {
                    Spacer()
                    
                    //selected button will apply Color change to related User Color slot
                    Button {
                        colorSelection = 1
                    } label: {
                        if(colorSelection == 1) {
                            col1Label
                                .underline()
                        } else {
                            col1Label
                        }
                    }
                    
                    Spacer()
                    
                    Text("|")
                        .font(.system(.title2,
                                      design: .rounded))
                        .fontWeight(.heavy)
                        .foregroundStyle(.white)
                    
                    Spacer()
                    
                    Button {
                        colorSelection = 2
                    } label: {
                        if(colorSelection == 2) {
                            col2Label
                                .underline()
                        } else {
                            col2Label
                        }
                    }
                    
                    Spacer()
                }
                .padding()
                
                //4x4 Grid of color options
                LazyVGrid(columns: [GridItem(spacing: 5), 
                                    GridItem(spacing: 5), 
                                    GridItem(spacing: 5), 
                                    GridItem(spacing: 5)], spacing: 5) {
                    
                    ForEach(colors, id: \.self) { color in
                        
                        //actual Color object for rgb Int in array
                        let trueColor = convertColor(rgb: color)
                        //display for selectable color option
                        let buttonView = RoundedRectangle(cornerRadius: 8)
                                             .foregroundStyle(trueColor)
                                             .shadow(color: trueColor, radius: 7)
                        //determines if Color selection is User's selected Color
                        //    this has a separate issue where the User's Color
                        //    isn't updated because the change isn't read from defaults
                        @State var currColor = color == 
                                               UserDefaults.standard.integer(forKey: 
                                               "color\(colorSelection)rgb")
                        
                        //Display button if Color is not selected, else a view with check
                        if(!currColor) {
                            Button {
                                UserDefaults.standard.set(color,
                                                      forKey: "color\(colorSelection)rgb")
                                colorSlots[colorSelection - 1] = convertColor(rgb: color)
                            } label: {
                                buttonView
                            }
                            .aspectRatio(contentMode: .fit)
                        } else {
                            //makes selected color tile an inactive view with checkmark
                            ZStack {
                                buttonView
                                
                                Image(systemName: "checkmark")
                                    .resizable()
                                    .foregroundStyle(.white)
                                    .padding()
                            }
                        }
                    }
                }
            }
            .padding(20)
            
            //'x' escape button in top right
            VStack {
                HStack {
                    Spacer()
                    
                    Button {
                        windowVisible = false
                    } label: {
                        Image(systemName: "x.circle")
                            .foregroundColor(.white)
                            .shadow(color: .white,
                                    radius: 10)
                    }
                }
                
                Spacer()
            }
        }
        .aspectRatio(contentMode: .fit)
    }
    
    //takes the local Int interpretation of rgb and returns the associated Color object
    func convertColor(rgb: Int) -> Color {
        let b = Double(rgb % 1000) / 255
        let g = Double((rgb % 1000000) / 1000) / 255
        let r = Double((rgb % 1000000000) / 1000000) / 255
        
        return Color(red: r, green: g, blue: b)
    }
    
}

#Preview {
    ColorSelect(windowVisible: Binding.constant(true),
                color1Link: Binding.constant(.black),
                color2Link: Binding.constant(.black))
}

(我的代码还存在其他问题,例如颜色选择的实际选择的颜色没有更新,因为它与 UserDefaults 相关并且无法实际观看更改,但这不是我现在关注的重点)

显而易见的是,在颜色选择之间切换时视图不应改变大小。我尝试将它放入框架中,但随后它的宽度只是缩小,而不是高度增加。我尝试删除垫片,看看它们在状态更新时是否会以某种方式改变大小,但这也没有解决问题。我盯着我的 Color 2 按钮操作以跟踪它所做的任何更改,但仍然没有找到任何线索。

ios swift swiftui struct formatting
1个回答
0
投票

当我运行应用程序模拟器时,您描述的调整大小问题并没有发生在我身上,但是,它确实在预览中偶尔发生。我怀疑预览的加载方式可能与作为应用程序运行时的加载方式不同,因此我不会担心它。

至于

UserDefaults
bug,可以使用
@AppStorage
属性来修复。例如,此代码将立即更新所选颜色:

struct ColorSelect: View {
    @AppStorage("color1rgb") var color1Selection: Int = -1
    @AppStorage("color2rgb") var color2Selection: Int = -1
    /* other variables... */

    var body: some View {
        /* rest of the view... */
        ForEach(colors, id: \.self) { color in
            let currColor = colorSelection == 1 ?
                            color == color1Selection :
                            color == color2Selection
        }
        /* rest of the view... */
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.