Post

Replies

Boosts

Views

Activity

SwiftUI hidesBottomBarWhenPushed equivalent?
Hello, I'm trying to hide my TabView when I push a new view in my NavigationView but for now it seems that there is no way to do it (I saw a lot of thing on Internet, but nothing seems work properly for me)? By default my code look like this: struct ContentView: View { var body: some View { TabView { NavigationView { view1 } .tabItem { Image(systemName: "house.fill") Text("Home") } NavigationView { view2 } .tabItem { Image(systemName: "bookmark.circle.fill") Text("Bookmark") } } .accentColor(.red) } private var view1: some View { List { NavigationLink { DetailsView() } label: { Text("View 1") } } .navigationTitle("View 1") } private var view2: some View { List { NavigationLink { DetailsView() } label: { Text("View 2") } } .navigationTitle("View 2") } } struct DetailsView: View { var body: some View { EmptyView() } } But then, I don't have any solution to hide my TabView, so I try something like this in my ContentView: var body: some View { NavigationView { TabView { view1 .tabItem { Image(systemName: "house.fill") Text("Home") } .navigationTitle(Text("title")) view2 .tabItem { Image(systemName: "bookmark.circle.fill") Text("Bookmark") } .navigationTitle(Text("title")) } .accentColor(.red) } } Now, the hide on push is working, but it cause some glitch in the navigation bar and I can't set multiple navigationTitle (one for each view) like I did before; I can set only one navigationTitle for the NavigationView. To solve the NavigationView title, I found a workaround by using a @State variable, but it remains this glitch on the navigation bar: sometimes the navigation view background is working, sometimes it's not working and sometimes I have a spacing between the title and the content (like in the Bookmark tab): What am I doing wrong? Does it exist any solution for this issue (hidesBottomBarWhenPushed + navigation bar glitch) ? Thanks, Alexandre
3
1
2.6k
Jul ’22
SwiftUI, List items reordering issue (iOS 16)
Hello, On iOS 15, I had a feature who allow the user to reorder some items inside of a list. Some view was not allowed to move (I use the modifier .moveDisabled for this behavior). In iOS 15, everything was working fine : I'm able to reorder items inside of the list (only for those who was allowed to be moved). But in iOS 16, I have a strange behavior : I still can reorder items, but if two items are not allowed to be reordered, I can't move any items between them. Here is the example : iOS 15 : iOS 16 : For this feature, I only use: standard SwiftUI List. .environment(\.editMode, .constant(.active)) (the view should always be editable). .moveDisabled() to allow items to be moved. No custom element here, everything is SwiftUI framework. What am I doing wrong? Thanks, Alexandre
5
5
2.8k
Sep ’22
SwiftUI Dismiss keyboard in modal issue
Hello, I have an issue with the automatic keyboard dismissing in a modal : If I present a modal with textfields, and I try to dismiss the modal to close the keyboard, the keyboard disappear (that's good) but it leave some space... Here is the example : And here is my code to reproduce the issue (iOS 16, real device) : struct ContentView: View {     @State private var isViewPresented: Bool = false     var body: some View {         Button {             isViewPresented = true         } label: {             Text("Show View")         }         .sheet(isPresented: $isViewPresented) {             FormView()         }     } } struct FormView: View {     var body: some View {         NavigationView {             ScrollView {                 VStack(spacing: 32) {                     TextField("Text 1", text: .constant(""))                         .frame(height: 42)                         .background(Color.red)                     TextField("Text 2", text: .constant(""))                         .frame(height: 42)                         .background(Color.red)                     TextField("Text 3", text: .constant(""))                         .frame(height: 42)                         .background(Color.red)                     TextField("Text 4", text: .constant(""))                         .frame(height: 42)                         .background(Color.red)                 }             }             .background(Color.yellow)             .navigationTitle("Form view")         }     } } As you can see, when I start to dismiss the modal, the keyboard disappear and then there is a black space who appears... Any suggestions ? Thanks, Alexandre
7
3
3.6k
Sep ’22
Strong password autofill, even if we don't want it
Hello, I have three textfields in a view of my application: TextField("Email address", text: $email) SecureField("Password", text: $password) .textContentType(.password) SecureField("Password confirmation", text: $passwordConfirmation) .textContentType(.password) When I tap on the password secure field, iOS show me the strong password view : If I use this feature, everything is working fine, but if I tap on "Other options..." then "Choose my own password": The textfields are cleared (that's great), but if I tap on the email textfield (or any other textfields), the password secure field is filled with the strong password that I've just said I don't want... Here is a video : And here is my code : @State private var email: String = ""     @State private var password: String = ""     @State private var passwordConfirmation: String = ""        var body: some View {         ScrollView {             VStack(spacing: 16) {                 TextField("Email address", text: $email)                 SecureField("Password", text: $password)                     .textContentType(.password)                 SecureField("Password confirmation", text: $passwordConfirmation)                     .textContentType(.password)             }             .padding(.vertical, 32)             .padding(.horizontal, 16)         }     } Any idea ? Thanks, Alexandre
10
1
4.7k
Sep ’22
Copy text without storing it in the UIPasteboard history ?
Hello, To copy some text in the clipboard and be able to paste it in another place, I use this line of code on iOS with Swift : UIPasteboard.general.string = "My text here" I also want to clear the clipboard after a duration, so I updated my code to : UIPasteboard.general.setItems([[UTType.plainText.identifier: "My text here"]], options: [.expirationDate: Date(timeIntervalSinceNow: 60)]) Both those code are working fine but I tried to do something as secure as possible and by trying password manager application (like 1Password for example), I saw that I can copy my password and paste it, but the password is not store in the clipboard history (I'm using "Paste" to be able to see my clipboard history). I didn't see anything about this in the Apple documentation. So, how those password managers are able to do this? I know it is possible to use a custom UIPasteboard but it means that the clipboard is only available in my others applications and I want to be able to paste the text everywhere (depending on user choice). So that's probably not an option for me. Any idea ? Thanks, Alexandre
0
0
485
Apr ’23
Interactive Widget (iOS 17) reload timeline on interaction
Hello everyone 👋 I'm currently implementing the new interactive widget for iOS 17 but there is a behaviour I don't understand. My Goal : The widget I want to create is pretty simple : I have a Store where I can find a list of MyObject, and in the widget I want to display 2 items randomly every X hours. For each item, there is a button to like/unlike the item. The Issue : When I tap the like button, the function func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) of the widget is called again and so, two items are get randomly (so the items I liked disappear). What I want : When two items are got randomly and I tap a like button, I want my item isLiked property to be toggled without refreshing my timeline. My current code : (The code is simplified for the demo, but if you copy/paste all of this code in a new widget, it should compile and run) MyObject final class MyObject { var isLiked: Bool let name: String init(isLiked: Bool, name: String) { self.isLiked = isLiked self.name = name } } MyStore final class MyStore { static let shared: MyStore = .init() private init() { } var myObjects: [MyObject] = [ .init(isLiked: false, name: "Test 1"), .init(isLiked: true, name: "Test 2"), .init(isLiked: false, name: "Test 3"), .init(isLiked: false, name: "Test 4"), .init(isLiked: false, name: "Test 5"), .init(isLiked: true, name: "Test 6"), .init(isLiked: false, name: "Test 7"), .init(isLiked: false, name: "Test 8"), .init(isLiked: false, name: "Test 9"), .init(isLiked: true, name: "Test 10"), .init(isLiked: false, name: "Test 11"), .init(isLiked: false, name: "Test 12"), .init(isLiked: true, name: "Test 13"), .init(isLiked: false, name: "Test 14"), ] func getRandom(_ number: Int) -> [MyObject] { guard !myObjects.isEmpty else { return [] } var random: [MyObject] = [] for _ in 0 ... number - 1 { let randomIndex: Int = Int.random(in: 0...myObjects.count - 1) random.append(myObjects[randomIndex]) } return random } } My action intent import AppIntents struct AddOrRemoveFromFavoriteAppIntent: AppIntent { static let title: LocalizedStringResource = "My title" static let description: IntentDescription = .init("My description") @Parameter(title: "name") var name: String init() { } init(name: String) { self.name = name } func perform() async throws -> some IntentResult { MyStore.shared.myObjects.first(where: { $0.name == name })?.isLiked.toggle() return .result() } } My widget struct MyWidget: Widget { let kind: String = "MyWidget" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: Provider()) { entry in MyWidgetEntryView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } .configurationDisplayName("My Widget") .description("This is an example widget.") } } My widget view struct MyWidgetEntryView : View { var entry: Provider.Entry var body: some View { if entry.objects.count >= 2 { HStack { HStack { Text(entry.objects[0].name) Button(intent: AddOrRemoveFromFavoriteAppIntent(name: entry.objects[0].name)) { Text(entry.objects[0].isLiked ? "Unlike" : "Like") } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.red) HStack { Text(entry.objects[1].name) Button(intent: AddOrRemoveFromFavoriteAppIntent(name: entry.objects[1].name)) { Text(entry.objects[1].isLiked ? "Unlike" : "Like") } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.green) } } else { Text("No data") } } } My widget model struct SimpleEntry: TimelineEntry { let date: Date let objects: [MyObject] } My widget provider struct Provider: TimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), objects: []) } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { let entry = SimpleEntry(date: Date(), objects: []) completion(entry) } func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) { var entries: [SimpleEntry] = [] let currentDate = Date() for hourOffset in 0 ..< 5 { let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! let entry = SimpleEntry(date: entryDate, objects: MyStore.shared.getRandom(2)) entries.append(entry) } let timeline = Timeline(entries: entries, policy: .atEnd) completion(timeline) } } What am I missing ? Are widgets not designed for this use case ? Thanks 🙏 Alexandre
3
0
2.3k
Aug ’23
Picture in Picture with WebRTC, nothing displayed
Hello 👋 I try to implement picture in picture on iOS with webRTC but I have some issue. I started by following this Apple article : https://developer.apple.com/documentation/avkit/adopting_picture_in_picture_for_video_calls At least when my app is in background, the picture in picture view appear, but nothing is display within it : So by searching on internet I found this post in Stackoverflow (https://stackoverflow.com/questions/71419635/how-to-add-picture-in-picture-pip-for-webrtc-video-calls-in-ios-swift), who says : It's interesting but unfortunately, I don't know what I have to do... Here is my PictureInPictureManager : final class VideoBufferView: UIView { override class var layerClass: AnyClass { AVSampleBufferDisplayLayer.self } var sampleBufferDisplayLayer: AVSampleBufferDisplayLayer { layer as! AVSampleBufferDisplayLayer } } final class PictureInPictureManager: NSObject { static let shared: PictureInPictureManager = .init() private override init() { } private var pipController: AVPictureInPictureController? private var bufferView: VideoBufferView = .init() func configure(for videoView: UIView) { if AVPictureInPictureController.isPictureInPictureSupported() { let bufferView: VideoBufferView = .init() let pipVideoCallViewController: AVPictureInPictureVideoCallViewController = .init() pipVideoCallViewController.preferredContentSize = CGSize(width: 108, height: 192) pipVideoCallViewController.view.addSubview(bufferView) let pipContentSource: AVPictureInPictureController.ContentSource = .init( activeVideoCallSourceView: videoView, contentViewController: pipVideoCallViewController ) pipController = .init(contentSource: pipContentSource) pipController?.canStartPictureInPictureAutomaticallyFromInline = true pipController?.delegate = self } else { print("❌ PIP not supported...") } } } With this code, the picture in picture view appear empty. I read multiple article who talk about using the buffer but I'm not sure how to do it with webRTC... I tried by adding this function to my PictureInPictureManager : func updateBuffer(with pixelBuffer: CVPixelBuffer) { if let sampleBuffer = createSampleBufferFrom(pixelBuffer: pixelBuffer) { bufferView.sampleBufferDisplayLayer.enqueue(sampleBuffer) } else { print("❌ Sample buffer error...") } } private func createSampleBufferFrom(pixelBuffer: CVPixelBuffer) -> CMSampleBuffer? { var presentationTime = CMSampleTimingInfo() // Create a format description for the pixel buffer var formatDescription: CMVideoFormatDescription? let formatDescriptionError = CMVideoFormatDescriptionCreateForImageBuffer( allocator: kCFAllocatorDefault, imageBuffer: pixelBuffer, formatDescriptionOut: &formatDescription ) guard formatDescriptionError == noErr else { print("❌ Error creating format description: \(formatDescriptionError)") return nil } // Create a sample buffer var sampleBuffer: CMSampleBuffer? let sampleBufferError = CMSampleBufferCreateReadyWithImageBuffer( allocator: kCFAllocatorDefault, imageBuffer: pixelBuffer, formatDescription: formatDescription!, sampleTiming: &presentationTime, sampleBufferOut: &sampleBuffer ) guard sampleBufferError == noErr else { print("❌ Error creating sample buffer: \(sampleBufferError)") return nil } return sampleBuffer } but by doing that, I get this error message : Any help is welcome ! 🙏 Thanks, Alexandre
3
0
1.4k
Oct ’23
SwiftUI preview : PropertyListError: Property list missing value for required key "binaryType"
Hello, SwiftUI previews are not working in my project : when I try to display the preview in Xcode, I got this error : And if I click on the help icon, here is the complete error message : RemoteHumanReadableError: Invalid preview service message on ServiceHub channel ================================== | RemoteHumanReadableError | | PropertyListError: Property list missing value for required key ”binaryType” | Property list: ["agentRole": previews, "environment": { | "DYLD_FRAMEWORK_PATH" = "/Users/alexandrecools/Library/Developer/Xcode/DerivedData/MyProject-gqsbendjcwgnvygdhqcoqqznoijh/Build/Intermediates.noindex/Previews/PreviewTesting/Products/Debug-iphonesimulator"; | "DYLD_LIBRARY_PATH" = "/Users/alexandrecools/Library/Developer/Xcode/DerivedData/MyProject-gqsbendjcwgnvygdhqcoqqznoijh/Build/Intermediates.noindex/Previews/PreviewTesting/Products/Debug-iphonesimulator"; | "OS_ACTIVITY_DT_MODE" = YES; | "PACKAGE_RESOURCE_BUNDLE_URL" = "/Users/alexandrecools/Library/Developer/Xcode/DerivedData/MyProject-gqsbendjcwgnvygdhqcoqqznoijh/Build/Intermediates.noindex/Previews/PreviewTesting/Products/Debug-iphoneos"; | "SQLITE_ENABLE_THREAD_ASSERTIONS" = 1; | "XCODE_RUNNING_FOR_PREVIEWS" = 1; | "__XCODE_BUILT_PRODUCTS_DIR_PATHS" = "/Users/alexandrecools/Library/Developer/Xcode/DerivedData/MyProject-gqsbendjcwgnvygdhqcoqqznoijh/Build/Intermediates.noindex/Previews/PreviewTesting/Products/Debug-iphonesimulator"; | "__XPC_DYLD_FRAMEWORK_PATH" = "/Users/alexandrecools/Library/Developer/Xcode/DerivedData/MyProject-gqsbendjcwgnvygdhqcoqqznoijh/Build/Intermediates.noindex/Previews/PreviewTesting/Products/Debug-iphonesimulator"; | "__XPC_DYLD_LIBRARY_PATH" = "/Users/alexandrecools/Library/Developer/Xcode/DerivedData/MyProject-gqsbendjcwgnvygdhqcoqqznoijh/Build/Intermediates.noindex/Previews/PreviewTesting/Products/Debug-iphonesimulator"; | }, "__unique_service_message_identifier": 4, "deviceEnvironment": { | "SIMULATOR_CAPABILITIES" = "/Applications/Xcode 14.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/DeviceTypes/iPhone 14 Pro Max.simdevicetype/Contents/Resources/capabilities.plist"; | "SIMULATOR_DEVICE_NAME" = iPhone4Simulator; | "SIMULATOR_LEGACY_ASSET_SUFFIX" = iphone; | "SIMULATOR_MAINSCREEN_HEIGHT" = 2796; | "SIMULATOR_MAINSCREEN_PITCH" = "460.000000"; | "SIMULATOR_MAINSCREEN_SCALE" = "3.000000"; | "SIMULATOR_MAINSCREEN_WIDTH" = 1290; | "SIMULATOR_MODEL_IDENTIFIER" = "iPhone15,3"; | "SIMULATOR_PRODUCT_CLASS" = D74; | }, "agentIdentifier": { | bundleID = "com.apple.dt.XCPreviewAgent"; | discriminant = bundleID; | }, "displaySize": { | height = 932; | width = 430; | }, "deviceIdentifier": com.apple.CoreSimulator.SimDeviceType.iPhone-14-Pro-Max, "processType": application, "arguments": <__NSArray0 0x1b9e04f48>( | | ) | , "workspaceID": E4CEE565-58C6-4EB5-94F1-7A9F48791515, "deviceType": simulated, "payloadUsedAgentIdentifier": 1, "frameBufferMaskPath": /Applications/Xcode 14.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/DeviceTypes/iPhone 14 Pro Max.simdevicetype/Contents/Resources/framebuffer.pdf, "displayScale": 3, "bundleID": com.apple.dt.XCPreviewAgent] ================================== | MessageSendFailure: Message send failure for <ServiceMessage 4: relaunch> Is there anyone who already encountered this error message? Or maybe anyone who have any idea how to solve it? Thanks, Alexandre
1
0
778
Nov ’23
No profiles for ... were found
Hi, I'm having some problems signing my application. Everything was working fine until recently when the certificates expired and I got these kinds of errors when I try to upload the app to AppStoreConnect. I can build the app in dev and production mode without any issue and I can create an archive. Problems occur when uploading to AppStoreConnect. The idea would be to let Xcode take care of signing everything necessary by checking the "Automatically manage signing" box. All my targets are in "Automatically manage signing" mode. I tried to delete all the certificates and provisioning profiles that I found on the Apple portal and then generate them again, but the problem is the same. There are two of us on the team, plus a CI machine (this should be the CI that takes care of signing everything needed to send a release to AppStoreConnect). If you have an idea, I'm interested! Thanks in advance, Alexandre
1
0
1.4k
Jun ’24