SwiftUI:将视图对齐到其父级的中心

时间:2019-12-02 20:39:55

标签: ios swift swiftui

我有一系列要在SwiftUI列表中显示的项目,如下所示:

struct MissionCell_Previews: PreviewProvider {
    static var missions: [Mission] = [
        Mission(name: "Cassini",
                launchDate: "10/15/97",
                launchLocation: "Cape Canaveral",
                missionEndDate: "09/15/17",
                status: "Past"),
        Mission(name: "Galaxy Evolution Explorer",
                launchDate: "04/28/03",
                launchLocation: "Cape Canaveral",
                missionEndDate: "06/28/13",
                status: "Past"),
        Mission(name: "IRAS",
                launchDate: "01/25/83",
                launchLocation: "Vandenberg",
                missionEndDate: "11/21/83",
                status: nil),
        Mission(name: "NuSTAR",
                launchDate: "06/13/12",
                launchLocation: "Central Pacific Ocean",
                missionEndDate: nil,
                status: "Current"),
        Mission(name: "Voyager 1",
                launchDate: "09/05/77",
                launchLocation: "Central Pacific Ocean",
                missionEndDate: nil,
                status: nil)
    ]

    static var previews: some View {
        List {
            ForEach(missions) { mission in
                MissionCell(mission: mission)
            }
        }
    }
}

我正在使用以下代码创建单元格视图:

struct MissionCell: View {
    var mission: Mission

    var body: some View {
        VStack(alignment: .missionOptionalInfoAlignment, spacing: 2) {
            Text(mission.name)
                .lineLimit(1)
                .truncationMode(.middle)
            HStack(alignment: .top) {
                VStack(alignment: .leading) {
                    HStack {
                        Image(systemName: "calendar")
                            .foregroundColor(Color(UIColor.systemGray))
                        Text(mission.launchDate)
                            .foregroundColor(Color(UIColor.systemGray))
                    }
                    HStack {
                        Image(systemName: "location.fill")
                            .foregroundColor(Color(UIColor.systemGray))
                        Text(mission.launchLocation)
                            .foregroundColor(Color(UIColor.systemGray))
                    }

                }
                VStack(alignment: .leading) {
                    if mission.missionEndDate != nil {
                        HStack {
                            Image(systemName: "hand.raised.slash.fill")
                                .foregroundColor(Color(UIColor.systemGray))
                            Text(mission.missionEndDate!)
                                .foregroundColor(Color(UIColor.systemGray))
                        }
                    }
                    if mission.status != nil {
                        HStack {
                            Image(systemName: "checkmark")
                                .foregroundColor(Color(UIColor.systemGray))
                            Text(mission.status ?? "")
                                .foregroundColor(Color(UIColor.systemGray))
                        }
                    }
                }
            }
        }
        .padding([.leading, .trailing], 16)
    }
}

我要实现2种对齐方式:

  1. missionEndDatestatus值的对齐。我已经成功地使用Stack对齐实现了这一点。
  2. 显示HStackmissionEndDate值的statusMissionCell视图中心的对齐。我无法做到这一点。我尝试使用自定义对齐方式,但是我无法使用自定义对齐方式,因为没有任何可以将此HStack与之对齐的方式(即,我不能告诉它与之对齐的方式)。家长中心)。这是目前的图片: Image showing incomplete alignment

我曾考虑过使用GeometryReader来获取顶级VStack的几何图形,但是随后我丢失了所有间距信息,无法再使用对齐方式。

是否有一种方法可以使子视图在自定义视图的树的深处对齐,使其位于其父容器的中心?

1 个答案:

答案 0 :(得分:1)

这是Zstack的一种情况:

  struct  ListMissionView : View{


                    var missions: [Mission] = [
                        Mission(name: "Cassini",
                                launchDate: "10/15/97",
                                launchLocation: "Cape Canaveral",
                                missionEndDate: "09/15/17",
                                status: "Past"),
                        Mission(name: "Galaxy Evolution Explorer",
                                launchDate: "04/28/03",
                                launchLocation: "Cape Canaveral",
                                missionEndDate: "06/28/13",
                                status: "Past"),
                        Mission(name: "IRAS",
                                launchDate: "01/25/83",
                                launchLocation: "Vandenberg",
                                missionEndDate: "11/21/83",
                                status: nil),
                        Mission(name: "NuSTAR",
                                launchDate: "06/13/12",
                                launchLocation: "Central Pacific Ocean",
                                missionEndDate: nil,
                                status: "Current"),
                        Mission(name: "Voyager 1",
                                launchDate: "09/05/77",
                                launchLocation: "Central Pacific Ocean",
                                missionEndDate: nil,
                                status: nil)
                    ]


                        var body: some View {
                            GeometryReader{ proxy in
                      List {
                            ForEach(self.missions, id: \.name) { mission in
                               MissionCell(mission: mission, proxy:  proxy)
                           }
                        }
                       }
                }
                }


            struct MissionCell: View {
                var mission: Mission

                var proxy: GeometryProxy
                var body: some View {

                   // VStack(alignment: .missionOptionalInfoAlignment, spacing: 2) {
                    VStack(alignment: .leading, spacing: 2) {
                        Text(self.mission.name)
                            .lineLimit(1)
                            .truncationMode(.middle)

                        ZStack(alignment: .topLeading) {

                            VStack(alignment: .leading) {
                                HStack {
                                    Image(systemName: "calendar")
                                        .foregroundColor(Color(UIColor.systemGray))
                                    Text(self.mission.launchDate)
                                        .foregroundColor(Color(UIColor.systemGray))
                                }
                                HStack {
                                    Image(systemName: "location.fill")
                                        .foregroundColor(Color(UIColor.systemGray))
                                    Text(self.mission.launchLocation)
                                        .foregroundColor(Color(UIColor.systemGray))
                                }

                            }

                            VStack(alignment: .leading) {

                                if self.mission.missionEndDate != nil {
                                    HStack {
                                        Image(systemName: "hand.raised.slash.fill")
                                            .foregroundColor(Color(UIColor.systemGray))
                                        Text(self.mission.missionEndDate!)
                                            .foregroundColor(Color(UIColor.systemGray))
                                    }
                                }
                                if self.mission.status != nil {
                                    HStack {
                                        Image(systemName: "checkmark")
                                            .foregroundColor(Color(UIColor.systemGray))
                                        Text(self.mission.status ?? "")
                                            .foregroundColor(Color(UIColor.systemGray))

                                    }
                                }
                            }.alignmentGuide(.leading){ _ in return -self.proxy.size.width / 2.0}
                        }
                    }
                    .padding([.leading, .trailing], 16)
                    }

            }