[英]How to make SwiftUI View expand available space?
我正在尝试使 SwiftUI 视图扩展其可用空间。 我有一个 MapView,它使用 MapKit 在屏幕上显示 map。 我想要这个 map 来扩展 VStack 中的可用空间。 您可以看到它位于红色视图上方和搜索栏下方。 如果我使红色视图的高度为 100,则 MapView 会缩小。 如果我没有在红色视图上设置高度,那么 MapView 会更大,但是红色视图看起来不像我想要的那样。
我希望红色视图的高度为 100,并且 MapView 填充搜索栏下方和红色视图上方的所有可用高度。
内容视图:
struct ContentView: View {
@ObservedObject
var viewModel: HomeViewModel
var body: some View {
NavigationView {
ZStack {
ColorTheme.brandBlue.value.edgesIgnoringSafeArea(.all)
VStack {
CardView {
EditText(hint: "Search", text: self.$viewModel.searchText, textContentType: UITextContentType.organizationName)
}
MapView(annotations: self.$viewModel.restaurantAnnotations)
.cornerRadius(8)
CardView(height: 100) {
HStack {
Color.red
}
}
}
}
.navigationBarTitle("", displayMode: .inline)
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
}
卡片视图
struct CardView<Content>: View where Content : View {
var height: CGFloat = .infinity
var content: () -> Content
var body: some View {
content()
.padding(EdgeInsets.init(top: 0, leading: 8, bottom: 8, trailing: 8))
.background(Color.white.cornerRadius(8))
.shadow(radius: 2, x: 0, y: 1)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: height)
}
}
编辑文本
struct EditText: View {
var hint: String
@Binding
var text: String
var label: String = ""
var textContentType: UITextContentType? = .none
var keyboardType: UIKeyboardType = .default
var textSize: CGFloat = 16
var body: some View {
return VStack(alignment: .leading) {
Text(label).font(.system(size: 12)).bold()
.foregroundColor(ColorTheme.text.value)
HStack {
TextField(hint, text: $text)
.lineLimit(1)
.font(.system(size: textSize))
.textContentType(textContentType)
.keyboardType(keyboardType)
.foregroundColor(ColorTheme.text.value)
}
Divider().background(ColorTheme.brandBlue.value)
}
}
}
地图视图
struct MapView: UIViewRepresentable {
@Binding
var annotations: [MKAnnotation]
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
view.delegate = context.coordinator
view.addAnnotations(annotations)
if annotations.count == 1 {
let coords = annotations.first!.coordinate
let region = MKCoordinateRegion(center: coords, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
view.setRegion(region, animated: true)
}
}
func makeCoordinator() -> MapViewCoordinator {
MapViewCoordinator(self)
}
}
地图视图协调器
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var mapViewController: MapView
init(_ control: MapView) {
self.mapViewController = control
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
//Custom View for Annotation
let identifier = "Placemark"
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
let button = UIButton(type: .infoDark)
annotationView.rightCalloutAccessoryView = button
return annotationView
}
return nil
}
}
这是一个解决方案(使用 Xcode 11.4 测试):
struct CardView<Content>: View where Content : View {
var height: CGFloat? = nil // << here !!
注意:定义的高度,即使使用.infinity
,通过向 map 视图请求高度来使您的上卡等效,因此它们划分了可用空间; 未指定高度时,组件紧贴内容
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.