SwiftUI 虽然出现了好几年(1.0好像2019年出的,还有SPM也是同一年),现在已经到从1.0到5.0,但受限于对系统的要求(最低iOS13.0,有的要求17.0及以上),每个版本里面差异也很大,语法和Flutter 的Dart 比较像。空闲之余可以先学习下,给有需要的同学做个参考, 官方也有现成案例,展示效果如图:
地标列表:
import SwiftUI/// 列表
struct LandmarkList : View {@Environment(ModelData.self) var modelData/// 仅展示收藏@State private var showFavoritesOnly = false/// 数据过滤private var filterLandmarks:[Landmark] {modelData.landmarkData.filter { $0.isFavorite == true || !showFavoritesOnly }}/// 转场设置@State private var selectIndex:Int = 0@State private var _index:Int? = nilvar body: some View {NavigationView {List{Toggle(isOn: $showFavoritesOnly, label: {Text("Favorites Only")})if selectIndex == 0 {ForEach(filterLandmarks) { landmark inNavigationLink {LandMarkDetail(landmark: landmark)} label: {LandmarkRow(landmark: landmark)}}}else{ForEach(filterLandmarks.indices,id:\.self) { index inLandmarkRow(landmark: filterLandmarks[index]).onTapGesture {_index = indexdebugPrint("onTapGesture:{\(index),\(String(describing: _index))}")}}.sheet(isPresented: .constant(selectIndex > 0 && _index != nil),onDismiss: {_index = nil},content: {if _index != nil && filterLandmarks.count > _index! {LandMarkDetail(landmark: filterLandmarks[_index!])}})}}.navigationBarTitle("Landmarks", displayMode: .large).navigationBarItems(trailing: SegmentButton(selectIndex:$selectIndex)).animation(.easeInOut, value: 0.5)}}
}#Preview {let modelData = ModelData()return LandmarkList().environment(modelData)
}
详情:
import SwiftUIstruct LandMarkDetail : View {@Environment(ModelData.self) var modelDatavar landmark : Landmarkvar landmarkIndex:Int? {get{modelData.landmarkData.firstIndex { $0.id == landmark.id }}}var body: some View {@Bindable var modelData = modelDataScrollView {MapView(coordinate: landmark.locationCoordinate).frame(height: 300)CircleImage(image: landmark.image(forSize: 250)).offset(y: -130).padding(.bottom, -130)VStack(alignment: .leading) {HStack{Text(landmark.name).font(.title)FavoriteButton(isSet: landmarkIndex != nil ? $modelData.landmarkData[landmarkIndex!].isFavorite : .constant(false))}HStack {Text(landmark.park)Spacer()Text(landmark.state)}.font(.subheadline).foregroundStyle(.secondary)Divider()Text("About \(landmark.name)").font(.title2)Text(landmark.description ?? "")}.padding()Spacer()}.navigationBarTitle(landmark.name, displayMode: .inline).navigationBarItems(trailing: FavoriteButton(isSet: landmarkIndex != nil ? $modelData.landmarkData[landmarkIndex!].isFavorite : .constant(false)))}
}#Preview {let modelData = ModelData()return LandMarkDetail(landmark: modelData.landmarkData[0]).environment(modelData)
}
每天学习一小步,进步一大步,Demo示例