Explore the art and science of app design. Discuss user interface (UI) design principles, user experience (UX) best practices, and share design resources and inspiration.

All subtopics
Posts under Design topic

Post

Replies

Boosts

Views

Activity

Issues with UserDefault boolean
Hi, I have a view that should do the following: Set up and confirm a passcode upon account creation. Verify passcode if signing in. Reset passcode if prompted. With the code below, functions 1 and 2 are working. However, I'm having an issue with function 3. I am able to declare the reset UserDefault on a previous view so that the proper logic occurs, which is to read in the input, and then confirm it. However, it is not working as intended. In this code here: else if reset { UserDefaults.standard.set(passcode, forKey: "new-passcode") UserDefaults.standard.set(false, forKey: "reset-passcode") passcode = "" } I store the new passcode, set reset to false, and clear the passcode so it can be entered again to confirm. The code does not run as intended however. The title does not change and I'm unsure if it is actually storing the passcode. And, when re-entering, it does not change the view as it should by setting view = .someView. I'm assuming there is just flaw in my logic but I'm not sure how to resolve this. Below is the full code. Please let me know if any further clarification is needed. struct EnterPasscode: View { @State var title = "" @State var passcode = "" @State var message = "" @State var buttonState = false @Binding var view: Views var body: some View { Group { Spacer() .frame(height: 50) Text(title) .font(.system(size: 36)) .multilineTextAlignment(.center) .frame(height: 50) Spacer() if passcode != "" { Text("\(passcode)") .font(.system(size: 24)) .frame(height: 25) } else { Spacer() .frame(height: 25) } Spacer() .frame(height: 50) PasscodeKeypad(passcode: $passcode) Spacer() if message != "" { Text(message) .frame(height: 25) .foregroundStyle(Color.red) } else { Spacer() .frame(height: 25) } Spacer() WideButton(text: "Continue", buttonFunction: .functional, openView: .enterPasscode, view: .constant(.enterPasscode), buttonState: $buttonState) .onChange(of: buttonState) { oldState, newState in if buttonState { let passcodeSet = UserDefaults.standard.bool(forKey: "passcode-set") let storedPasscode = UserDefaults.standard.string(forKey: "passcode") let reset = UserDefaults.standard.bool(forKey: "passcode-reset") let newPasscode = UserDefaults.standard.string(forKey: "new-passcode") print(reset) if passcode.count == 4 { if storedPasscode == nil { if newPasscode == nil { UserDefaults.standard.set(passcode, forKey: "new-passcode") passcode = "" } else if passcode == newPasscode { UserDefaults.standard.set(passcode, forKey: "passcode") UserDefaults.standard.set(true, forKey: "passcode-set") view = .someView } } else if reset { UserDefaults.standard.set(passcode, forKey: "new-passcode") UserDefaults.standard.set(false, forKey: "reset-passcode") passcode = "" } else if newPasscode != nil { if passcode == newPasscode { UserDefaults.standard.set(passcode, forKey: "passcode") view = .someView } } } checkPasscodeStatus() buttonState = false } } Spacer() if !UserDefaults.standard.bool(forKey: "passcode-reset") && UserDefaults.standard.bool(forKey: "passcode-set") { Button(action: { view = .verifyPhone }) { Text("Forgot passcode?") .foregroundStyle(.black) } } Spacer() .frame(height: 25) } .onAppear() { checkPasscodeStatus() } .frame(width: UIScreen.main.bounds.width - 50) } func checkPasscodeStatus() { let passcodeSet = UserDefaults.standard.bool(forKey: "passcode-set") let storedPasscode = UserDefaults.standard.string(forKey: "passcode") let reset = UserDefaults.standard.bool(forKey: "passcode-reset") if reset { title = "Enter new passcode" } else if passcodeSet { title = "Enter Passcode" } else if storedPasscode != nil && storedPasscode != "" { title = "Confirm Passcode" } else { title = "Select a 4 Digit Passcode" } } } struct WideButton: View { @State var text: String @State var buttonFunction: ButtonType @State var openView: Views? @Binding var view: Views @Binding var buttonState: Bool var body: some View { Button(action: { buttonPressed() }, label: { ZStack { RoundedRectangle(cornerRadius: 5) .fill(Color.black) .frame(width: UIScreen.main.bounds.width - 50, height: 50) Text(text) .foregroundColor(.white) } }) } func buttonPressed() { switch buttonFunction { case .openView: view = openView! case .functional: buttonState = true } } } enum ButtonType { case openView case functional }
Topic: Design SubTopic: General Tags:
3
0
729
Nov ’24
Novice SwiftUI developer can't make network call
I'm trying to use URL structure in the foundation framework and it is failing to build, returning a nil value. Could it be trying to evaluate the string I am giving it as a variable for its argument at build time? Is there a test argument I can give URL to see if it can return a non-nil value? (of URL type)?
Topic: Design SubTopic: General
17
0
1.5k
2w
How to attribute/credit Apple Fonts added to app?
My app lets users create things with text, and I've included Apple fonts so users can format their text with them. These were fonts I found in the Font Book app that comes with macOS. My assumption is that these, like the San Francisco font, can be distributed with apps. Do I need to attribute these fonts to their creators and publish a license in my "About" page? If so, where do I find the license(s) and what is the proper way of publishing them? Is there anything else I should know? Please let me know if this should've been posted under a different topic and tag
Topic: Design SubTopic: General Tags:
3
0
1.1k
Jan ’25
iOS App to connect to classic bluetooth devices
Hi, I am developing an application using Flutter to connect to a Bluetooth Classic device (device is also developed by me), as Flutter is multi-platform I have tested this functionality in Android devices and it works fine, but when I want to develop the functionality of scanning BT devices, connect and send commands it is not possible due to I haven't found classic BT libraries to make this actions for iOS, do you know any library? There is any reason why isn't it possible?
3
0
1k
Nov ’24
Wrong unit in HIG > Components > System Experiences > Widget > watchOS widget dimensions
Hello, I noticed a small mistake in the Human Interface Guidelines (HIG). On the page HIG > Components > System Experiences > Widget > watchOS Widget Dimensions, scroll down to the bottom. In the "watchOS widget dimensions" section, the sizes in the table are in pixels (px), not points (pt) actually. However, the table header indicates the sizes should be in points (pt). Page link: https://developer.apple.com/design/human-interface-guidelines/widgets#watchOS-widget-dimensions For example, the widget size in the Smart Stack on a 49mm watch should be 192x81.5 pt (or 382x163 px), not 382x163 pt. This size can be verified with the information provided here: https://developer.apple.com/documentation/watchos-apps/supporting-multiple-watch-sizes/. https://developer.apple.com/documentation/watchkit/wkinterfacedevice/1620974-screenscale
Topic: Design SubTopic: General Tags:
3
0
809
Jan ’25
Meetings color in calendar
Hi, starting from iOS18, it is impossible to differentiate between completed meetings and future meetings in calendar - almost the same color (unless I switch to dark mode). Is there a way to fix it or is it a human engineering bug?
Topic: Design SubTopic: General Tags:
2
0
494
Oct ’24
iOS 18 Recommended Tweak
Prior to iOS 18 I could interact with my touchscreen when my phone was in standby mode. This was perfect because I could check weather, time, date, pause and play music, change songs, all at my desk, all without picking up my phone from the wireless charger. This feature is now gone in iOS 18 and I would REALLY like it back. It was super useful all day at work and now I’m constantly fumbling with my phone for every little thing.
Topic: Design SubTopic: General Tags:
1
0
611
Oct ’24
Email icons
The most recent update included coloured icons for grouping of emails anybody previously needing to group emails we’re able to achieve this alphabetically by simply searching for what you were looking for. These icons clutter the page with totally unnecessary screen pollution. if you want to persist with this folly can you please provide a classic display option for those of us who have happily survived using email for 30 years without this fluff.
Topic: Design SubTopic: General Tags:
2
0
596
Feb ’25
Feature Request: Dual Apple Pencil Pro Use or Charging Dock Support
Hi everyone 👋 I’ve been using the Apple Pencil Pro with my iPad Pro M4 and absolutely love it — the squeeze gesture, rotation, and haptics are amazing for creative work. But I’ve run into a little roadblock… Right now, only one Pencil Pro can be paired at a time. So while one is charging, you can’t use another as a backup without unpairing and re-pairing, which interrupts the workflow. I’d really love to see one of two things: The ability to use one Pencil while another charges or An official external charger (or support for third-party ones) Personally, I’d happily buy both a second Pencil and a charger if this became possible. I’ve even chatted with other creatives who feel the same — it would make a huge difference for long projects or working on the go. Just wanted to share this idea and see if anyone else here would like this too. Thanks for reading!
1
0
383
Jul ’25
MusicKit design guidelines
Hi community, I have a question regarding MusicKit, is it necessary to follow a design guideline to integrate this framework into my App? Also, when no music is reproducing in MusicKit which placeholder we should show, do you provide the resource? Or can we create our own placeholder? Thanks for all, David.
1
0
595
Feb ’25
Core database relationship are only partially updating.
I created a data structure based on a dictionary of words. The purpose is to link each word to all other words made up of the same letters plus one. Example: table -> ablate, cablet, tabled, gablet, albeit, albite, etc. For this I built a data model made of three entities: Word, Draw, Link. A Draw is a set of letters corresponding to a Word and sorted in alphabetic order, like : HOUSE -> EHOSU. A Link is a letter that you add to a Draw to get another Draw. So my data model looks like this: And here is how I implemented it in Xcode: Entity Word (let's forget the attribute optComp that plays no role here) Entity Draw Entity Link I am populating the data in two steps: first I read a list of words from a .txt source and I populate the Word entity and at the same time the Draw entity with the corresponding relationship (function loadDic()) This first step apparently works fine. I can easily find all anagrams of any word with something like word.sort.word.spelling I read through the Draw entity. For each draw I seek all existing +1 draws considering each letter of the alphabet. If there are, I create a Link and add the relationships (function createLinks()) Here is where something goes wrong. If the Link's and the relationship Draw.plus seem to be correctly created, the other relationship Link.gives is only partially populated, say 50%. Moreover, I tried to apply an additional routine (updateLinks()) , focusing only on Link's with an empty Link.gives relationship and updating them. But again, only 50% of the nil relationships appear to be populated. I could not find out why those relationships are not properly populated. If someone can help me out I would be grateful. Here is the code: LoadDic() function (OK) : func loadDic() { print("Loading dictionary...") dataAlreadyLoaded.toggle() guard let url = Bundle.main.url(forResource: INPUT_FILE, withExtension: "txt") else { fatalError("\(INPUT_FILE).txt not found") } if let dico = try? String(contentsOf: url, encoding: String.Encoding.utf8 ) { let lines = dico.split(separator: "\r\n") for line in lines { let lineArray = line.split(separator: " ") print("\(lineArray[0])") // word let wordSorted = String(lineArray[0].sorted()) let draw = getDraw(drawLetters: wordSorted) ?? addDraw(drawLetters: wordSorted) // look if draw already exists, otherwise create new one. let wordItem = Word(context: viewContext) // create word entry with to-one-relationship to draw wordItem.spelling = String(lineArray[0]) wordItem.optComp = (Int(String(lineArray[1])) == 1) wordItem.sort = draw do { try viewContext.save() } catch { print("Errort saving ods9: \(error)") } } } print("Ods Chargé") } func addDraw(drawLetters: String) -> Draw { let newDraw = Draw(context: viewContext) newDraw.draw = drawLetters return(newDraw) } func getDraw(drawLetters: String) -> Draw? { let request: NSFetchRequest<Draw> = Draw.fetchRequest() request.entity = Draw.entity() request.predicate = NSPredicate(format: "draw == %@", drawLetters) do { let drw = try viewContext.fetch(request) return drw.isEmpty ? nil : drw[0] } catch { print("Erreur recherche Tirage") return nil } } createLinks() function (NOK): func createLinks() { var erreur = " fetch request <Draw>" let request: NSFetchRequest<Draw> = Draw.fetchRequest() request.entity = Draw.entity() request.predicate = NSPredicate(value: true) print("Building relationships...") do { let draws = try viewContext.fetch(request) count = draws.count for draw in draws { print("\(count) - \(draw.draw!)") linkTable.removeAll() for letter in ALPHABET { print(letter) let drawLettersPlus = String((draw.draw! + String(letter)).sorted()) // draw with one more letter if let drawPlus = draws.first(where: { $0.draw == drawLettersPlus }) { // look for Draw entity that matches augmented draw let linkItem = Link(context: viewContext) // if found, create new link based on letter with relationship to augmented draw linkItem.letter = String(letter) linkItem.gives = drawPlus erreur = " saving \(draw.draw!) + \(letter)" try viewContext.save() linkTable.append(linkItem) // saves link to populate the one-to-many relationship of the initial draw, once the alphabet is through } } let drawUpdate = draw as NSManagedObject // populate the one-to-many relationship of the initial draw let linkSet = Set(linkTable) as NSSet drawUpdate.setValue(linkSet, forKey: "plus") erreur = " saving \(draw.draw!) links plus" try viewContext.save() count -= 1 // next draw } } catch { print("Error " + erreur) } print("Graph completed") } updateLinks function (NOK): func updateLinks() { var erreur = "fetch request <Link>" let request: NSFetchRequest<Link> = Link.fetchRequest() request.entity = Link.entity() print("Running patch...") do { request.predicate = NSPredicate(format: "gives == nil") let links = try viewContext.fetch(request) for link in links { let baseDraw = link.back!.draw! print("\(baseDraw) \(link.letter!)") let augmDrawLetters = String((baseDraw + link.letter!).sorted()) if let augmDraw = getDraw(drawLetters: augmDrawLetters) { viewContext.perform { let updateLink = link as NSManagedObject updateLink.setValue(augmDraw, forKey: "gives") erreur = " saving \(augmDraw.draw!) \(link.letter!)" do { try viewContext.save() } catch { print("Erreur mise à jour lien") } } } } } catch { print("Error " + erreur) } } RESULT And this is the output showing the content of the Draw entity with relationships after createLinks() is applied: And here after updateLinks() is applied :
2
0
955
Feb ’25
Huge UI difference between Simulator and Real Device
Hi everyone, I’m testing our SwiftUI app on both Xcode simulator and a real iPhone. On the simulator, everything looks clean and aligned. But when I run it on an actual iPhone (same build, iOS 18), the layout looks broken—fonts overlap, spacing is off, and elements are misaligned. Both screenshots are from the exact same screen and time. First is simulator, second is iPhone. Any idea why this difference happens? Is there something I should check in terms of rendering or layout settings? Thanks in advance!
1
0
247
Jul ’25
NavigationStack Fatal error: ‘try!
I am struggling to get pickers work in a form. I add NavigationStack and get this error Fatal error: 'try!' expression unexpectedly raised an error: SwiftUI.AnyNavigationPath.Error.comparisonTypeMismatch I have tried most every format or picker setup as well as DatePicker and can’t seem to determine how to get the selected item in a picker list saved. running: Xcode 16.1 import SwiftUI import SwiftData struct RoundsEditView: View { @Bindable var roundsdata: RoundsData @Environment(.modelContext) private var modelContext // @Environment(.dismiss) var dismiss @State private var playDate = Date.now @State private var selectedTee = "Gold" let tees = ["Black", "Blue", "White", "Gold", "Red", "Silver"] @Query(sort: \PlayerData.playerHandle) private var players: [PlayerData] @State private var selectedHandle: PlayerData? = nil var body: some View { NavigationStack { Form { HStack { Text("Course:") TextField("Course Name", text: $roundsdata.roundscourseName) .textContentType(.name) } HStack { // DatePicker("Date:", selection: $playDate, in: ...Date(), DatePicker("Date:", selection: $playDate, displayedComponents: [.date]) // DatePicker("Date:", selection: $playDate, in: ...Date(), // displayedComponents: .date).onChange(of: playDate) { oldState, newState in model.youDidChangeMethod(from: oldState, to: newState) } Section { Picker("Handle:", selection: $selectedHandle) { Text("Select a Handle").tag(nil as PlayerData?) ForEach(players, id: \.self) { player in HStack { Text(player.playerHandle) .frame(maxWidth: .infinity, alignment: .leading) .tag(player as PlayerData?) } .frame(maxWidth: .infinity, alignment: .leading) .tag(player as PlayerData?) } } // .pickerStyle(.inline) this does not fix issue or design wise work } // HStack { // Text("Tee:") // TextField("Tee", text: $roundsdata.roundsTee) // .textContentType(.name) // } HStack { Picker("Tee:", selection: $selectedTee) { ForEach(tees, id: \.self) { Text($0) } } } HStack { Text("Handicap:") TextField("Handicap", value: $roundsdata.roundsHandicap, format: .number) .textContentType(.name) } HStack { Text("Gross:") TextField("Gross", value: $roundsdata.roundsGross, format: .number) } HStack { Text("Net:") TextField("Net", value: $roundsdata.roundsNet, format: .number) .textContentType(.name) } HStack { Text("Rating:") TextField("Rating", value: $roundsdata.roundsRating, format: .number) .textContentType(.name) } HStack { Text("Slope:") TextField("Slope", value: $roundsdata.roundsSlope, format: .number) .textContentType(.name) } } .navigationTitle("Edit Rounds") } } }
Topic: Design SubTopic: General
10
0
1.2k
Nov ’24
ios 18
i accidentally updated my iphone with the ios 18 and i dislike it. the emoji display were too huge and the picture gallery was kinda messy. i hope apple could fix this by bringing back the old emoji display and the gallery settings.
Topic: Design SubTopic: General
1
0
453
Feb ’25
Apple Intelligence and Siri
I downloaded iOS 26 beta 3. I was very happy with how it turned out, but when I activated Siri, I noticed the rainbow pulsing glow that bordered the phone was missing, and all that was left was the original Siri bubble. I was very disappointed, does anyone know how to get this back? I loved that design feature.
1
0
318
Jul ’25