Explore the various UI frameworks available for building app interfaces. Discuss the use cases for different frameworks, share best practices, and get help with specific framework-related questions.

All subtopics

Post

Replies

Boosts

Views

Activity

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
60
2d
UICollectionView scrolls back to 0 using comp layout
PLATFORM AND VERSION: iOS Development environment: Xcode 15.2 macOS 13.6.3 iOS 17.2 DESCRIPTION OF PROBLEM Using a UICollectionView with compositional layout, once the view is created, programmatically scroll to a row using the scrollToItem method. For this report I created a simple dataSource with 400 rows and 1 section. Scrolling to row 200 in viewDidLoad or viewWillAppear after calling collectionView.layoutIfNeeded(). The compositional layout's orthogonalScrollingBehavior is set to .groupPagingCentered The collectionView behaves as expected and shows row 200. Issue The issue is that when swiping too quickly to go to row 199 or prior the entire collectionView is reset to row 0. This does not happen when swiping to go on row 201 or above. STEPS TO REPRODUCE Run the app on iPhone. Swipe right quickly (to go to row prior to 200) Expected result: row 199 or 198 is shown Actual result: collectionView is reset to row 0
0
0
58
2d
Force accessible Color
Looking at Apple's Color Guidelines and taking into account that building my app to work for both light/dark modes I run into an issue where I want to use colors for statuses: red and green. I want to avoid declaring custom colors and I try to use the default ones that adjust for the selected appearance. Unfortunately I noticed that the Color.green does not work well on the default light background of my view (.background(Color (.windowBackgroundColor))) because there is not enough contrast. I noticed that Apple also lists "Accessible" versions of those colors but these are probably managed dynamically. My question: Is there a way to programatically force my app to use the accessible version of a Color (e.g. green)? Thanks
1
0
57
2d
TipKit: explicit vs. implicit iCloud sync
With iOS 18, TipKit got explicit support for syncing tip state via iCloud. However, before that, TipKit already did iCloud syncing implicitly, as far as I know. How does the new explicit syncing relate to the previous mechanism? Do we have to enable iCloud syncing manually now to retain the functionality in iOS 18? Is there a way to sync with the state that was already stored by TipKit in iCloud on iOS 17?
0
0
55
3d
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
0
104
3d
SwiftUI document-based app bug
I have a simple text editor style app, based on the XCode template of an iOS document-based app. Everything works really – except the unfolding of the dropdown on the first opening of a new file. On real hardware (eg. my iPhone or iPad) it is consistently a problem. Everything is up-to-date and rebooted etc. etc. On the XCode Simulator, I can't get it to do it. I've included 3 screenshots, one showing how it should look when properly unfolded on the XCode Simulator, the other when it hasn't unfolded properly on the first opening of a document, and lastly, subsequent visits to that dropdown and it will behave correctly.
0
0
48
3d
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
89
3d
View identities updated on every keystroke in .searchable
I have a SwiftUI list that is backed by a @FetchRequest to Core Data. To display the items in the list it is necessary to traverse relationships on the originally fetched objects and currently the fetch is a little bit slow, while a number of the objects being displayed require images to be rendered, so overall it is a heavy view at present. I am working to make both the view rendering and the fetch more efficient, but alongside that I tried to improve the user experience by debouncing the connection between the user's search text and when the predicate would be updated on the @FetchRequest. This was quite simple to do, and meant the source data would only be re-fetched when the user had stopped typing for at least 0.5 seconds. However, what this demonstrated was that with a .searchable attached to the list, all items in the list were being updated on every keystroke, with printing changes revealing it was because their identity itself was changing, rather than any content. I found this was still the case even if I completely removed my updating of the predicate, so the text binding from the .searchable was stored in an @State value on the view, or stored in a @Binding to some other location, but was not being read nor used for anything else. Is this intended as a "feature" of .searchable, that it is intentionally triggering a view update on the assumption that when the .searchable text is changed that the view will want to change? If so, this is definitely a bug in SwiftUI from the perspective of how I was wanting to use it. Alternatively, any pointers to how I might be triggering this issue would be appreciated!
0
0
141
3d
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
82
3d
TextField set behavior request
Hello there! I come from Objective-C and there I could have an NSTextField set to not be editable or selectable: NSTextField *outputfield; [outputfield setEditable:false]; [outputfield setSelectable:false]; You can do the same in Xcode's Interface Builder panel and select options from a Picker to (Selectable, Editable or None): There is no way to achieve this in SwiftUI and the only option you have is to set a TextField() as .disabled which is not the same. I often used this setters to have an evenly looking form but where only output text (that's not meant to be edited) is show but is clearly visible. The text inside a .disabled text field has no contrast and is not clearly visible. Therefore I would like to request an addition of these two modifiers: selectable(_ selectable: Bool) editable(_ editable: Bool) I am looking forward to fully switch to SwiftUI therefore whenever I encounter something that I could do in Obj-c/Cocoa but not in SwiftUI I will evaluate and suggest it as an addition. Thanks!
2
0
73
3d
Xcode previews fail with JIT error
== PREVIEW UPDATE ERROR: JITError ================================== | NoBuiltTargetDescriptionCouldBeFound | | translationUnit: PreviewTranslationUnit(moduleNamePrefix: "Previews_EmptyFeedRow", sourceIdentifier: file:///Users/bryananderson/Developer/JournalApp/JournalApp/Interface/Feed/EmptyFeedRow.swift -> EmptyFeedRow.swift, parseTree: ParseTree(version: 727, statements: 3, providers: 1), update: nil, changesContextMemoizer: PreviewsPipeline.PreviewTranslationUnit.(unknown context at $34b4b9c4c).ChangesContextMemoizer(parseTree: ParseTree(version: 727, statements: 3, providers: 1), sourceIdentifier: file:///Users/bryananderson/Developer/JournalApp/JournalApp/Interface/Feed/EmptyFeedRow.swift -> EmptyFeedRow.swift, cachedValue: os.OSAllocatedUnfairLock<Swift.Optional<PreviewsModel.ParseTree.PreviewChangesContext>>(__lock: Swift.ManagedBuffer<Swift.Optional<PreviewsModel.ParseTree.PreviewChangesContext>, __C.os_unfair_lock_s>)), registryDeclarationMemoizer: PreviewsPipeline.PreviewTranslationUnit.(unknown context at $34b4b9bec).RegistryDeclarationMemoizer) | | builtTargetDescriptions: | == VERSION INFO: Tools: 16A5171c OS: 24A5264n PID: 906 Model: MacBook Pro Arch: arm64e == ENVIRONMENT: openFiles = [ /Users/bryananderson/Developer/JournalApp/JournalApp/Interface/Feed/EmptyFeedRow.swift ] wantsNewBuildSystem = true newBuildSystemAvailable = true activeScheme = JournalApp activeRunDestination = iPhone 15 Pro variant iphonesimulator arm64 workspaceArena = [x] buildArena = [x] buildableEntries = [ Remember.app ] runMode = JIT Executor == SELECTED RUN DESTINATION: name = iPhone 15 Pro eligible = true sdk = Optional(<DVTSDK:0x13870da30:'iphonesimulator18.0':Simulator - iOS 18.0:<DVTFilePath:0x600001e8c700:'/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.0.sdk'>>) variant = Optional("iphonesimulator") device = Optional(<DVTiPhoneSimulator: 0x32f00d290> { SimDevice: iPhone 15 Pro (CF3C85BC-F559-4437-9072-7F30153B399B, iOS 18.0, Booted) PairedSim: <DVTiPhoneSimulator: 0x33733d150> { SimDevice: Apple Watch Series 9 (45mm) (627CE93E-EB02-4200-BE40-3DCB5C91DB44, watchOS 11.0, Shutdown) } }) == SELECTED RUN DESTINATION: Simulator - iOS 18.0 | iphonesimulator | arm64 | iPhone 15 Pro | Apple Watch Series 9 (45mm) jit enabled: true fallback to dynamic replacement: false
2
1
90
3d
List Rows Can Be Moved While Not Editing
Hi, I am building a view containing a list of struct objects. I have implemented the onMove to allow the list rows to be moved together with the toolbar EditButton. This works but I have a problem as per title, even when the EditButton is not clicked, i.e., not in editing mode, I still can move the list rows by long pressing the rows. I have searched high and low for a solution but couldn't find one that works perfectly. Below is the code snippet. I am a new iOS dev and really appreciate if someone could help me. Many thanks! @AppStorage("fruits") private var fruits = Fruits.fruits var body: some View { NavigationStack { VStack { List { ForEach(fruits) { fruit in NavigationLink(destination: FruitsView(title: fruit.title)) { fruit.icon Text(fruit.title) } } .onMove { fruits.move(fromOffsets: $0, toOffset: $1) } } .environment(\.defaultMinListRowHeight, UIElementConstants.listCellHeight) } .toolbar { EditButton() } .navigationTitle("Fruits") } } struct Fruits: Identifiable, Codable { var id: UUID var title: String var iconName: String var icon: Image { Image(systemName: self.iconName) } init(id: UUID = UUID(), title: String, iconName: String) { self.id = id self.title = title self.iconName = iconName } } extension Fruits { static let fruits: [Fruits] = [ Fruits( title: "Apple", iconName: "basket.fill"), Fruits( title: "Banana", iconName: "basket.fill"), Fruits( title: "Pineapple", iconName: "basket.fill") ] }
2
1
111
3d
Data update issue when both parent and child views are @State in SwiftUI
Here is my test code import SwiftUI struct SubView1: View { @State var data: String var body: some View { Text(data) let _ = addr() } func addr() { let a = withUnsafePointer(to: data) { pointer in return"\(pointer)" } let b = withUnsafePointer(to: self) { pointer in return"\(pointer)" } print("SubView1, \(a), \(b), \(self)") } } struct SubView2: View { var data: String var body: some View { Text(data) let _ = addr() } func addr() { let a = withUnsafePointer(to: data) { pointer in return"\(pointer)" } let b = withUnsafePointer(to: self) { pointer in return"\(pointer)" } print("SubView2, \(a), \(b), \(self)") } } struct ContentView: View { @State var data: String = "a" var body: some View { let _ = print("ContentView") SubView1(data: data) SubView2(data: data) Button("change") { data = "b" print("changed") } } } Here is what is printed ContentView SubView1, 0x000000016ce791a8, 0x000000016ce79170, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView1, 0x000000016ce79260, 0x000000016ce79230, SubView2(data: "a") changed ContentView SubView1, 0x000000016ce7d548, 0x000000016ce7d510, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView1, 0x000000016ce7d600, 0x000000016ce7d5d0, SubView2(data: "b") In my understanding, @State wrapping is monitoring of variables, and when the wrapped variables change, it will trigger the update of this page. Updating the interface means recreating the body, so all subpages will be recreated. When I click the button, the data of ContentView is updated first, which leads to the update of ContentView , and then leads to the reconstruction of SubView1 and SubView2. Judging from the changed address, it is indeed rebuilt rather than reused. But the problem is that the data of ContentView has been updated to "b" at this time, and SubView2 is indeed reinitialized using "b", so why does SubView1 still use "a"? In addition, I modified another one and added a SubView1 to ContentView struct ContentView: View { @State var data: String = "a" var body: some View { let _ = print("ContentView") SubView1(data: data) SubView2(data: data) SubView1(data: data) Button("change") { data = "b" print("changed") } } } The following result was obtained ContentView SubView1, 0x000000016d9cd1a8, 0x000000016d9cd170, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView2, 0x000000016d9cd260, 0x000000016d9cd230, SubView2(data: "a") SubView1, 0x000000016d9cd1a8, 0x000000016d9cd170, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) changed ContentView SubView1, 0x000000016d9d1548, 0x000000016d9d1510, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) SubView2, 0x000000016d9d1600, 0x000000016d9d15d0, SubView2(data: "b") SubView1, 0x000000016d9d1548, 0x000000016d9d1510, SubView1(_data: SwiftUI.State<Swift.String>(_value: "a", _location: Optional(SwiftUI.StoredLocation<Swift.String>))) It seems that the two SubView1 are the same object?
2
0
80
4d
TextKit2 to PDF WITHOUT Font embedding
I can render text from TextKit2 into a PDF everything is fine. But in this case the font is embedded into the PDF. I need the Pdf to contains only the paths / glyphs and not font. I can't find a solution yet. I don't want to create an image or using UIViews etc. It would be nice to get the bezier path of the text I have done this with TextKit1 but the glyphs are gone with TextKit2 Can anyone help me ? Thanks :)
0
0
50
4d
Disabling screenshot and screen recording capabilities on users' devices
Hello, We represent an AI-powered content monetization platform. Recently, we encountered challenges during the approval process for our app on the Apple platform. Specifically, our efforts to disable screenshot and screen recording features within the app were unsuccessful. Consequently, sensitive content uploaded by content creators on our platform has been vulnerable to unauthorized distribution by users, negatively impacting our business model. We've observed that platforms like WhatsApp have successfully implemented features to prevent screenshots in view-once messages, prompting us to seek guidance on potential solutions or best practices to safeguard content creators' copyrights by disabling screenshot and screen recording capabilities on users' devices. We appreciate any insights or recommendations you can provide to address this issue effectively. Thank you for your attention to this matter. We eagerly await your response.
0
0
55
4d
uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar.
Hey,bros: I meet this crash,but I can't find any useful infos to fix this crash.And this crash only happens on iOS17. Here are the crash infos: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Layout requested for visible navigation bar, <UINavigationBar: 0x106128820; frame = (0 0; 430 44); opaque = NO; autoresize = W; tintColor = UIExtendedGrayColorSpace. Here are the stacks: Thread 0 name: com.apple.main-thread CoreFoundation ___exceptionPreprocess (in CoreFoundation) libobjc.A.dylib _objc_exception_throw (in libobjc.A.dylib) Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] (in Foundation) UIKitCore -[UINavigationBar layoutSubviews] (in UIKitCore) UIKitCore -[UIView(CALayerDelegate) layoutSublayersOfLayer:] (in UIKitCore) longbridge-ios-app -[UIView(Thread) ex_layoutSublayersOfLayer:] (in longbridge-ios-app:UIView+Thread.m:36) UIKitCore -[UINavigationBar layoutSublayersOfLayer:] (in UIKitCore) QuartzCore CA::Layer::layout_if_needed(CA::Transaction*) (in QuartzCore) UIKitCore -[UIView(Hierarchy) layoutBelowIfNeeded] (in UIKitCore) UIKitCore -[UINavigationController _positionNavigationBarHidden:edge:initialOffset:] (in UIKitCore) UIKitCore -[UINavigationController _positionNavigationBarHidden:edge:] (in UIKitCore) UIKitCore -[UINavigationController _updateBarsForCurrentInterfaceOrientationAndForceBarLayout:] (in UIKitCore) UIKitCore -[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] (in UIKitCore) UIKitCore -[UINavigationController viewDidMoveToWindow:shouldAppearOrDisappear:] (in UIKitCore) UIKitCore -[UIView(Internal) _didMoveFromWindow:toWindow:] (in UIKitCore) UIKitCore ___45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke (in UIKitCore) CoreAutoLayout -[NSISEngine withBehaviors:performModifications:] (in CoreAutoLayout) UIKitCore -[UIView _postMovedFromSuperview:] (in UIKitCore) UIKitCore -[UIView(Internal) _addSubview:positioned:relativeTo:] (in UIKitCore) UIKitCore -[UITransitionView transition:fromView:toView:removeFromView:] (in UIKitCore) UIKitCore -[UIViewControllerBuiltinTransitionViewAnimator animateTransition:] (in UIKitCore) UIKitCore ____UIViewControllerTransitioningRunCustomTransition_block_invoke_3 (in UIKitCore) UIKitCore +[UIKeyboardSceneDelegate _pinInputViewsForKeyboardSceneDelegate:onBehalfOfResponder:duringBlock:] (in UIKitCore) UIKitCore ____UIViewControllerTransitioningRunCustomTransition_block_invoke_2 (in UIKitCore) UIKitCore +[UIView(Animation) _setAlongsideAnimations:toRunByEndOfBlock:] (in UIKitCore) UIKitCore __UIViewControllerTransitioningRunCustomTransition (in UIKitCore) UIKitCore ___56-[UIPresentationController runTransitionForCurrentState]_block_invoke_3 (in UIKitCore) UIKitCore -[_UIAfterCACommitBlock run] (in UIKitCore) UIKitCore -[_UIAfterCACommitQueue flush] (in UIKitCore) UIKitCore __runAfterCACommitDeferredBlocks (in UIKitCore) UIKitCore __cleanUpAfterCAFlushAndRunDeferredBlocks (in UIKitCore) UIKitCore __UIApplicationFlushCATransaction (in UIKitCore) UIKitCore __UIUpdateSequenceRun (in UIKitCore) UIKitCore _schedulerStepScheduledMainSection (in UIKitCore) UIKitCore _runloopSourceCallback (in UIKitCore) CoreFoundation _CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION (in CoreFoundation) CoreFoundation ___CFRunLoopDoSource0 (in CoreFoundation) CoreFoundation ___CFRunLoopDoSources0 (in CoreFoundation) CoreFoundation ___CFRunLoopRun (in CoreFoundation) CoreFoundation _CFRunLoopRunSpecific (in CoreFoundation) GraphicsServices _GSEventRunModal (in GraphicsServices) UIKitCore -[UIApplication _run] (in UIKitCore) UIKitCore _UIApplicationMain (in UIKitCore) longbridge-ios-app main (in longbridge-ios-app:main.m:22) dyld start (in dyld)
0
0
43
4d
SwiftUI "scaleEffect(..)" commentary
I've a SwiftUI-based app that draws into a Canvas for a complicated, dynamic rendering. Since that rendering is based on a map of the world, I transform the provided context to (±180°×±90°) longitude / latitude coordinates before stroking paths etc. Note that the necessary scaling flips the Y-axis because latitude increases up the screen. All is well until I add words to the picture. Because of the inversion of the Y-axis, the text is rendered inverted. mercatorContext.draw(Text(satellite.commonName) .font(Font(.init(.userFixedPitch, size: 4.0))) .foregroundColor(.white), at: satPoint) My solution was to draw the text via a another (un-inverted) context which corrects the words, but requires the satPoint to be flipped to place the words at the right place on the (inverted) map .. With that preamble, someone suggested I apply scaleEffect(y: -1) to the Text and avoid messing with more than one GraphicsContext. This seemed an excellent solution but it doesn't work .. context.draw(Text(.. draws a Text view but applying scaleEffect turns it into a View which context.draw can't accept. Once it's a View, I suppose I could convert it to an Image and context.draw(Image(.. instead which seems messy. I wondered about the scaleEffect function .. is it the case that it would ever actually return a view type that was different from the type it was given? Leaving my curiosity aside, what would a better way than using a second context to keep my text upright?
0
0
74
4d