I have a bottom bar with buttons in it. I'm having trouble adding badges to the buttons and tried using the native .badges modifier but had no effect.
This is what I'm trying:
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Test")
}
.padding()
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
ControlGroup {
Button(action: {}) {
Label("Button 1", systemImage: "doc")
.badge(1)
}
Button(action: {}) {
Label("Button 2", systemImage: "checkmark")
}
.badge(2)
Button(action: {}) {
Label("Button 3", systemImage: "person")
}
}
}
}
}
}
}
This is what it looks like:
Is there a way to achieve this in SwiftUI?
Documentation of badge modifier states "Badges are only displayed in list rows and iOS tab bars" . Toolbar is not a Tabbar.
A possible approach is to do that in custom way (because toolbar accepts just a view), so it could be like
Tested with Xcode 13.4 / iOS 15.5
ControlGroup {
Button(action: {}) {
Label("Button 1", systemImage: "doc")
}
Button(action: {}) {
Label("Button 2", systemImage: "checkmark")
}
Button(action: {}) {
Label("Button 3", systemImage: "person")
}
}
.overlay(HStack(alignment: .top) { // << here !!
Image(systemName: "1").foregroundColor(.green)
.frame(maxWidth: .infinity)
Image(systemName: "3").foregroundColor(.orange)
.frame(maxWidth: .infinity)
Image(systemName: "9").foregroundColor(.purple)
.frame(maxWidth: .infinity)
}
.frame(maxHeight: .infinity)
.symbolVariant(.fill)
.symbolVariant(.circle)
.allowsHitTesting(false)
.offset(x: 10, y: -10)
// ^^^^ just for demo simplicity, can be somehow dynamic
)
Test code on GitHub
Related
I'm trying to figure out why the navigation title is not working with some devices, but I'm not able to figure out this issue. Can any one please help me to find out this issue, why the navigation title shows only the first 3 letters and after showing?
I have attached the Screenshot also please check.
iPhone 11 Device
iPhone 11 Simulator
Code:-
var body: some View {
ZStack {
Color.init(ColorConstantsName.MainThemeBgColour)
.ignoresSafeArea()
GeometryReader { geo in
ScrollView(.vertical) {
Text("Testing")
}
}
}
.navigationBarBackButtonHidden(true)
.navigationTitle(CommonAllString.BlankStr)
.navigationViewStyle(.stack)
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(leading:AnyView(leadingButton),trailing:AnyView(self.trailingButton))
.foregroundColor(Color.white)
}
var trailingButton: some View {
HStack {
Image(systemName: ImageConstantsNameForChatScreen.PersonImg)
.padding(.trailing)
Image(ImageConstantsName.DTRShareIconImg)
.resizable().frame(width: 20, height: 20)
}
}
Below Code Working:-
struct PSScreen: View {
var body: some View {
ZStack {
Color.init("Colour")
.ignoresSafeArea()
VStack{
Text("PSScreen")
}
}
.navigationBarBackButtonHidden(true)
.navigationBarTitle("", displayMode: .inline)
.navigationViewStyle(.stack)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
leadingButton.frame(width: 50, alignment: .leading)
}
ToolbarItem(placement: .navigationBarTrailing) {
trailingButton
}
}.foregroundColor(Color.white)
}
var leadingButton: some View {
HStack{
Text("Profile")
}
}
var trailingButton: some View {
HStack {
Image(systemName: "Person")
.padding(.trailing)
Image("Share")
.resizable().frame(width: 20, height: 20)
}
}
}
How can I influence the placement of a contextMenu in SwiftUI? I seem to be getting the exact opposite of what I want. What I want is the context menu to be aligned with the text as indicated in the arrows in the attached photos. The image contextMenus work perfect, but the text portion is where the challenge is. I have also tried changing the alignments, but no joy...
struct ContextMenuView: View {
var body: some View {
HStack {
ScrollView(.vertical, showsIndicators: false) {
HStack {
VStack() {
Text("Test").font(.footnote)
Text("Test").lineLimit(30)
}
.frame(minWidth: 0, maxWidth: .infinity, alignment: .trailing)
.padding()
.background(Color.blue)
.cornerRadius(10)
.contentShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
.contextMenu() {
Button {
print("Delete")
} label: {
Label("Delete this message", systemImage: "trash")
}
}
Image(systemName: "person.fill")
.contextMenu() {
Button {
print("Send")
} label: {
Label("Send private message", systemImage: "mail")
}
}
}.padding()
HStack {
Image(systemName: "person.fill")
.contextMenu() {
Button {
print("Send")
} label: {
Label("Send private message", systemImage: "mail")
}
}
VStack() {
Text("Test").font(.footnote)
Text("Test").lineLimit(30)
}
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.padding()
.background(Color.blue)
.cornerRadius(10)
.contentShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
.contextMenu() {
Button {
print("Delete")
} label: {
Label("Delete this message", systemImage: "trash")
}
}
}.padding()
}
}
}
}
I'm trying to make an iOS app that uses SwiftUI's NavigationView to build a side menu.
On iPhone it works perfectly, but on iPad I cannot get Rid of the Sidebar button and the back button text and icon. I would like to replace those buttons with the three horizontal lines icon named line.horizontal.3
Landscape screenshot with side menu icon I'd like to replace with three lines icon
Portrait screenshot with back button (woth icon and text) I'd like to replace with three lines icon
The code I'm using is the following:
import SwiftUI
struct ContentView_iPad: View {
#State var showMenu: Bool = false
var body: some View {
NavigationView{
MenuView()
iPad_menu()
.navigationBarTitle("Side Menu", displayMode: .inline)
.navigationBarItems(leading:
(Button(action: {
withAnimation{
self.showMenu.toggle()
}
}){
Image(systemName: "line.horizontal.3").imageScale(.large)
}
))
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
The MainView:
import SwiftUI
struct iPad_menu: View {
var body: some View {
EmptyView()
.background(Color.black)
}
}
The MenuView:
import SwiftUI
struct MenuView: View {
var body: some View {
VStack(alignment: .leading) {
HStack {
Image(systemName: "person")
.foregroundColor(.gray)
.imageScale(.large)
Text("Profile")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 100)
HStack {
Image(systemName: "envelope")
.foregroundColor(.gray)
.imageScale(.large)
Text("Messages")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
HStack {
Image(systemName: "gear")
.foregroundColor(.gray)
.imageScale(.large)
Text("Settings")
.foregroundColor(.gray)
.font(.headline)
}
.padding(.top, 30)
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color(red: 32/255, green: 32/255, blue: 32/255))
.edgesIgnoringSafeArea(.all)
}
}
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.
public struct Frontside: View
{
#Binding public var kanatext: String
public var body: some View
{
ZStack{
RoundedRectangle(cornerRadius: 25, style: .continuous)
.foregroundColor(Color.red)
.frame(width: 160, height: 160)
.zIndex(0)
Text(self.kanatext)
.font(.title)
.fontWeight(.black)
.padding(50)
.zIndex(1)
VStack {
Spacer()
HStack {
Button(action: {
print("button pressed")
}) {
Image(systemName: "xmark.circle")
.font(.title)
}
.mask(Circle())
.opacity(0.4)
Button(action: {
print("button pressed")
}) {
Image(systemName: "checkmark.circle")
.font(.title)
}
.mask(Circle())
.opacity(0.4)
}
}
.zIndex(2)
}
}
}
In the above code snippet, I have used a Zstack to layer different parts of a flash card, a background, the text, and then correct/incorrect buttons. The uppermost layer are the buttons, which appear correctly, but for some reason they are not actually pressable.
Have you tried using onTapGesture? It might have to do with the fact that you're using a ZStack.
Try something like:
Image(systemName: "checkmark.circle")
.font(.title)
.onTapGesture {
print("button pressed")
}
In this case there would be no needed to wrap the Image in a Button.
If this doesn't work add onTapGesture to your VStack and have it be empty.