Hi all,
It wasn't extensively covered in the "Unlock the power of places with MapKit" at WWDC, but is it possible to add your own views to the mapItemDetailAccessory? The default view is great, but I would like to add a button for opening a new window showing another view. The documentation is rather limited at the moment so I thought I would ask here.
Thanks in advance.
SwiftUI
RSS for tagProvide views, controls, and layout structures for declaring your app's user interface using SwiftUI.
Post
Replies
Boosts
Views
Activity
Summary
When trying to display SwiftUI previews, building the previews may fail with the following error:
Linking failed: linker command failed with exit code 1 (use -v to see invocation)
ld: warning: search path '/Applications/Xcode.app/Contents/SharedFrameworks-iphonesimulator' not found
ld: warning: Could not find or use auto-linked framework 'CoreAudioTypes': framework 'CoreAudioTypes' not found
Note that may app does not use CoreAudioTypes.
Observation
This issue seems to occur when two conditions are met:
The SwiftUI view must be located in a Swift Package
Somewhere in either the View or the #Preview a type from another package has to be used.
Say I have to packages one named Model-package and one named UI-Package. The UI-Package depends on the Model-Package. If I have a SwiftUI view in the UI-Package that uses a type of the Model-Package either in the View itself or in the #Preview, then the described error occurs. If I have a View in the UI-package that does not use a type of the Model-Package anywhere in its View or #Preview then the SwiftUI Preview builds and renders successful.
I created a bug report: FB13033812
I have two (local) Swift packages (both with a single library product): RemoteImage, which defines setImage(from:) function on UIImageView and SatelitUI package which directly depends on the first one and defines some views. But when I'm trying to preview views from the second package I'm getting the following error:
linker command failed with exit code 1 (use -v to see invocation)
LinkDylibError: Failed to build TrailerView.swift
Linking failed: linker command failed with exit code 1 (use -v to see invocation)
ld: warning: directory not found for option '-F/Applications/Xcode-beta.app/Contents/SharedFrameworks-iphonesimulator'
Undefined symbols for architecture x86_64:
"(extension in RemoteImage):__C.UIImageView.setImage(from: Foundation.URL?) -> ()", referenced from:
(extension in SatelitUI_PreviewReplacement_TrailerView_2):SatelitUI.TrailerView.(previewupdate in _8C3731B0EF007627509BEEB93277D681)(with: SatelitUI.Trailer?) -> () in TrailerView.2.preview-thunk.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Apparently, Xcode fails to link the library from the first package because it's dynamic. Static linking works as expected.
It's a bug I believe?
Hi all, I have done a lot of research on this but am not able to come up with a workable solution.
Background:
I am trying to make an universal app on macOS/iOS that organizes media (image/video/pdf); think of its functionality like Apple's Photos app. So for my app document type, I would have my custom file package and within the package folder, there would be a SwiftData model container file and folders to hold user media.
Approaches taken:
DocumentGroup with SwiftData model then write directly into the file package
In my App scene, I create document by having DocumentGroup(editing: .customDocument, migrationPlan: CustomMigrationPlan.self). This will create a document with a model container with my SwiftData model. And when I need to add media files into the document, I get the URL of the document, then use FileManager to write the file into the desired folder in the document. The result is that the media file is saved in the file package but then the SwiftData container is corrupted (all model data is reset to empty.)
I am now trying to:
2. DocumentGroup with custom file package then try to embed SwiftData container
In my current approach, I would create a document by having DocumentGroup(newDocument: CustomFileDocument()). I have custom FileDocument and FileWrapper. But the problem is I don't know how to embed a SwiftData container into my FileDocument. Is it possible to create a SwiftData model container when my FilerWrapper initialize? I can't figure out how to do this.
Can anyone please advice on how I should accomplish this? Or if maybe I am looking at this problem wrongly? Do I need to use AppKit/UIKit with Core Data because it's currently not possible with SwiftUI/SwiftData?
Thank you so much for reading and any input is greatly appreciated.
I'm creating an app where I'm recreating how Apple Maps shows the user location button - i.e, in a stack with a background. I'd like the MapUserLocationButton to follow the styling that it does in Apple Maps (i.e., when locked to the user location, it switches to a filled icon, instead of colouring the background. Is there a way to do this?
This is a report of an issue that appears to be a regression regarding NavigationStack.
I have been aware of an issue where views are being automatically popped within NavigationView / NavigationStack since iOS 15, and it seems to be reoccurring in iOS 18.0 beta2.
Below is the reproducible code. Additionally, in my environment, this problem does not occur iOS 18 simulator, but it does happen on an iPhone XS Max(real device) with iOS 18 beta 2.
Environment:
Xcode: Version 16.0 beta (16A5171c)
iOS: 18.0 (22A5297f)
iPhone: XS Max (real device)
import SwiftUI
@main
struct iOS16_4NavigationSample2App: App {
var body: some Scene {
WindowGroup {
NavigationStack {
NavigationLink {
ContentView()
} label: {
Text("Content")
}
}
}
}
}
enum Kind { case none, a, b, c }
struct Value: Hashable, Identifiable {
let id: UUID = UUID()
var num: Int
}
@MainActor
class ContentModel: ObservableObject {
@Published var kind: Kind = .a
@Published var vals: [Value] = {
return (1...5).map { Value(num: $0) }
}()
init() {}
}
struct ContentView: View {
@StateObject private var model = ContentModel()
@State private var selectedData: Value?
@State private var isShowingSubView = false
@Environment(\.dismiss) private var dismiss
init() {
}
var body: some View {
if #available(iOS 16.0, *) {
List(selection: $selectedData) {
ForEach(model.vals) { val in
NavigationLink(value: val) {
Text("\(val.num)")
}
}
}
.navigationDestination(isPresented: .init(get: {
selectedData != nil
}, set: { newValue in
if !newValue && selectedData != nil {
selectedData = nil
}
}), destination: {
SubView(kind: model.kind)
})
}
}
}
struct SubView: View {
init(kind: Kind) {
print("init(kind:)")
}
init() {
print("init")
}
var body: some View {
Text("Content")
}
}
This code was shared in a different issue [iOS 16.4 NavigationStack Behavior Unstable].
I'm trying to convert my project to use Swift 6 with Complete Concurrency in Xcode 16 beta 1.
The project uses TipKit, but I'm getting compile errors when trying to use the TipKit Parameters feature. Here is an example of the type of error I'm seeing (Note that this code from https://developer.apple.com/documentation/tipkit/highlightingappfeatureswithtipkit):
struct ParameterRuleTip: Tip {
// Define the app state you want to track.
@Parameter
static var isLoggedIn: Bool = false
Static property '$isLoggedIn' is not concurrency-safe because it is non-isolated global shared mutable state.
Is there a new pattern for supporting TipKit Parameters in Swift 6 with Complete Concurrency enabled? There is no obvious suggestion for how to fix this.
The latest WWDC 2024 TipKit doesn't appear to have any solution(s).
Is there a way to optimize a List in SwiftUI?
There is a problem with selection not working properly when the List has many rows.
If you scroll to multi-select and up, some rows in the middle are not selected.
I have an issue where selecting an unselected row deselects nearby rows.
Is there any way for selection to work reliably even for a List of many rows?
I would like to find a solution that is stable even when multiple lines are selected, like mail and note, which are the default apps in ios.
ps. I am using CoreData.
@State var selectedItem = Set<MyEntity>()
List(selection: $selectItem){
ForEach(items, id: \.self){ item in
ContactsRow(contactsData: item)
}
}
.environment(\.editMode, $editMode)
I am new to SwiftUI, and I wrote a ReorderableForEach struct with onDrag and onDrop, which is working well on iOS17. However it's not wokring on iOS18 beta1 or beta2 on my iPhone or simulator. When I long press the item, nothing happens.
When I remove onDrop, I can perform a Drag animation, so I think something wrong with my onDrop code.
the whole code:
import UIKit
import SwiftUI
public typealias Reorderable = Identifiable & Equatable
struct GridData: Identifiable, Equatable {
let id: Int
}
public struct ReorderableForEach<Item: Reorderable, Content: View, Preview: View>: View {
@Binding
private var active: Item?
@State
private var hasChangedLocation = false
private let items: [Item]
private let content: (Item) -> Content
private let preview: ((Item) -> Preview)?
private let moveAction: (IndexSet, Int) -> Void
private var onDropAction: ((Item) -> Void)?
private var allowReorder: Bool
public init(
_ items: [Item],
active: Binding<Item?>,
allowReorder: Bool,
@ViewBuilder content: @escaping (Item) -> Content,
@ViewBuilder preview: @escaping (Item) -> Preview,
moveAction: @escaping (IndexSet, Int) -> Void,
onDropAction: ((Item) -> Void)? = nil
) {
self.items = items
self._active = active
self.allowReorder = allowReorder
self.content = content
self.preview = preview
self.moveAction = moveAction
self.onDropAction = onDropAction
}
public init(
_ items: [Item],
active: Binding<Item?>,
allowReorder: Bool,
@ViewBuilder content: @escaping (Item) -> Content,
moveAction: @escaping (IndexSet, Int) -> Void,
onDropAction: ((Item) -> Void)? = nil
) where Preview == EmptyView {
self.items = items
self._active = active
self.allowReorder = allowReorder
self.content = content
self.preview = nil
self.moveAction = moveAction
self.onDropAction = onDropAction
}
public var body: some View {
ForEach(items) { item in
if !allowReorder {
contentView(for: item)
}
else if let preview {
contentView(for: item)
.onDrag {
return dragData(for: item)
} preview: {
preview(item)
}
} else {
contentView(for: item)
.onDrag {
return dragData(for: item)
}
}
}
}
private func contentView(for item: Item) -> some View {
content(item)
.opacity(active == item && hasChangedLocation ? 0.5 : 1)
.onDrop(
of: [.text],
delegate: ReorderableDragRelocateDelegate(
item: item,
items: items,
active: $active,
hasChangedLocation: $hasChangedLocation
) { from, to in
withAnimation {
moveAction(from, to)
}
} onDropAction: { item in
onDropAction?(item)
}
)
}
private func dragData(for item: Item) -> NSItemProvider {
active = item
return NSItemProvider(object: "\(item.id)" as NSString)
}
}
struct ReorderableDragRelocateDelegate<Item: Reorderable>: DropDelegate {
let item: Item
var items: [Item]
@Binding var active: Item?
@Binding var hasChangedLocation: Bool
var moveAction: (IndexSet, Int) -> Void
var onDropAction: ((Item) -> Void)?
func dropEntered(info: DropInfo) {
guard item != active, let current = active else { return }
guard let from = items.firstIndex(of: current) else { return }
guard let to = items.firstIndex(of: item) else { return }
hasChangedLocation = true
if items[to] != current {
moveAction(IndexSet(integer: from), to > from ? to + 1 : to)
}
}
func dropUpdated(info: DropInfo) -> DropProposal? {
DropProposal(operation: .move)
}
func performDrop(info: DropInfo) -> Bool {
hasChangedLocation = false
active = nil
onDropAction?(item)
return true
}
}
struct ReorderableDropOutsideDelegate<Item: Reorderable>: DropDelegate {
@Binding
var active: Item?
func dropUpdated(info: DropInfo) -> DropProposal? {
DropProposal(operation: .move)
}
func performDrop(info: DropInfo) -> Bool {
active = nil
return true
}
}
public extension View {
func reorderableForEachContainer<Item: Reorderable>(
active: Binding<Item?>
) -> some View {
onDrop(of: [.text], delegate: ReorderableDropOutsideDelegate(active: active))
}
}
#Preview {
ReorderableForEach(
(1...10).map { GridData(id: $0) },
active: .constant(nil),
allowReorder: true
) { item in
Text("Item \(item.id)")
.padding()
.background(Color.blue)
.cornerRadius(8)
} preview: { item in
Text("Preview \(item.id)")
.padding()
.background(Color.red)
.cornerRadius(8)
} moveAction: { from, to in
print("Move from \(from) to \(to)")
}
}
Am I missing something or this is a bug on iOS18?
Thanks in advance.
We have an app that is saving UIColor through NSKeyedArchiver.archivedData to a file.
Now we are trying to port the app to a Mac and will like to load the UIColor. But on a Mac, we are using NSColor. Are there any recommendations of what I can do?
When using the Navigation Stack with paths, I've faced an issue where tapping the 'back' button on the custom navigation bar results in a blank screen. With light theme the screen is white, when using dark theme the screen is black. I've found a decision with using an environment value to dismiss a single screen when needed. However, the problem becomes more prominent when I want to pop back to the root view.
This issue has become since updating to iOS 17.
Using the new navigationDestination and NavigationPath functions previously on iOS 16 everything has been working fine using a custom back button, which calls path.removeLast().
However, if we try this on iOS 17, the screen being removed flashes white.
You can try this code as an example (NOTE THE WHITE FLASH ON REMOVE LAST):
struct DetailView: View {
@Binding var path: NavigationPath
var body: some View {
ZStack {
Color.black
VStack(alignment: .center) {
Spacer()
Button(action: {
path.removeLast()
}, label: {
Text("BACK")
})
Spacer()
}
}
}
}
struct ParentView: View {
@State var path: NavigationPath = .init()
var body: some View {
NavigationStack(path: $path) {
ZStack {
Color.red
VStack(alignment: .center) {
Spacer()
Button(action: {
path.append("TEST")
}, label: {
Text("FORWARD")
})
Spacer()
}
}
.navigationDestination(for: String.self) { _ in
DetailView(path: $path)
}
}
}
}
Any work arounds? Suggestions?
I have a horizontal scroll view and a fixed array. I would like to loop it such that when I scroll left and get near the end, the array will add the items in the beginning to the end so that the user can continue to scroll. I would like this to happen when scrolling both left and right and to not have the current position of the user jump around. Here is my code. What am I missing? Would appreciate any and all help.
import SwiftUI
import Algorithms
struct ContentView: View {
@State private var timePosition = ScrollPosition(idType: Int.self, edge: .leading)
@State private var times: [Int] = Array(0...23)
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 0) {
ForEach(times, id:\.self) { time in
Text("\(time)")
.font(.system(.callout, design: .monospaced, weight: .semibold))
.padding(8)
.frame(width: 180, height: 110, alignment: .topLeading)
.border(width: 1, edges: [.leading, .trailing], color: .primary.opacity(0.05))
.id(time)
}
}
.scrollTargetLayout()
}
.frame(height: 110)
.scrollPosition($timeScrollPosition, anchor: .center)
.onScrollTargetVisibilityChange(idType: Int.self) { timeIDs in
if let currentViewID = model.timeScrollPosition.viewID {
if timeIDs.contains(times[times.count - 2]) {
times.rotate(toStartAt: times.count - 1)
}
if timeIDs.contains(times[1]) {
times.rotate(toStartAt: times.count-1)
}
print("New times: \(times)")
timeScrollPosition.scrollTo(id: currentViewID)
}
}
}
}
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.
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.
See FB13917278 (App Becomes Unresponsive for iOS/iPadOS 18 Regular Size Class Interactions When Selecting One Particular View in Sidebar).
Hi
I have an enum of the TextFields in an Update SwiftData view. When the view opens, the focus is correct, and the button in the .toolbar keyboard sets the focus to nil and dismisses the keyboard. It works just fine.
But, if I tap on a different TextField other than the original field that the focus was set in a .onAppear, the button on the keyboard dims out and no longer works.
This same code works as expected in another view, the only difference in the Update view is that the data in the fields comes from an @Bindable variable.
Any clue what is going on?
Thanks so much!
Blessings,
--Mark
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!
In my case, I open an immersiveSpace and windowGroupA together. When I successfully push a new windowGroupB from windowGroupA, dismissing windowGroupB should return me to windowGroupA. However, this fails, and windowGroupA remains in the background scenePhase. I tried closing immersiveSpace, and it worked successfully. Therefore, pushWindow cannot be used when immersiveSpace is open.
Greetings -
If I build an app using DocumentGroup, I get the document picker when the app launches.
A good iOS app should restore the state the app was in when it was closed. It seems like with DocumentGroup, when the user leaves my app and the app is killed, the next time they launch it, they have to remember the document they were working on and reopen it.
How can I have my DocumentGroup-based app restore the last open document at launch?
FB13874563
Thanks - Steve