Yes it is possible to change the mapType from hybrid to satellite.
The "trick" is to use an ObservableObject to change the state of the view.
Here is a basic setup that works well for me, passing the
MapModel through an EnvironmentObject. Let us know if this works for you.
import SwiftUI
import Foundation
import MapKit
@main
struct TestApp: App {
var mapModel = MapModel()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(mapModel)
}
}
}
class MapModel: ObservableObject {
@Published var mapType = MKMapType.standard
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 35.685, longitude: 139.7514), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
}
struct ContentView: View {
@EnvironmentObject var mapModel: MapModel
@State private var mapType: Int = 0
@State private var mapTypes = ["Standard", "Satellite", "Hybrid"]
var body: some View {
ZStack (alignment: .topLeading) {
MapView().edgesIgnoringSafeArea(.all)
mapTools
}
}
var mapTools: some View {
HStack {
Spacer()
Picker(selection: Binding<Int> (
get: {self.mapType},
set: {
self.mapType = $0
self.mapModel.mapType = self.getMapType()
}
), label: Text("")) {
ForEach(0 ..< mapTypes.count) {
Text(self.mapTypes[$0])
}
}.pickerStyle(SegmentedPickerStyle())
.labelsHidden()
.frame(width: 222, height: 60)
.clipped()
Spacer()
}
}
func getMapType() -> MKMapType {
switch mapType {
case 0: return .standard
case 1: return .satellite
case 2: return .hybrid
default:
return .standard
}
}
}
struct MapView: UIViewRepresentable {
@EnvironmentObject var mapModel: MapModel
let mapView = MKMapView()
func makeUIView(context: Context) -> MKMapView {
mapView.mapType = mapModel.mapType
mapView.setRegion(mapModel.region, animated: true)
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.mapType = mapModel.mapType
}
}
Post
Replies
Boosts
Views
Activity
you could initialize your player in the init(...) something like this:
struct ExercisingSessionView: View {
let exerciseName: String
let videoName: String
@State var player: AVPlayer
@State var isplaying = false
@State var showcontrols = false
init(exerciseName: String, videoName: String) {
self.exerciseName = exerciseName
self.videoName = videoName
self._player = State(initialValue: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: videoName, ofType: "mov")!)))
}
var body: some View {
CustomVideoPlayer(player: $player)
.frame(width: 390, height: 219)
.onTapGesture {
self.showcontrols = true
}
}
}
see my answer on stack overflow. My solution works.
works without any problems for me on macos 12.beta,
xcode 13.beta, target ios 15 and macCatalyst.
Tested on ios15 devices and macos 12. I also tried using 10000, and that works well.
Maybe your issue happens on older ios and macos.
You maybe interested in "https://stackoverflow.com/questions/68450344/swift-ui-overwhelmed-by-high-frequency-stateobject-updates"
where code struggles on ios14 but not ios15.
You could try other ways to see if you can improve the performance, such as:
ForEach(items.indices, id: \.self) { index in
Text(items[index]).background(colors.randomElement()!)
}
or
ForEach(Array(items.enumerated()), id: \.0) { index, item in
Text(item).background(colors.randomElement()!)
}
This is the code I used for my test, on macOS 12, using Xcode 13 tested on ios15. Of course could be different on xcode 12. It also works if I put the sheet outside the toolbar.
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct TaskToDoView: View {
@Environment(\.managedObjectContext) private var viewContext
// @FetchRequest(
// sortDescriptors: [NSSortDescriptor(keyPath: \SimpleRecord.title, ascending: true)],
// animation: .default)
//
// private var items: FetchedResults<SimpleRecord>
@State var items = ["one","two","three"]
@State private var isModal = false
var body: some View {
NavigationView {
List {
ForEach(items, id: \.self) { item in // <-- note the id:
NavigationLink(destination: Text("navlinkview: \(item)")) {
Text("Item at \(item)")
}
}
// .onDelete(perform: deleteItems)
}
.toolbar {
HStack {
#if os(iOS)
EditButton()
#endif
Button(action: addItem) {
Label("Add Item", systemImage: "plus")
}
.sheet(isPresented: $isModal,
onDismiss: dismissToDoModelView,
content: {
Text("ToDoModelView")
})
}
}
}
}
private func dismissToDoModelView() {
print("Modal Dismissed")
print("Modal is \(self.isModal)")
}
private func addItem() {
self.isModal.toggle()
}
}
struct ContentView: View {
var body: some View {
TaskToDoView()
}
}
maybe it is to do with ToDoModelView(), because it works well in my simple test on ios 15 and macos 12.
well why do you say "TabView disappearing on Xcode 13", if you mean "I cant see the background"
your functions signatures are wrong. For example, if you use this it works:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("\n-------> applicationDidFinishLaunching")
return true
}
see this solution on Stack Overflow: https://stackoverflow.com/questions/66301334/swiftui-datepicker-day-of-week-language
works without any problems for me on macos 12.beta, xcode 13.beta, target ios 15 and macCatalyst.
I can see the TabView just like you show in your picture. Tested on real devices, simulators and in the preview.
Here is a possible setup. I've used 2 states in a ObservableObject, one for the UI and one for the PSU.
I change the UI only if there is a change.
import SwiftUI
@main
struct TestApp: App {
@StateObject var psu = PSUModel()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(psu)
}
}
}
class PSUModel: ObservableObject {
@Published var uiState = false
@Published var psuState = false
}
struct ContentView: View {
@EnvironmentObject var psu: PSUModel
var body: some View {
VStack (spacing: 50) {
Button("simulate a PSU change") {
psu.psuState.toggle()
}
Toggle("", isOn: $psu.uiState)
.toggleStyle(SwitchToggleStyle(tint: Color.green))
// changing the PSU state from the UI
.onChange(of: psu.uiState) { value in
// request(action: .PSU, param: psu)
print("---> send to PSU: \(value)")
psu.psuState = value
}
// receiving PSU state changes from the PSU
.onReceive(psu.$psuState) { value in
print("-----> received from PSU: \(value) ")
// update the UI with what we received from the PSU, but only if there is a change
if psu.uiState != value {
psu.uiState = value
}
}
}
}
}
try this:
func wordChained() -> Bool{
let char1 = prevWord[prevWord.index(prevWord.startIndex, offsetBy: prevWord.count - 1)]
let char2 = playerWord[playerWord.index(playerWord.startIndex, offsetBy: 0)]
if char1.lowercased() == char2.lowercased() { // <--- here
return true
}
else{
return false
}
}
or just:
func wordChained() -> Bool{
let char1 = prevWord[prevWord.index(prevWord.startIndex, offsetBy: prevWord.count - 1)]
let char2 = playerWord[playerWord.index(playerWord.startIndex, offsetBy: 0)]
return char1.lowercased() == char2.lowercased() // <--- here
}
remove all "@State" in the "struct Player. "@State" is only for use in Views.
You are also missing a closing bracket "} " in Player and Game.
Also remove ":" and use "struct Player {"
there are many ways to do this, this is one way:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State var goToIt = false
var body: some View {
NavigationView {
NavigationLink(destination: Text("Second View"), isActive: $goToIt) {
Text("Second view in 3 seconds")
}
}.onAppear {
// simulating another process that triggers the change
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
goToIt = true
}
}
}
}
show us the code you use to check for camera permission, for example where you use: "AVCaptureDevice.authorizationStatus(for: .video)"