如何在swiftui中将图像对准按钮顶部?

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

我希望在按下“删除按钮”时在每个按钮的右上角添加一个“垃圾桶”图像,以便当用户点击垃圾桶图像时,该按钮将从vstack中删除。我想我应该使用zstack定位废纸image图像,但目前不知道如何。下面显示了垃圾桶图像在每个按钮中应位于的位置。

enter image description here

[另外,当我按下'Delete Button'时,似乎每个按钮的文本大小和与另一个按钮的间距都略有变化。我该如何克服这个问题?当单击“删除按钮”时,按钮位置,间距,文本大小应保持不变。

struct someButton: View {
    @Environment(\.editMode) var mode
    @ObservedObject var someData = SomeData()
    @State var newButtonTitle = ""
    @State var isEdit = false

    var body: some View {
        NavigationView{
//            List{ // VStack
                VStack{
                    VStack{
                        ForEach(Array(someData.buttonTitles.keys.enumerated()), id: \.element){ ind, buttonKeyName in
//

                               Button(action: {
                                self.someData.buttonTitles[buttonKeyName] = !self.someData.buttonTitles[buttonKeyName]!
                                print("Button pressed! buttonKeyName is: \(buttonKeyName) Index is \(ind)")
                                print("bool is \(self.someData.buttonTitles[buttonKeyName]!)")



                               }) {
                                   HStack{ //HStack, ZStack
                                    if self.isEdit{
                                           Image(systemName: "trash")
                                            .foregroundColor(.red)
                                            .onTapGesture{
                                                print("buttonkey \(buttonKeyName) will be deleted")
                                                self.deleteItem(ind: ind)
                                            }
                                    }


                                    Text(buttonKeyName)
//                                           .fontWeight(.semibold)
//                                           .font(.title)
                                   }



                               }
                               .buttonStyle(GradientBackgroundStyle(isTapped: self.someData.buttonTitles[buttonKeyName]!))
                               .padding(.bottom, 20)



                        }
                    }


                    HStack{
                        TextField("Enter new button name", text: $newButtonTitle){
                            self.someData.buttonTitles[self.newButtonTitle] = false
                            self.newButtonTitle = ""
                        }
                    }


                }
                .navigationBarItems(leading: Button(action: {self.isEdit.toggle()}){Text("Delete Button")},
                                    trailing: EditButton())

//                .navigationBarItems(leading: Button(action: {}){Text("ergheh")})
//            }

        }

    }


    func deleteItem(ind: Int) {
        let key = Array(someData.buttonTitles.keys)[ind]
        print(" deleting ind \(ind), key: \(key)")
       self.someData.buttonTitles.removeValue(forKey: key)
       }


}




struct GradientBackgroundStyle: ButtonStyle {
    var isTapped: Bool

    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .frame(maxWidth: .infinity, maxHeight: 50)
            .padding()
            .foregroundColor(isTapped ? Color.blue : Color.black)
            .background(LinearGradient(gradient: Gradient(colors: [Color("DarkGreen"), Color("LightGreen")]), startPoint: .leading, endPoint: .trailing))

            .cornerRadius(40)
            .overlay(RoundedRectangle(cornerRadius: 40)
                .stroke(isTapped ? Color.blue : Color.black, lineWidth: 4))
            .shadow(radius: 40)
            .padding(.horizontal, 20)
            .scaleEffect(configuration.isPressed ? 0.9 : 1.0)
//


    }
}



class SomeData: ObservableObject{
    @Published var buttonTitles: [String: Bool] = ["tag1": false, "tag2": false]
}
swift button swiftui
2个回答
0
投票

这里是可能方法的演示。使用Xcode 11.4 / iOS 13.4(带有一些复制代码)进行了测试]

demo

var body: some View {
       Button(action: { }) {
        Text("Name")
       }
       .buttonStyle(GradientBackgroundStyle(isTapped: tapped))
       .overlay(Group {
            if self.isEdit {
                ZStack {
                    Button(action: {print(">> Trash Tapped")}) {
                       Image(systemName: "trash")
                            .foregroundColor(.red).font(.title)
                    }.padding(.trailing, 40)
                    .alignmentGuide(.top) { $0[.bottom] }
                }.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)

            }
       })
       .padding(.bottom, 20)
}

0
投票

解决方案之一是使用GeometryReaderZStack的组合:

ForEach(Array(someData.buttonTitles.keys.enumerated()), id: \.element) { ind, buttonKeyName in
    Button(action: {
        self.someData.buttonTitles[buttonKeyName] = !self.someData.buttonTitles[buttonKeyName]!
        print("Button pressed! buttonKeyName is: \(buttonKeyName) Index is \(ind)")
        print("bool is \(self.someData.buttonTitles[buttonKeyName]!)")

    }) {
        GeometryReader { geo in
            ZStack {
                Text(buttonKeyName)
                if self.isEdit {
                    Image(systemName: "trash")
                        .foregroundColor(.red)
                        .offset(x: geo.size.width * 4 / 9, y: -1 * geo.size.height / 2)
                        .onTapGesture {
                            print("buttonkey \(buttonKeyName) will be deleted")
                            self.deleteItem(ind: ind)
                        }
                }
            }
        }
    }
    .buttonStyle(GradientBackgroundStyle(isTapped: self.someData.buttonTitles[buttonKeyName]!))
    .padding(.bottom, 20)
}

您可以通过设置xy参数来调整确切的相对位置:

.offset(x: geo.size.width * 4 / 9, y: -1 * geo.size.height / 2)
© www.soinside.com 2019 - 2024. All rights reserved.