why on my toggle star.fill changes to star.square.fill - swiftui

So I only want it to star, change to green but instead around it changes and itself remains white.
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Toggle(isOn: $favourites) {
Image(systemName: favourites ? "star.fill" : "star")
}
.tint(.green)
}
around of the star green only

Sounds like you don't want to use a Toggle, but just a regular button instead.
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
favourites.toggle()
} label: {
Image(systemName: favourites ? "star.fill" : "star")
.foregroundColor(.green)
}
}
}

The tint needs to placed on the Image and not the Toggle. Like so:
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Toggle(isOn: $favourites) {
Image(systemName: favourites ? "star.fill" : "star")
.tint(.green)
}
.tint(.white)
}

Related

Restructure NavigationLink to Button for LongPressGesture

I am trying to put an option for .onlongpressgesture for this list of groups. However, it doesn't seem to work and I figure, it will work on Button.
I have tried to apply ".onTapGesture" and ".onLongPressGesture", but there is no effect.
Is there a way I can transform the Code below from a NavigationLink to a Button with the same destination when tapped and an additional Menu (called "OptionsmenuView") when long pressed?
The NavigationLink:
VStack (spacing: 20){
ForEach(groups, id:\.self) { Group in
NavigationLink(destination: GroupView()) {
ZStack (alignment: .bottomLeading) {
Image(uiImage: (UIImage(data: Group.groupThumbnail ?? self.image) ?? UIImage(named: "defaultGroupThumbnail"))!)
.resizable(capInsets: EdgeInsets())
.aspectRatio(contentMode: .fill)
.frame(height: 200.0, alignment: .center)
.cornerRadius(22)
VStack (alignment: .leading) {
Text("\(Group.groupTitle ?? "Untitled")")
.font(.title)
.fontWeight(.heavy)
.multilineTextAlignment(.leading)
Text("Consists of 5 Flowers")
}
.padding([.leading, .bottom], 18.0)
.foregroundColor(.primary)
}
.listRowBackground(Color.black)
}
}
}
The OptionMenuView:
struct OptionsMenuView: View {
var body: some View {
Menu {
Button("Cancel", role: .destructive) {
// Do something
}
Button {
// Do something
} label: {
Label("Edit", systemImage: "square.and.pencil")
}
Button {
// Do something
} label: {
Label("Delete", systemImage: "trash")
}
} label: {
Label("Settings", systemImage: "gearshape.fill")
}
}
}
I appreciate any form of advice. Thanks in advance.
Couldn't you just use .contextMenu ?
NavigationView {
List (0..<10) { i in
NavigationLink {
Text("DestionationView")
} label: {
Text("Item \(i)")
}
.contextMenu { // << here
Button("Cancel", role: .destructive) {
// Do something
}
Button {
// Do something
} label: {
Label("Edit", systemImage: "square.and.pencil")
}
Button {
// Do something
} label: {
Label("Delete", systemImage: "trash")
}
}
}
}

SwiftUI: How to set foregroundColor on menu button

I would like to make a menu button red as it carries a destructive nature, but my implementation doesn't override the foreground color at all.
Code.
ToolbarItem(placement: .navigationBarTrailing) {
Menu {
Button(action: {}) {
Label("Delete", systemImage: "trash")
.foregroundColor(.red)
}
}
label: {
Text("Next")
}
}
Other attempts:
ToolbarItem(placement: .navigationBarTrailing) {
Menu {
Button(action: {}) {
Label("Delete", systemImage: "trash")
}
.foregroundColor(.red)
}
label: {
Text("Next")
}
}
Results
Noticed that the "Delete" button is not red.

Too much space left between items when using ToolbarItemGroup

When I use toolbar group in SwiftUI, there is too much space between elements. I put it with HStack in iOS 13, it is ok. But when I put it with toolbar in iOS 14, there is a problem. How can I fix this?
var muteUser: some View {
NavigationLink(destination: Text("dddd").environmentObject(CurrentUser)) {
Image(systemName: "speaker.slash")
.frame(width: 22, height: 22)
}
}
var friendSetting: some View {
NavigationLink(destination: FriendSettings().environmentObject(CurrentUser)) {
Image(systemName: "gear")
.frame(width: 22, height: 22)
}
}
var body: some View {
GeometryReader { geometry in
if #available(iOS 14.0, *) {
chatView
.toolbar {
ToolbarItem(placement: .principal) {
centerNavBar()
.frame(maxWidth: geometry.size.width*0.75)
}
ToolbarItemGroup(placement: .navigationBarTrailing) {
muteUser
friendSetting
}
}
} else {
chatView
.navigationBarItems(trailing:
HStack(){
centerNavBar()
Spacer()
rightNavBar
}
.frame(width: geometry.size.width*0.75)
)
}
}
}
It looks like this is the standard appearance of two buttons inside ToolbarItemGroup.
You can use a HStack instead:
.toolbar {
ToolbarItem(placement: .principal) {
Image(systemName: "star.fill")
}
ToolbarItem(placement: .navigationBarTrailing) {
HStack {
NavigationLink(destination: Text("dddd").environmentObject(CurrentUser)) {
Image(systemName: "speaker.slash")
.imageScale(.large)
}
NavigationLink(destination: FriendSettings().environmentObject(CurrentUser)) {
Image(systemName: "gear")
.imageScale(.large)
}
}
}
}
Try omitting the .frame(width: 22, height: 22) on the toolbar item Images. I think that’s causing the iOS 14 toolbar to create UIToolbarItems with embedded views instead of simple images.

