Skip to content

Commit

Permalink
[MAPSIOS-1184] View annotations misplased when .ignoresSafeArea(.all) (
Browse files Browse the repository at this point in the history
  • Loading branch information
aleksproger authored Mar 11, 2024
1 parent af97247 commit 4c05abe
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 16 deletions.
4 changes: 4 additions & 0 deletions Apps/Examples/Examples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
10ECE7FE19CEC239DDA96961 /* ExampleProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10C7CEE3F343DF482D428211 /* ExampleProtocol.swift */; platformFilters = (ios, ); };
1372F3B8047B6B4EE70933D9 /* StandardStyleExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 996964F634A4536F664C2611 /* StandardStyleExample.swift */; platformFilters = (ios, ); };
14799547EFD5C4757FBAD6E4 /* ViewportExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0C19E67A2E87A3D18B7B511 /* ViewportExample.swift */; platformFilters = (ios, ); };
1687412AC1637D7EA697C7A4 /* View+OnShake.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83E9078B1B13E54C2FFC5FFC /* View+OnShake.swift */; };
1820AE40702C7875656BA2D7 /* radar0.gif in Resources */ = {isa = PBXBuildFile; fileRef = 1BCE444AC33D2F1F88F4CCF0 /* radar0.gif */; };
18F76FE745B049D1F0CAF6CA /* GeoJSONSourceExample.geojson in Resources */ = {isa = PBXBuildFile; fileRef = F033C8EFB89A90D6705B047D /* GeoJSONSourceExample.geojson */; };
191391C51FC69A6D36EB67F0 /* ResizableImageExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12A0818B5BC601707E3235A9 /* ResizableImageExample.swift */; platformFilters = (ios, ); };
Expand Down Expand Up @@ -227,6 +228,7 @@
7DB76F486D80FED88678B04D /* LongTapAnimationExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongTapAnimationExample.swift; sourceTree = "<group>"; };
7DCBE4524A8793B4DE950533 /* PolygonAnnotationExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonAnnotationExample.swift; sourceTree = "<group>"; };
7F5E598A16FA446F583344CB /* TrackingModeExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackingModeExample.swift; sourceTree = "<group>"; };
83E9078B1B13E54C2FFC5FFC /* View+OnShake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+OnShake.swift"; sourceTree = "<group>"; };
858990E6795D3162A941E82C /* ButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonStyle.swift; sourceTree = "<group>"; };
876CE24F4E565ED342DDDCD6 /* radar4.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = radar4.gif; sourceTree = "<group>"; };
87D0CD9C2D04EA5B12E7F84C /* DataJoinExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataJoinExample.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -384,6 +386,7 @@
CBD8F852552CA316EFFCDD64 /* CalloutView.swift */,
75D03F5A3A0E879717BFE421 /* Constants.swift */,
26964B05A794CC808C594AB5 /* SwiftExtensions.swift */,
83E9078B1B13E54C2FFC5FFC /* View+OnShake.swift */,
F393DF039D7AD2F35C8DE4CE /* ViewExtensions.swift */,
);
path = Util;
Expand Down Expand Up @@ -870,6 +873,7 @@
7036A19FCD2CCE85BDDF4E00 /* TrackingModeExample.swift in Sources */,
A6A68B4ED674A924ACBD8FA2 /* UIColor+Random.swift in Sources */,
D9297596469F9B31C2350B43 /* UIViewController+Extensions.swift in Sources */,
1687412AC1637D7EA697C7A4 /* View+OnShake.swift in Sources */,
CF5C5513D659D4981706DDEC /* ViewAnnotationAnimationExample.swift in Sources */,
BD99E89F050E7D93846147FF /* ViewAnnotationBasicExample.swift in Sources */,
4EF3E4C342C3F8ED5BF6C332 /* ViewAnnotationMarkerExample.swift in Sources */,
Expand Down
60 changes: 46 additions & 14 deletions Apps/Examples/Examples/SwiftUI Examples/SwiftUIRoot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import UIKit
@available(iOS 14.0, *)
struct SwiftUIRoot: View {
var body: some View {
NavigationView {
ExamplesNavigationView {
List {
Section {
ExampleLink("Show me the map!", note: "Just a Map().", destination: Map().ignoresSafeArea())
Expand Down Expand Up @@ -44,16 +44,6 @@ struct SwiftUIRoot: View {

} header: { Text("Testing Examples") }
}
.listStyle(.plain)
.navigationTitle(title)
.navigationBarTitleDisplayMode(.inline)
.modifier(ToolbarContentWhenPresented { dismiss in
ToolbarItem(placement: .navigationBarLeading) {
Button("Close") {
dismiss()
}
}
})
}
}
}
Expand All @@ -69,13 +59,13 @@ struct ExampleLink<S, Destination>: View where S : StringProtocol, Destination:
self.destination = destination
}
var body: some View {
NavigationLink(destination: destination) {
NavigationLink(destination: ExampleView(destination)) {
VStack(alignment: .leading) {
Text(title)
note.map {
Text($0)
.font(.footnote)
.foregroundColor(.gray)
.font(.footnote)
.foregroundColor(.gray)
}
}
}
Expand Down Expand Up @@ -116,4 +106,46 @@ func createSwiftUIExamplesController() -> UIViewController {
return controller
}


@available(iOS 14.0, *)
struct ExamplesNavigationView<Content>: View where Content: View {
let content: Content

init(@ViewBuilder content: () -> Content) {
self.content = content()
}

var body: some View {
NavigationView {
content
.listStyle(.plain)
.navigationTitle(title)
.navigationBarTitleDisplayMode(.inline)
.modifier(ToolbarContentWhenPresented { dismiss in
ToolbarItem(placement: .navigationBarLeading) {
Button("Close") { dismiss() }
}
})
}
}
}

@available(iOS 14.0, *)
struct ExampleView<Content>: View where Content: View {
@State private var isNavigationBarHidden = false
let content: Content

init(@ViewBuilder _ content: () -> Content) {
self.content = content()
}

var body: some View {
content
.navigationBarHidden(isNavigationBarHidden)
.onShake {
isNavigationBarHidden.toggle()
}
}
}

private let title = "SwiftUI Examples"
33 changes: 33 additions & 0 deletions Apps/Examples/Examples/SwiftUI Examples/Util/View+OnShake.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import SwiftUI
import UIKit

extension UIWindow {
open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if motion == .motionShake {
NotificationCenter.default.post(name: deviceDidShake, object: nil)
}
}
}

@available(iOS 13.0, *)
struct DeviceShakeViewModifier: ViewModifier {
let action: () -> Void

func body(content: Content) -> some View {
content
.onAppear()
.onReceive(NotificationCenter.default.publisher(for: deviceDidShake)) { _ in
action()
}
}
}

@available(iOS 13.0, *)
extension View {
func onShake(perform action: @escaping () -> Void) -> some View {
modifier(DeviceShakeViewModifier(action: action))
}
}

private let deviceDidShake = Notification.Name(rawValue: "deviceDidShake")

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Turf
struct ViewAnnotationsExample: View {
@State private var taps: [Tap] = []
@State private var allowOverlap: Bool = false
@State private var ignoreAllSafeArea: Bool = true
@State private var selected = false
@State private var etaAnnotationAnchor = ViewAnnotationAnchor.center
@State private var overlayHeight: CGFloat = 0
Expand Down Expand Up @@ -81,14 +82,15 @@ struct ViewAnnotationsExample: View {
}
// Add bottom padding for the bottom config panel, View Annotations won't appear there.
.additionalSafeAreaInsets(.bottom, overlayHeight)
.ignoresSafeArea(edges: [.leading, .trailing, .bottom])
.ignoresSafeArea(edges: ignoreAllSafeArea ? [.all] : [.horizontal, .bottom])
.onTapGesture {
print("SwiftUI view tap received.")
}
.safeOverlay(alignment: .bottom) {
VStack(alignment: .leading) {
Text("Tap to add annotations")
Toggle("Allow overlap", isOn: $allowOverlap)
Toggle("Ignore all safe area", isOn: $ignoreAllSafeArea)
}
.padding(.horizontal, 10)
.padding(.vertical, 6)
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Mapbox welcomes participation and contributions from everyone.
* Add annotations drag handlers callbacks `dragBeginHandler`, `dragChangeHandler`, `dragEndHandler` to all Annotation types.
* Add `allowHistTesting` modifier on `MapViewAnnotation`.
* Fix taps propagation on `ViewAnnotation`.
* Fix view annotations positioning on `.ignoresSafeArea(.all)` in SwiftUI
* Bump core maps version to 11.2.0 and common sdk to 24.2.0.
* Added Attribution and Telemetry pop-up dialogs and compass view content description translations for Arabic, Belarusian, Bulgarian, Catalan, Chinese Simplified, Chinese Traditional, Czech, Danish, Dutch, French, Galician, German, Hebrew, Italian, Japanese, Korean, Lithuanian, Norwegian, Polish, Belarusian, Russian, Spanish, Swedish, Ukranian and Vietnamese.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ final class ViewAnnotationCoordinator {

init(viewAnnotationsManager: ViewAnnotationsManaging,
addViewController: @escaping ViewControllerHandler,
removeViewController: @escaping ViewControllerHandler) {
removeViewController: @escaping ViewControllerHandler
) {
self.viewAnnotationsManager = viewAnnotationsManager
self.addViewController = addViewController
self.removeViewController = removeViewController
Expand Down Expand Up @@ -94,6 +95,7 @@ private struct DisplayedViewAnnotation {

vc.view.backgroundColor = .clear
vc.view.isUserInteractionEnabled = viewAnnotation.allowHitTesting
vc.disableSafeArea()
}

func update(with viewAnnotation: MapViewAnnotation) {
Expand All @@ -110,3 +112,16 @@ private struct DisplayedViewAnnotation {
_update(viewAnnotation.content)
}
}

@available(iOS 13.0, *)
private extension UIHostingController {
func disableSafeArea() {
if #available(iOS 16.4, *) {
safeAreaRegions = SafeAreaRegions()
} else {
/// This is a private API, but it's the only good way to disable safe area in UIHostingController in iOS 16.4 and lower
/// Details: https://stackoverflow.com/questions/70156299/cannot-place-swiftui-view-outside-the-safearea-when-embedded-in-uihostingcontrol
_disableSafeArea = true
}
}
}

0 comments on commit 4c05abe

Please sign in to comment.