Post

Replies

Boosts

Views

Activity

Reply to SwiftUI 4, IOS 16
I don't understand what the problem is here. You have a native SwiftUI TabView that has its own tab bar (which I think you want to hide), and then a custom tab bar that overlays the system one. It seems like the more tab, that appears when there are more than five tab items, is affecting you're custom tab bar approach. Is this correct? Also, why do you have a system tab bar if you're not going to use it? Just use an if or switch statement, without the TabView, to change between the tabbed views based on what the user has selected from the custom tab bar.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to SwiftUI 4, IOS 16
Thanks for clearing things up. I have found that the previously mentioned modifier should be applied to each view inside of the TabView for it to take effect, like this: TabView { Tab1() .toolbar(.hidden, for: .tabBar) Tab2() .toolbar(.hidden, for: .tabBar) Tab3() .toolbar(.hidden, for: .tabBar) ... } Hopefully that should work. However, I believe there is still the problem of the "More" tab that arises from the TabView's five tab limit. When selecting one of these tabs from the custom tab bar, the view is shown, unexpectedly to the user, in the "More" navigation stack, which isn't pleasant to use. I don't think there is a way to remove this feature, so there are probably only two solutions to this: Only have a maximum of five tabs, or Use the custom tab bar approach without the TabView.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to New ShareLink with custom type is not working
is there any way to deal with this optional? What error are you getting exactly? Is it a simple "Unexpectedly found nil while unwrapping an Optional value" sort of thing? You will need to check that the value in the url property is a genuine URL. You could provide a default URL, maybe this: URL(fileURLWithPath: "/dev/null") but it's up to you and how you manage that url property. ‎ ‎ I must associate destination to Recording.url In the importing closure you would need to return an instance of Recording, given the file URL (received.file). What the example it doing is copying the received file to a location in the user's file system and using that new URL to create a Video object. If you look at the Copy Code snippets for that session, you can see the contents of the Video.copyVideoFile method. So yes, the received/copied destination file URL needs to be assigned to the Recording.url property. ‎ ‎If there are additional issues, please create a new post as this one is about a different (solved?) problem. Don't forget to close this thread.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to Swiftui MacOS App Example Project OnDelete func
Update I have just created a new macOS project with Core Data enabled and run the program without modifying the template code. Even though the onDelete(perform:) modifier has been attached to the ForEach, the delete swipe action won't work as the List is in a sidebar-style state. If you change the list style to something different, like .inset, the swipe action will work. You could use the onDeleteCommand(perform:) modifier where you can delete the currently selected item in the List when the delete key is pressed. You could also add a contextMenu(menuItems:) modifier and add your own Button that deletes the selected item.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to SwiftUI: List selection of custom struct
Because you're using a List with selection enabled, the whole row will be selected/highlighted – that's the default behaviour. What do you mean by only the title text be selectable? Do you only want the title text to respond to taps, or do you only want the title text to be highlighted when selected?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to Sheet Presented From List Showing Incorrect Data
You need to move the sheet modifier outside of the ForEach, as it's currently creating a sheet for every item bound to the same isPresented variable. When you set isPresented to true, you are essentially showing each item's sheet, but you only see the last one. You can instead use the sheet(item:onDismiss:content:) modifier. Something like this will work: // the item parameter requires the data to be Identifiable // you can make a custom struct to hold this, or manually conform String to Identifiable struct Item: Identifiable { let id = UUID() let name: String } // you can remove the isPresented variable @State selectedItem: Item? var body: some View { ... ForEach(...) { item in Button { selectedItem = Item(name: item) } label: { ... } } // move outside loop so there is only one sheet that shows a view dependant on the selectedItem .sheet(item: $selectedItem) { item in CustomView(text: item) } ... }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to SwiftUI: How to animate List when being populated
It seems the problem lies with the if-else statement and the way SwiftUI handles view identity and layout. First of all, you need to be animating changes to the rooms property otherwise there will be no animated transition. Something like this can work, but there are other ways: withAnimation { rooms.append(newRoom) } As the List will not be shown when it has no items, you can use a single if statement for the loading text, and the transition which will work as expected. Here's how it would look: ZStack { if items.isEmpty { Text("Loading...") .transition(.slide) .zIndex(1) // place above the List (with ZStack) } List(selection: $selectedRoom) {     ...               } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to Custom Label doesn't work (MenuPickerStyle)
A Picker with the .menu picker style won't use the view specified in the label closure. It will generate its label based off of the currently selected item. This is the default behaviour. If you want a custom label, use a standard Menu and add your Picker inside of that. Note, you won't get the iOS 16 style double chevron indicator.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to How to display [Link]?
You can use it like this: Link("Click this link", destination: URL(string: "https://some.destination.url")!) The init(_:destination:) initialiser will convert the title string parameter to a Text object, hence getting you to your Link<Text> object. Check out the documentation for more.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to How to display [Link]?
What do you mean by "displaying" the links? (1) Is it showing them repeatedly in a row/column? (2) Or do you want the links to be interpolated in some standard text? I would recommend using an array of a custom type that can then each be converted into a Link view, instead of storing the actual view. Something like this: struct DisplayedLink { let title: String let url: URL } let links: [DisplayedLink] = [ ... ] Option 1: // any suitable layout container VStack { ForEach(links, id: \.self) { link in Link(link.title, destination: link.url) } } Option 2: var linksText: AttributedString { var str = AttributedString("text comprised of the links' titles") for link in links { if let range = str.range(of: link.title) { str[range].link = link.url } } return str } // the linked text is coloured and tappable Text(linksText)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to Setting background color of whole View in SwiftUI when using NavigationView
Your issue is not because of the NavigationView but the fact that you have a List. Up until iOS 16 there had been no direct SwiftUI way of changing the background colour of a List. You had to access the UITableView appearance proxy and "remove" the background colour that way. Now there is a dedicated modifier for this: scrollContentBackground(_:). Use either of these methods, dependant on the target version, to clear the default list background colour, and then set your own, like this: // iOS 15 and earlier init() { UITableView.appearance().backgroundColor = .clear } List { ... } // iOS 16 .scrollContentBackground(.hidden) // set background to any colour or gradient .background(.linearGradient(colors: [.green, .red], startPoint: .top, endPoint: .bottom))
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Sep ’22
Reply to SwiftUI 4, IOS 16
I don't understand what the problem is here. You have a native SwiftUI TabView that has its own tab bar (which I think you want to hide), and then a custom tab bar that overlays the system one. It seems like the more tab, that appears when there are more than five tab items, is affecting you're custom tab bar approach. Is this correct? Also, why do you have a system tab bar if you're not going to use it? Just use an if or switch statement, without the TabView, to change between the tabbed views based on what the user has selected from the custom tab bar.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to SwiftUI 4, IOS 16
Thanks for clearing things up. I have found that the previously mentioned modifier should be applied to each view inside of the TabView for it to take effect, like this: TabView { Tab1() .toolbar(.hidden, for: .tabBar) Tab2() .toolbar(.hidden, for: .tabBar) Tab3() .toolbar(.hidden, for: .tabBar) ... } Hopefully that should work. However, I believe there is still the problem of the "More" tab that arises from the TabView's five tab limit. When selecting one of these tabs from the custom tab bar, the view is shown, unexpectedly to the user, in the "More" navigation stack, which isn't pleasant to use. I don't think there is a way to remove this feature, so there are probably only two solutions to this: Only have a maximum of five tabs, or Use the custom tab bar approach without the TabView.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to View not update when published variable in class changes within the class
Where are you calling changeShow()? The code you provided should work fine. Can you show some more code which would reveal the problem. I tested with this code and tapping the "Text" showed and hid the "Bar" text. var body: some View { Text("Text") .onTapGesture { isText.changeShow() } if isText.show {        Text("Bar")     } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to New ShareLink with custom type is not working
You are using the ShareLink initialiser that accepts a String or URL as the item parameter. You instead need to use an initialiser with the preview parameter which accepts a Transferable object and requires a SharePreview.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to New ShareLink with custom type is not working
is there any way to deal with this optional? What error are you getting exactly? Is it a simple "Unexpectedly found nil while unwrapping an Optional value" sort of thing? You will need to check that the value in the url property is a genuine URL. You could provide a default URL, maybe this: URL(fileURLWithPath: "/dev/null") but it's up to you and how you manage that url property. ‎ ‎ I must associate destination to Recording.url In the importing closure you would need to return an instance of Recording, given the file URL (received.file). What the example it doing is copying the received file to a location in the user's file system and using that new URL to create a Video object. If you look at the Copy Code snippets for that session, you can see the contents of the Video.copyVideoFile method. So yes, the received/copied destination file URL needs to be assigned to the Recording.url property. ‎ ‎If there are additional issues, please create a new post as this one is about a different (solved?) problem. Don't forget to close this thread.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to Swiftui MacOS App Example Project OnDelete func
The onDelete(perform:) modifier should cause list rows to be deleted through a swipe action. Are you saying this isn't working?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to Swiftui MacOS App Example Project OnDelete func
Update I have just created a new macOS project with Core Data enabled and run the program without modifying the template code. Even though the onDelete(perform:) modifier has been attached to the ForEach, the delete swipe action won't work as the List is in a sidebar-style state. If you change the list style to something different, like .inset, the swipe action will work. You could use the onDeleteCommand(perform:) modifier where you can delete the currently selected item in the List when the delete key is pressed. You could also add a contextMenu(menuItems:) modifier and add your own Button that deletes the selected item.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to SwiftUI: List selection of custom struct
Because you're using a List with selection enabled, the whole row will be selected/highlighted – that's the default behaviour. What do you mean by only the title text be selectable? Do you only want the title text to respond to taps, or do you only want the title text to be highlighted when selected?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to Sheet Presented From List Showing Incorrect Data
You need to move the sheet modifier outside of the ForEach, as it's currently creating a sheet for every item bound to the same isPresented variable. When you set isPresented to true, you are essentially showing each item's sheet, but you only see the last one. You can instead use the sheet(item:onDismiss:content:) modifier. Something like this will work: // the item parameter requires the data to be Identifiable // you can make a custom struct to hold this, or manually conform String to Identifiable struct Item: Identifiable { let id = UUID() let name: String } // you can remove the isPresented variable @State selectedItem: Item? var body: some View { ... ForEach(...) { item in Button { selectedItem = Item(name: item) } label: { ... } } // move outside loop so there is only one sheet that shows a view dependant on the selectedItem .sheet(item: $selectedItem) { item in CustomView(text: item) } ... }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to SwiftUI: How to animate List when being populated
It seems the problem lies with the if-else statement and the way SwiftUI handles view identity and layout. First of all, you need to be animating changes to the rooms property otherwise there will be no animated transition. Something like this can work, but there are other ways: withAnimation { rooms.append(newRoom) } As the List will not be shown when it has no items, you can use a single if statement for the loading text, and the transition which will work as expected. Here's how it would look: ZStack { if items.isEmpty { Text("Loading...") .transition(.slide) .zIndex(1) // place above the List (with ZStack) } List(selection: $selectedRoom) {     ...               } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to Custom Label doesn't work (MenuPickerStyle)
A Picker with the .menu picker style won't use the view specified in the label closure. It will generate its label based off of the currently selected item. This is the default behaviour. If you want a custom label, use a standard Menu and add your Picker inside of that. Note, you won't get the iOS 16 style double chevron indicator.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to How to display [Link]?
You can use it like this: Link("Click this link", destination: URL(string: "https://some.destination.url")!) The init(_:destination:) initialiser will convert the title string parameter to a Text object, hence getting you to your Link<Text> object. Check out the documentation for more.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to How to display [Link]?
What do you mean by "displaying" the links? (1) Is it showing them repeatedly in a row/column? (2) Or do you want the links to be interpolated in some standard text? I would recommend using an array of a custom type that can then each be converted into a Link view, instead of storing the actual view. Something like this: struct DisplayedLink { let title: String let url: URL } let links: [DisplayedLink] = [ ... ] Option 1: // any suitable layout container VStack { ForEach(links, id: \.self) { link in Link(link.title, destination: link.url) } } Option 2: var linksText: AttributedString { var str = AttributedString("text comprised of the links' titles") for link in links { if let range = str.range(of: link.title) { str[range].link = link.url } } return str } // the linked text is coloured and tappable Text(linksText)
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to Setting background color of whole View in SwiftUI when using NavigationView
Your issue is not because of the NavigationView but the fact that you have a List. Up until iOS 16 there had been no direct SwiftUI way of changing the background colour of a List. You had to access the UITableView appearance proxy and "remove" the background colour that way. Now there is a dedicated modifier for this: scrollContentBackground(_:). Use either of these methods, dependant on the target version, to clear the default list background colour, and then set your own, like this: // iOS 15 and earlier init() { UITableView.appearance().backgroundColor = .clear } List { ... } // iOS 16 .scrollContentBackground(.hidden) // set background to any colour or gradient .background(.linearGradient(colors: [.green, .red], startPoint: .top, endPoint: .bottom))
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to How to use EnvironmentObject correctly
The first option is the recommended way of doing it. Create the ObservableObject class as an @StateObject property first, and only once Pass it into the environment, with environmentObject(_:) Access the class from subviews using @EnvironmentObject
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Sep ’22