Provide views, controls, and layout structures for declaring your app's user interface using SwiftUI.

Posts under SwiftUI tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Obscuration of Specific Content in Screenshots on visionOS
Hello, I am currently developing an app using visionOS, and I am looking for a way to obscure specific content in screenshots. My app includes certain content that is exclusive to premium users, and I need to hide these parts when screenshots are shared on social media. In iOS, I was able to achieve this by extending SecureField to hide specific Views or Images, but this method does not work in visionOS. I am seeking advice on the best approach to implement this feature in visionOS. https://github.com/yoxisem544/ScreenshotPreventing-iOS Specifically, I would appreciate guidance on the following points: The optimal method for obscuring specific Views or Images in screenshots on visionOS Any tips or tricks when using existing components similar to SecureField Techniques or approaches used by other developers to implement similar features Your assistance would be greatly appreciated. Thank you for your help.
0
0
153
4w
Pop to root view when selected tab is tapped again for WebKit
Hello everyone! I have a WKWebView in my swiftui app and would like to enable to "pop root view when selected tab is tapped again" feature, but I have been unable to figure out how to implement this. Here's the basic code: class TabIdentifierModel:ObservableObject { @Published var tabSelection:TabIdentifier { willSet { if newValue == tabSelection { NotificationCenter.default.post(name: .popRootView, object: nil, userInfo: ["tab": newValue.rawValue]) } } } init() { tabSelection = .home } } struct ContentView: View { @AppStorage(AppStorageKeys.enableShorts) var enableShorts = true @StateObject var storeVM = StoreVM() @StateObject var downloadURLManager = DownloadURLManager.shared @State var downloadViewIsOpen = false // ...... @State var tabSelection = TabIdentifierModel() var body: some View { TabView(selection: $tabSelection.tabSelection) { // ...... WebViewWrapper(url: $libraryTabURL) .tabItem { Label { Text("Library") } icon: { Image(systemName: "folder.fill") } }.tag(TabIdentifier.library) // ...... } .environmentObject(tabSelection) } } Tapping on the tab again doesn't seem to set the value again thus the NotificationCenter.default.post is not sent and the web view is not reloaded. Help would be much appreciated! Thanks in advance!
0
0
163
4w
Sheet Presentation
Hi, would appreciate based on my implementation how can I control the dimmed effect of sheet presentation on iOS 17 later. Here is my sample implementation: struct ContentView: View { @State private var present = true var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } .padding() .sheet(isPresented: $present, content: { ContentView2() .modifier( SheetModifier( dismissDisabled: true, detents: [.medium, .large], dragIndicator: .hidden ) ) }) } } #Preview { ContentView() } struct SheetModifier: ViewModifier { var dismissDisabled: Bool var detents: Set<PresentationDetent> var backgroundInteraction: PresentationBackgroundInteraction var dragIndicator: Visibility var cornerRadius: CGFloat init( dismissDisabled: Bool = false, detents: Set<PresentationDetent>, backgroundInteraction: PresentationBackgroundInteraction = .automatic, dragIndicator: Visibility = .automatic, cornerRadius: CGFloat = 20 ) { self.dismissDisabled = dismissDisabled self.detents = detents self.backgroundInteraction = backgroundInteraction self.dragIndicator = dragIndicator self.cornerRadius = cornerRadius } func body(content: Content) -> some View { content .background(.clear) .interactiveDismissDisabled(dismissDisabled) .presentationDetents(detents) .presentationBackgroundInteraction(backgroundInteraction) .presentationDragIndicator(dragIndicator) .presentationCornerRadius(cornerRadius) } }
0
0
253
4w
Add a modifier to a single model in the Reality Composer Pro scene
We can add many models in the Reality Composer Pro scene, but when I use RealityView to display and add modifiers in SwiftUI, the modifiers will have Effect, and I don't want to do this. I hope this modifier will be valid for a single model in the Reality Composer Pro scenario. May I ask how to add modifiers to a single model in the Reality Composer Pro scene?
2
0
298
2w
scrollPosition(id:anchor:) freeze UI when show/hide keyboard
Hello ! This will be my first blog post. I hope I will find the solution. So, I try to use the new iOS 17+ API for ScrollView. I have an array of messages that I want to show in scroll view. And I need to scroll to bottom when I tap to Send button. When I use scrollPosition(id:anchor:), it freeze the UI. The link to the screencast to demonstrate. I think the problem might be the keyboard when it shows and hides. But I can't understand what can I do. struct ChatView: View { @ObservedObject var viewModel: CoachViewModel @State private var scrollTo: Message.ID? var body: some View { ScrollView { LazyVStack { ForEach(viewModel.messages) { message in MessageView(viewModel: viewModel, message: message) } } .scrollTargetLayout() } .scrollPosition(id: $scrollTo) .background(.primaryBackground) .onChange(of: viewModel.scrollToBottom) { if $1, let lastMessage = viewModel.messages.last { withAnimation { scrollTo = lastMessage.id } viewModel.scrollToBottom = false } } } } struct Message: Identifiable, Hashable { let id: UUID let author: MessageAuthor let text: String } final class CoachViewModel: ObservableObject { @Published var messageTextInput = "" @Published var scrollToBottom = false @Published var messages: [Message] = [...] // ... more code ... func sendMessage() { messages.append( .init( id: .init(), author: .user, text: messageTextInput ) ) messageTextInput.removeAll() scrollToBottom = true } } struct CoachView: View { @StateObject private var viewModel = CoachViewModel() @State private var isSearching = false var body: some View { VStack(spacing: 0) { Group { CoachTitleView(viewModel: viewModel, isSearching: $isSearching) ChatView(viewModel: viewModel) } .onTapGesture { UIApplication.shared.endEditing() } if isSearching { MatchboxView(viewModel: viewModel) } else { InputTextFieldView(viewModel: viewModel) } } } }
0
0
165
Jun ’24
Long Hang Times When Accessing View With Posts
For some reason, every time I'm accessing a view populated with posts and fetching posts, my app has like a 5-8 second hang time. I don't know whats causing this issue, and I have been dealing with this for 3 days. `func fetchPosts(completion: @escaping (Result<[PostWithUser], Error>) -> Void) { if !cachedPosts.isEmpty { completion(.success(self.cachedPosts)) return } postsRef.order(by: "timestamp", descending: true).getDocuments { [weak self] snapshot, error in guard let self = self else { return } if let error = error { completion(.failure(error)) return } guard let documents = snapshot?.documents else { completion(.success([])) return } let group = DispatchGroup() var postsWithUsers: [PostWithUser] = [] DispatchQueue.global(qos: .userInitiated).async { for document in documents { group.enter() let data = document.data() guard let userId = data["userId"] as? String, let parentId = data["parentId"] as? String, let groupId = data["groupId"] as? String, let text = data["text"] as? String, let isPinned = data["isPinned"] as? Bool, let imageUrl = data["imageUrl"] as? String, let videoUrl = data["videoUrl"] as? String, let timestamp = data["timestamp"] as? Timestamp, let views = data["views"] as? Int else { group.leave() continue } let post = Post(id: document.documentID, userId: userId, parentId: parentId, groupId: groupId, text: text, imageUrl: imageUrl, videoUrl: videoUrl, timestamp: timestamp.dateValue(), isPinned: isPinned, likedBy: [], views: views) self.usersRef.document(userId).getDocument { userDocument, error in defer { group.leave() } if let userDocument = userDocument, let userData = userDocument.data() { let user = User( id: userId, username: userData["username"] as? String ?? "", bio: userData["bio"] as? String ?? "", profilePictureUrl: userData["profileImageUrl"] as? String ?? "", privateProfile: userData["privateProfile"] as? Bool ?? false, privateFollowerList: userData["privateFollowerList"] as? Bool ?? false, privateFollowingList: userData["privateFollowingList"] as? Bool ?? false, privateReplies: userData["privateReplies"] as? Bool ?? false, privateLikes: userData["privateLikes"] as? Bool ?? false ) let postWithUser = PostWithUser(post: post, user: user) DispatchQueue.main.async { postsWithUsers.append(postWithUser) } } else { print("Failed to fetch user data for userId: \(userId), error: \(String(describing: error))") } } } group.notify(queue: .main) { self.cachedPosts = postsWithUsers completion(.success(postsWithUsers)) } } } }` ` func fetchPosts() { PostService.shared.fetchPosts { result in switch result { case .success(let posts): DispatchQueue.main.async { self.posts = posts } case .failure(let error): print("Failed to fetch posts: \(error)") } } } func refreshPosts() { PostService.shared.refreshPosts { result in switch result { case .success(let posts): DispatchQueue.main.async { self.posts = posts } case .failure(let error): print("Failed to fetch posts: \(error)") } } }
1
0
182
Jun ’24
SwiftUI SideMenu Navigation Issue
I am currently refactoring my app's side menu to be more like Twitter's. I have the UI down in terms of how the side menu looks and appears, but the issue is navigating to a view from the side menu. The views that a user can go to from the side menu are a mix of SwiftUI views & UIKit View Controllers. As of right now, when a user navigates to a view from the side menu, it presents it modally as a sheet. I want it to have regular navigation, where the user goes to the view displayed in full screen and can tap on the back button to go back to the previous view. Here is the associated code: SideMenuView.swift SideMenuViewModel.swift How can I modify the navigation logic to be like Twitter's? I've been stuck for days trying to find a fix but it has been a struggle.
1
0
222
4w
Questions Tags Saves Users Companies LABS Jobs Discussions COLLECTIVES Communities for your favorite technologies. Explore all Collectives TEAMS Ask questions, find answers and collaborate at work with Stack Overflow for Teams. Looking for your
0 I'm trying to make a list of trips that a person has gone on, and when someone has no trips in their list, it will display a ContentUnavailableView with a NavigationLink to take them to a new view. I am encountering strange issues when using the ContentUnavailableView with the NavigationLink, such as the back button being unaligned and not being able to swipe back to the previous view. I expected the ContentUnavailableView to link without any of these issues. Any guidance would be greatly appreciated.
0
0
145
Jun ’24
Prevent Data Retention in Core Data When View is Dismissed
Prerequisite Information I am trying to use Core Data in my SwiftUI app. I have created 3 entities, a Record, a Header and an Entry. The Record contains the Header entities. The Header contain other Header or Entry entities. The Entry has a title and a value. My List view looks like this, I fetch the records with a @FetchRequest. NavigationView { List { ForEach(records) { record in NavigationLink(destination: DetailView(headers: record.headers!.allObjects as? [Header] ?? [], isNewEntry: true)) { Text(record.id!.uuidString) } } } } In my DetailView I have a form that passes the details to other views which create a DisclosureGroup for a Header, a bold Text for a subheader, and a TextField for an Entry let headers: [Header] let isNewEntry: Bool @Environment(\.managedObjectContext) var managedObjectContext init(headers: [Header], isNewEntry: Bool = false) { self.headers = headers self.isNewEntry = isNewEntry } Form { ForEach(Array(headers.enumerated()), id: \.element) { index, header in HeaderView(header: header, isExpanded: Binding( get: { self.expandedStates[header.id!, default: false] }, set: { self.expandedStates[header.id!] = $0 } )) } } Problem When I press the record in the list, it takes me to the DetailView where I can write something in the TextField. Then if I slide back and do not press the save button and then press the same record again from the list, it retains the data I wrote in the TextField. Question How can I make it so that the data is not retained if I slide back except only when I press the save button? Please let me know if any other information is needed or if something is unclear.
0
1
222
Jun ’24
Location Permission Popup Not Appearing in SwiftUI App
Hello everyone, I'm working on a SwiftUI app that requires location services, and I've implemented a LocationManager class to handle location updates and permissions. However, I'm facing an issue where the location permission popup does not appear when the app is launched. Here is my current implementation: LocationManager.swift: import CoreLocation import SwiftUI class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { private let locationManager = CLLocationManager() @Published var userLocation: CLLocation? @Published var isAuthorized = false @Published var authorizationStatus: CLAuthorizationStatus = .notDetermined override init() { super.init() locationManager.delegate = self checkAuthorizationStatus() } func startLocationUpdates() { locationManager.startUpdatingLocation() } func stopLocationUpdates() { locationManager.stopUpdatingLocation() } func requestLocationAuthorization() { print("Requesting location authorization") DispatchQueue.main.async { self.locationManager.requestWhenInUseAuthorization() } } private func checkAuthorizationStatus() { print("Checking authorization status") authorizationStatus = locationManager.authorizationStatus print("Initial authorization status: \(authorizationStatus.rawValue)") handleAuthorizationStatus(authorizationStatus) } func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { print("Authorization status changed") authorizationStatus = manager.authorizationStatus print("New authorization status: \(authorizationStatus.rawValue)") handleAuthorizationStatus(authorizationStatus) } private func handleAuthorizationStatus(_ status: CLAuthorizationStatus) { switch status { case .authorizedAlways, .authorizedWhenInUse: DispatchQueue.main.async { self.isAuthorized = true self.startLocationUpdates() } case .notDetermined: requestLocationAuthorization() case .denied, .restricted: DispatchQueue.main.async { self.isAuthorized = false self.stopLocationUpdates() print("Location access denied or restricted") } @unknown default: DispatchQueue.main.async { self.isAuthorized = false self.stopLocationUpdates() } } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { DispatchQueue.main.async { self.userLocation = locations.last } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Location manager error: \(error.localizedDescription)") } } MapzinApp.swift: @main struct MapzinApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate @StateObject private var locationManager = LocationManager() var body: some Scene { WindowGroup { Group { if locationManager.authorizationStatus == .notDetermined { Text("Determining location authorization status...") } else if locationManager.isAuthorized { CoordinatorView() .environmentObject(locationManager) } else { Text("Location access is required to use this app. Please enable it in Settings.") } } } } } Log input: Checking authorization status Initial authorization status: 0 Requesting location authorization Authorization status changed New authorization status: 0 Requesting location authorization Despite calling requestWhenInUseAuthorization() when the authorization status is .notDetermined, the permission popup never appears. Here are the specific steps I have taken: Checked the Info.plist to ensure the necessary keys for location usage are present: NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription Verified that the app's target settings include location services capabilities. Tested on a real device to ensure it's not a simulator issue. I'm not sure what I might be missing. Any advice or suggestions to resolve this issue would be greatly appreciated. Thank you!
1
0
291
4w
Inline Widget Displays Custom Image Abnormally
I want to display my own image in an inline widget. Using the SwiftUI Image syntax doesn't show the image, so following advice from online forums, I used the syntax Image(uiImage: UIImage(named: String)). This successfully displays the image, but if I change the image file name in the app, the image doesn't update properly. I tested displaying the image file name using Text in the inline widget, and it correctly shows the updated file name from my app. So, my AppStorage and AppGroups seem to be working correctly. I'd like to ask if there's a way to update my images properly and if there's an alternative method to display images without converting them to UIImage. Thanks.
0
0
172
Jun ’24
.fullScreenCover Incorrectly Dismissed
Hi, thought I'd share some feedback (which was also sent to Apple) publicly in case anyone else is experiencing the same issue or has an idea of how to circumvent the issue while Apple investigates. TLDR: Views presented with the .fullScreenCover modifier can be incorrectly dismissed when a child view presented with a .sheet modifier inside the .fullScreenCover is dismissed. The intended behavior is that the child sheet views can be dismissed without dismissing the parent full screen cover views. It appears this bug has been present in versions of iOS 17 as well as iOS 18. Short of using something other than a .fullScreenCover to present the view, I'm still searching for a solution to this bug. Filing: FB14007758 Steps to Reproduce (see code below): Open a View in .fullScreenCover presentation In the view presented via the .fullScreenCover, add two sheet modifiers with two different views (e.g. SheetOneView, SheetTwoView) Toggle the presentation of SheetOneView and SheetTwoView randomly until the .fullScreenCover is incorrectly dismissed. Reproducible Code: import SwiftUI struct SheetOneView: View { var body: some View { Text("Sheet: 1") } } struct SheetTwoView: View { var body: some View { Text("Sheet: 2") } } struct FullScreenCoverView: View { @State var isSheetOnePresented = false @State var isSheetTwoPresented = false var body: some View { VStack(content: { Text("Full Screen Cover") HStack { Button("Open Sheet 1") { isSheetOnePresented = true } Button("Open Sheet 2") { isSheetTwoPresented = true } } .buttonStyle(.borderedProminent) .buttonBorderShape(.capsule) }) .sheet(isPresented: $isSheetOnePresented) { SheetOneView() } .sheet(isPresented: $isSheetTwoPresented) { SheetTwoView() } } } struct ContentView: View { @State var isFullScreenCoverPresented = false var body: some View { VStack { Button("Open Full Screen Cover") { isFullScreenCoverPresented = true } } .fullScreenCover(isPresented: $isFullScreenCoverPresented, content: { FullScreenCoverView() }) .padding() } }
1
0
203
Jun ’24
Inline Widget Displays Custom Image Abnormally
I want to display my own image in an inline widget. Using the SwiftUI Image syntax doesn't show the image, so following advice from online forums, I used the syntaxImage(uiImage: UIImage(named: String))This successfully displays the image, but if I change the image file name in the app, the image doesn't update properly. I tested displaying the image file name using Text in the inline widget, and it correctly shows the updated file name from my app. So, my AppStorage and AppGroups seem to be working correctly. I'd like to ask if there's a way to update my images properly and if there's an alternative method to display images without converting them to UIImage. Thanks.
0
0
139
Jun ’24
Compact screens, keyboard and dynamic type UI issues
When testing my app on an iPhone SE i noticed an issue with the UI when editing some text in a text field. When the keyboard comes up it pushes everything in the view up and part of the text field gets covered by the navigation title and buttons. It gets worse when testing dynamic fonts and changing the text to XXLarge or higher. There are no issues on a larger screen. Is it possible to prevent the keyboard from push up the content of the view when it is displayed? This is with the default font of large. This is with the extra large text var body: some View { NavigationStack { VStack { HStack { Text("Name") Spacer() TextField("Name", text: $name) .multilineTextAlignment(.trailing) .textFieldStyle(.roundedBorder) .frame(width: 240) .onChange(of: name) { if name.count >= 10 { isShowingLongNameWarning = true } else { isShowingLongNameWarning = false } } } VStack(alignment: .trailing){ HStack { Text("Short Name") Spacer() TextField("Short Name", text: $shortName.max(shortNameCharacterLimit)) .multilineTextAlignment(.trailing) .textFieldStyle(.roundedBorder) .frame(width: isShowingLongNameWarning ? 215 : 240) if isShowingLongNameWarning { VStack { Image(systemName: "exclamationmark.circle") } .popoverTip(shortNameTip) } } Text("Short Name Length: \(shortName.count) characters") .font(.caption) .foregroundStyle(shortName.count >= shortNameCharacterLimit ? .red : .primary) } HStack { Text("Fluid Amount") Spacer() TextField("Fluid Amount", value: $amount, format: .number) .multilineTextAlignment(.trailing) .textFieldStyle(.roundedBorder) .keyboardType(.decimalPad) .focused($numberPadIsFocused) .frame(width: 140) .toolbar { if numberPadIsFocused { ToolbarItemGroup(placement: .keyboard) { Spacer() Button("Done") { numberPadIsFocused = false } } } } } HStack { Text("Unit of Measure") Spacer() Picker("Unit of measure", selection: $unitOfMeasure) { ForEach(FluidUnit.allCases) { Text($0.title) } } .tint(colorScheme == .dark ? .yellow : .pink) } .accessibilityElement() Toggle("Favorite Drink", isOn: $isFavorite) Text("Drink Image") ScrollView(.horizontal) { HStack{ ForEach(DataStore.drinkImages, id: \.self) { image in Button { selectDrinkImage(imageName: image) } label: { ZStack { Image(image) .resizable() .scaledToFit() .frame(height: 100) if imageName == image { SelectedDrinkImageView() } } } .padding(.trailing, 30) } } .scrollTargetLayout() } .scrollIndicators(.hidden) .scrollTargetBehavior(.viewAligned) Spacer() .navigationTitle("Add a Drink") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .topBarTrailing) { Button("Save") { addDrink() } .tint(colorScheme == .dark ? .yellow : .pink) .disabled(disableSaveButton()) } ToolbarItem(placement: .topBarLeading) { Button("Cancel") { dismiss() } .tint(colorScheme == .dark ? .yellow : .pink) } } } .padding() } }
0
0
195
Jun ’24
TabView Sidebar Style Default?
I'm loving the TabView behaviour, but specifically on a landscape iPad, I'd like to have the app default to sidebar mode. There's tons of space, and for my app it just looks better. I'd like the TabView behaviour everywhere else, though. I know I can set TabView { ... }.tabViewStyle(.sidebarAdaptable) But what I really want is a .sidebarPreferred attribute that uses a sidebar where it would make sense, and a tab bar anywhere else. Even on a portrait iPad I'd like to have the option to have the sidebar style be the default. Is there a way to do this now, or should I open a Feedback? Thanks
1
0
175
Jun ’24
What is the proper way to handle videos in SwiftData ?
I'm creating an application with swiftui which gets images and videos from the Photos picker then store them with swiftData for later use. I save both images and videos as data with  @Attribute(.externalStorage). But it just seems wrong to me to store the videos that way, they can be several gigabytes in size . What is the correct way to handle something like this ? Is it to store the url and then each time the user wants to see a video save a temporary video ?. If that's the case can anyone show me how this should be done? Any comments appreciated Guillermo
0
0
202
Jun ’24
Combining Matched Geometry with New Zoom Navigation Transitions in iOS 18
With the introduction of the new matchedTransitionSource from iOS 18, we can apply a zoom transition in the navigation view using .navigationTransition(.zoom) This works well for zoom animations. However, when I try to apply a matched geometry effect to views that are similar in the source and destination views, the zoom transition works, but those views don't transition seamlessly as they do with a matched geometry effect. Is it possible to still use matched geometry for subviews of the source and destination views along with the new navigationTransition? Here’s a little demo that reproduces this behaviour: struct ContentView: View { let colors: [[Color]] = [ [.red, .blue, .green], [.yellow, .purple, .brown], [.cyan, .gray] ] @Namespace() var namespace var body: some View { NavigationStack { Grid(horizontalSpacing: 50, verticalSpacing: 50) { ForEach(colors, id: \.hashValue) { rowColors in GridRow { ForEach(rowColors, id: \.self) { color in NavigationLink { DetailView(color: color, namespace: namespace) .navigationTransition( .zoom( sourceID: color, in: namespace ) ) .edgesIgnoringSafeArea(.all) } label: { ZStack { RoundedRectangle(cornerRadius: 5) .foregroundStyle(color) .frame(width: 48, height: 48) Image(systemName: "star.fill") .foregroundStyle(Material.bar) .matchedGeometryEffect(id: color, in: namespace, properties: .frame, isSource: false) } } .matchedTransitionSource(id: color, in: namespace) } } } } } } } struct DetailView: View { var color: Color let namespace: Namespace.ID var body: some View { ZStack { color Image(systemName: "star.fill") .resizable() .foregroundStyle(Material.bar) .matchedGeometryEffect(id: color, in: namespace, properties: .frame, isSource: false) .frame(width: 100, height: 100) } .navigationBarHidden(false) } } #Preview { ContentView() }
0
1
280
Jun ’24
TipKit: Popover Tip w/ use of Menu in Toolbar
As the title states, I'm trying to apply a .popoverTip to a Menu { } which is inside of a .toolbar { }. The toolbar has default placement and the menu includes a toggle button, and a NavigationLink. I've ensured that tips can show on the view by using a TipView(tip: ) within my view which displays. Am I missing something? Is this not possible? Alternatively, can anyone recommend a method to potentially debug why a tip won't show for future debugging?
1
0
242
Jun ’24
Typography on Apple Watch Live Activity
I'm not quite sure whether this post belongs in a Design forum or here, but with iOS 18 Developer Beta 1 and watchOS 11 Developer Beta 1, when a Live Activity is displayed on an Apple Watch, the system font used is SF Pro rather than SF Compact. I would expect that the design guidance would be to stick with SF Compact while on watchOS, and I would expect that the system font, when displayed on the Apple Watch using .supplementalActivityFamilies([.small]), would appear as SF Compact. To ensure that SF Compact appears on my Live Activity when viewed on Apple Watch, I can set a custom font for use with the small supplemental family, but this seems really clunky; is there any other guidance here?
0
0
254
Jun ’24