Post

Replies

Boosts

Views

Activity

No pop up to ask a user’s location within the app in MacOS
I have a map tool app in MacOS which needs request Location permission to show MapUserLocationButton. During development, the request for permission can pop up for the first run in my mac, but when it comes to the Apple review(Submission ID: 11f52f82-1d54-481a-9eed-880521fda2b3), they never see that. My mac is Macbook air M2 2022, 14.5 (23F79). Of course, enable App Sandbox - Location and fill up the Privacy - Location When in Use Usage Description Code: // // LocationManager.swift // import MapKit @Observable class LocationManager: NSObject { static let shared = LocationManager() private let manager = CLLocationManager() var isReady: Bool = false var showingAlert = false // var location: CLLocationCoordinate2D? var isAuthorized: Bool { #if os(macOS) .authorized == manager.authorizationStatus #else .authorizedWhenInUse == manager.authorizationStatus #endif } private override init() { super.init() manager.delegate = self manager.desiredAccuracy = kCLLocationAccuracyBest setup() } private func setup() { isReady = isAuthorized #if os(macOS) if CLLocationManager.locationServicesEnabled() { checkStatus() } else { showingAlert = true } #else checkStatus() #endif } private func checkStatus() { switch manager.authorizationStatus { case .notDetermined: manager.startUpdatingLocation() #if os(macOS) #else manager.requestWhenInUseAuthorization() #endif #if os(macOS) case .restricted, .denied: showingAlert = true case .authorizedAlways, .authorizedWhenInUse: manager.startUpdatingLocation() #else // case .authorizedWhenInUse: // manager.requestLocation() #endif default: break } } } extension LocationManager: CLLocationManagerDelegate { func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { isReady = isAuthorized guard isReady else { return } // manager.requestLocation() } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // location = locations.last?.coordinate } }
2
0
796
Jun ’24
SwiftUI: view with animation jumps to destination when state changed
RectangleView with TextView slide into screen in 3 seconds, but state of TextView changed after a second while sliding. Now you can see TextView stops sliding, jumps to the destination at once. I Just want the RectangleView with the TextView as a whole when sliding, and do not change TextView's position whatever it rotates or keeps still when state changed. GIF dmeo: https://stackoverflow.com/questions/65795434/swiftui-view-with-animation-jumps-to-destination-when-state-changed import SwiftUI struct RotationEnvironmentKey: EnvironmentKey { static let defaultValue: Bool = false } extension EnvironmentValues { var rotation: Bool { get { return self[RotationEnvironmentKey] } set { self[RotationEnvironmentKey] = newValue } } } struct AnimationTestView: View { @State private var go = false @State private var rotation = false var body: some View { VStack { Button("Go!") { go.toggle() DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { rotation.toggle() print("set rotation = \(rotation)") } } Group { if go { RectangleView() .transition(.slide) .environment(\.rotation, rotation) } }.animation(.easeInOut(duration: 3.0), value: go) }.navigationTitle("Animation Test") } } struct RectangleView: View { var body: some View { Rectangle() .frame(width: 200, height: 100) .foregroundColor(.pink) .overlay(TextView()) } } struct TextView: View { @Environment(\.rotation) var rotation @State private var animationRotating: Bool = false let animation = Animation.linear(duration: 3.0).repeatForever(autoreverses: false) var body: some View { print("refresh, rotation = \(rotation)"); return HStack { Spacer() if rotation { Text("R") .foregroundColor(.blue) .rotationEffect(.degrees(animationRotating ? 360 : 0)) .animation(animation, value: animationRotating) .onAppear { animationRotating = true } .onDisappear { animationRotating = false } } else { Text("S") } } } }
0
0
1.9k
Mar ’21
swiftui+combine: why isFavoriteO changed when scroll the LazyVGrid?
I have a LazyVGrid, every item with is favorite button. and use combine to debounce user input($isFavoriteI), when isFavoriteO changed, then modify the items. it works fine, but when i scroll the list, log will print: "X, isFavorite changed as false/true)", what cause isFavoriteO changed and why? because of item reusing in list? how to avoid it? index 7, isFavorite changed as true index 7, isFavorite changed as true index 7, isFavorite changed as true index 7, isFavorite changed as true index 7, isFavorite changed as true index 7, isFavorite changed as true index 7, isFavorite changed as true index 7, isFavorite changed as true import SwiftUI import Combine struct Item { var index: Int var favorite: Bool } var items = [ Item(index: 0, favorite: true), Item(index: 1, favorite: false), Item(index: 2, favorite: true), Item(index: 3, favorite: false), Item(index: 4, favorite: true), Item(index: 5, favorite: false), Item(index: 6, favorite: true), Item(index: 7, favorite: false), // Item(index: 8, favorite: true), // Item(index: 9, favorite: false), // Item(index: 10, favorite: true), // Item(index: 11, favorite: false), // Item(index: 12, favorite: true), // Item(index: 13, favorite: false), // Item(index: 14, favorite: true), // Item(index: 15, favorite: false), // Item(index: 16, favorite: true), // Item(index: 17, favorite: false), // Item(index: 18, favorite: true), // Item(index: 19, favorite: false), ] struct ViewModelInListTestView: View { var body: some View { ScrollView(showsIndicators: false) { LazyVGrid(columns: [GridItem(.adaptive(minimum: 200), spacing: 4, alignment: .center)], spacing: 4) { ForEach(items, id: \.index) { item in ItemView(item: item) } } }.navigationTitle("ViewModel In List") } } struct ItemView: View { let item: Item @ObservedObject var viewModel: ViewModel init(item: Item) { print("ItemView.init, \(item.index)") self.item = item self.viewModel = ViewModel(item: item) } var body: some View { HStack { Text("index \(item.index)") Spacer() Image(systemName: viewModel.isFavoriteI ? "heart.fill" : "heart") .foregroundColor(viewModel.isFavoriteI ? .red : .white) .padding() .onTapGesture { onFavoriteTapped() } .onChange(of: viewModel.isFavoriteO) { isFavorite in setFavorite(isFavorite) } } .frame(width: 200, height: 150) .background(Color.gray) } func onFavoriteTapped() { viewModel.isFavoriteI.toggle() } func setFavorite(_ isFavorite: Bool) { print("index \(item.index), isFavorite changed as \(isFavorite)") items[item.index].favorite = isFavorite } class ViewModel: ObservableObject { @Published var isFavoriteI: Bool = false @Published var isFavoriteO: Bool = false private var subscriptions: SetAnyCancellable = [] init(item: Item) { print("ViewModel.init, \(item.index)") let isFavorite = item.favorite isFavoriteI = isFavorite; isFavoriteO = isFavorite $isFavoriteI .print("index \(item.index) isFavoriteI:") .dropFirst() .debounce(for: .milliseconds(500), scheduler: DispatchQueue.main) .removeDuplicates() .eraseToAnyPublisher() .print("index \(item.index) isFavoriteO:") .receive(on: DispatchQueue.main) .assign(to: \.isFavoriteO, on: self) .store(in: &subscriptions) } } }
1
0
1.7k
Mar ’21