How to add space in toolbar items (SwiftUI)

the Spacer() has no effect in the ToolbarItem, I want to let items spread out rather than clustering. Do you know how to solve this? Thank you.
This is the code.
struct ContentView: View {
var body: some View {
NavigationView {
VStack{
Image("searchbar")
Text("Test")
}
.toolbar {
ToolbarItem(placement: .principal) {
HStack {
Text("9scoretrain")
Spacer()
NavigationLink(
destination: Text("SearchView"),
label: {
Image("searchbar")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width:200)
})
Spacer()
NavigationLink(
destination: Text("CameraView"),
label: {
Image(systemName: "camera.viewfinder")
})
}
}
}
}
}
}
This is the current effect.
This is the effect I want in which items are evenly distributed.
This method might solve, but there is still some space between the centered item and the trailing item.
This is still not what I want, I want items are evenly distributed.
This is the effect.
This is the code.
struct ContentView: View {
var body: some View {
NavigationView {
VStack{
Image("searchbar")
Text("Test")
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Text("9scoretrain")
}
ToolbarItem(placement: .principal) {
NavigationLink(
destination: Text("SearchView"),
label: {
Image("searchbar")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width:200)
})
}
ToolbarItem(placement: .navigationBarTrailing) {
NavigationLink(
destination: Text("CameraView"),
label: {
Image(systemName: "camera.viewfinder")
})
}
}
}
}
}

Buttons inside ToolbarItem cannot dismiss sheet

In Xcode 12 Beta 6, dismissing a sheet doesn't work inside a button's action inside a ToolbarItem.
My sheet view looks like:
NavigationView {
Form {
Section {
TextField("Name", text: $name)
}
}
.navigationTitle("New Thing")
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(action: {
self.presentation.wrappedValue.dismiss()
}, label: {
Text("Cancel")
})
}
ToolbarItem(placement: .confirmationAction) {
Button(action: {
do {
// some saving logic
try managedObjectContext.save()
self.presentation.wrappedValue.dismiss()
} catch {
print("didn't save due to \(error.localizedDescription)")
}
}, label: {
Text("Save")
})
}
}
}
EDIT: here's how I constructed the sheet
var body: some View {
List {
ForEach(results) { result in
HStack {
NavigationLink(destination: SingleResultView(result: result)) {
SingleResultRowView(result: result)
}
}
}
.onDelete(perform: deleteResult)
}
.navigationTitle("All Results")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: {
self.isNewResultSheetPresented.toggle()
}, label: {
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
})
.sheet(isPresented: $isNewResultSheetPresented) {
NewResultView()
// ^ this contains the code above
.environment(\.managedObjectContext, self.managedObjectContext)
}
}
}
}
When the sheet is first presented, immediately a console log appears:
2020-09-13 20:52:02.333679-0700 MyApp[2710:89263]
[Presentation] Attempt to present <_TtGC7SwiftUI22SheetHostingControllerVS_7AnyView_: 0x1027b7890> on
<_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x10270d620>
(from <_TtGC7SwiftUIP10$194f39bd428DestinationHostingControllerVS_7AnyView_: 0x103605930>)
which is already presenting <_TtGC7SwiftUI22SheetHostingControllerVS_7AnyView_: 0x103606d60>.
I can dismiss the sheet only by swiping down.
For reference, I went back to an older commit where I used NavigationBarItems and it worked perfectly. But from what I understand, this is a situation where I'm supposed to be using ToolbarItem.
Does anybody know why the good old self.presentation.wrappedValue.dismiss() doesn't work here or why is the sheet being presented twice?
Move sheet out of toolbar, as
var body: some View {
List {
ForEach(results) { result in
HStack {
NavigationLink(destination: SingleResultView(result: result)) {
SingleResultRowView(result: result)
}
}
}
.onDelete(perform: deleteResult)
}
.navigationTitle("All Results")
.sheet(isPresented: $isNewResultSheetPresented) { // << here !!
NewResultView()
// ^ this contains the code above
.environment(\.managedObjectContext, self.managedObjectContext)
}
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: {
self.isNewResultSheetPresented.toggle()
}, label: {
Image(systemName: "plus.circle.fill")
.resizable()
.frame(width: 30, height: 30, alignment: .center)
})
}
}
}