Nested button not responding - swift

I have a navigationlink and a button side by side in a hstack, but neither are responding when tapped.
navigationbaritems button works as expected.
NavigationView {
ZStack {
"Buttons here works fine"
VStack{
HStack(alignment: .center) {
NavigationLink(destination: ProfileView()) {
Text("anonymous")
.font(.caption)
.fontWeight(.bold)
}
Spacer()
Button(action: { self.cardOptions.toggle() }) {
Image(systemName: "ellipsis")
.frame(width: 32, height: 32, alignment: .center)
.font(Font.title.weight(.black))
.foregroundColor(Color("costumLightGrey"))
}.alert(isPresented:$cardOptions) {
Alert(title: Text("Alert"), message: Text("Message"), primaryButton: .destructive(Text("Delete")) {
print("Did tap")
}, secondaryButton: .cancel())
}
}
}
}
}

Related

Location of buttons in SwiftUI

i'm making an app and i have a problem, my interface (buttons, image etc.) placed in the center of the screen. and i want to place them at the top. Here is the code
var body: some View {
VStack{
HStack{
Button {
} label: {
Image(systemName: "pencil")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 45, height: 45)
.clipShape(Circle())
}
.hLeading()
Button {
} label: {
Image(systemName: "calendar")
.font(.title2)
.foregroundColor(.white)
}
Button {
} label: {
Image(systemName: "bell")
.font(.title2)
.foregroundColor(.white)
}
}
.padding()
}
.vTop()
.hCenter()
.background(Color("BG"))
.preferredColorScheme(.dark)
}
Can anybody help me?
add Spacer() in your VStack
like this:
var body: some View {
VStack{
HStack{
Button {
} label: {
Image(systemName: "pencil")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 45, height: 45)
.clipShape(Circle())
}
.hLeading()
Button {
} label: {
Image(systemName: "calendar")
.font(.title2)
.foregroundColor(.white)
}
Button {
} label: {
Image(systemName: "bell")
.font(.title2)
.foregroundColor(.white)
}
}
.padding()
Spacer() // <- this
}
.vTop()
.hCenter()
.background(Color("BG"))
.preferredColorScheme(.dark)
}

Fit Image & Text in Frame SwiftUI

I have two problems with my code.
I want to fit my Image into the frame I created. The image format is not the same with that of the frame, I would rather have just part of the image there instead of white borders.
The title text I created with the blur background should fit into the bottom of the frame.
struct VisualEffectView: UIViewRepresentable {
var effect: UIVisualEffect?
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIVisualEffectView { UIVisualEffectView() }
func updateUIView(_ uiView: UIVisualEffectView, context: UIViewRepresentableContext<Self>) { uiView.effect = effect }
}
struct ContentView: View {
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
ZStack {
Image("Yosemite")
.resizable()
.scaledToFill()
.overlay(content: {
Text("Lorem ipsum dolor sit amet")
.font(.largeTitle)
.fontWeight(.bold)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.foregroundColor(.white)
.background(VisualEffectView(effect: UIBlurEffect(style: .systemMaterialDark)))
.frame(minWidth: 350, maxWidth: .infinity, minHeight: 250, maxHeight: .infinity, alignment: .bottom)
.scaledToFit()
})
}.padding()
.frame(width: 350, height: 400)
.background()
.clipShape(RoundedRectangle(cornerRadius: 30))
}
}
}
I don't know about your blur background, but the rest would work like this:
struct ContentView: View {
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
Image("image")
.resizable()
.scaledToFill()
.frame(width: 350, height: 400)
.cornerRadius(30)
.overlay {
Text("Lorem ipsum dolor sit amet")
.font(.largeTitle)
.fontWeight(.bold)
.multilineTextAlignment(.leading)
.foregroundColor(.white)
.padding(.horizontal, 8)
.background(.ultraThinMaterial)
.frame(maxHeight: .infinity, alignment: .bottom)
.padding()
}
}
}
}

How to Clear a Textfield with a Button (Swift UI)

I am trying out to implement a Mailview like I've seen in a tutorial before.
After solving the layout, I tried to get some features on it.
If I begin to write a new message, I want to clear the filled Textfield boxes, when the user clicks the trash bin. But however I don't find out how to clear it.
import SwiftUI
var inboundMails = [[String()]]
var outboundMails = [[String()]]
struct ContentView: View {
#State var showComposeMessageView: Bool = false
var body: some View {
TabView
{
NavigationView
{
List (0 ..< 6)
{
_ in
NavigationLink(destination: Text("Nachrichtentext"))
{
SingleMessageView()
}
}
.listStyle(GroupedListStyle())
.navigationTitle("Inbox")
.navigationBarItems(trailing:
Button(action: { showComposeMessageView.toggle() }, label: {
Image(systemName: "square.and.pencil")
})
)
}
// Verfassen Button
.sheet(isPresented: $showComposeMessageView, content:
{
NewMessage()
}) //.sheet
.tabItem {
Image(systemName: "envelope.fill")
Text("Inbox")
}
Text("Sent")
.tabItem {
Text("Sent")
Image(systemName: "paperplane.fill")
}
}
}
}
// Design eines einzelnen Nachrichtenblocks
struct SingleMessageView: View {
var body: some View {
HStack
{
Image(systemName: "person.circle.fill")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
.foregroundColor(.gray)
VStack(alignment: .leading)
{
HStack
{
Text("Absender")
.font(.headline)
Spacer()
Text("01-07-2020")
.font(.subheadline.monospacedDigit())
.foregroundColor(.secondary)
}
Text("Betreff")
.font(.subheadline)
.lineLimit(2)
}
}
}
}
//Neue Nachricht verfassen
struct NewMessage: View {
#State var messageText = ""
#State var betreff = ""
#State var cc = ""
#State var empfaenger = ""
#State var sendButton: Bool = false
var body: some View {
ZStack
{
Color.white
Spacer()
VStack(alignment: .leading)
{
// Kopfzeile
HStack(alignment: .top)
{
Spacer()
Image(systemName: "paperplane.circle")
.resizable()
.frame(width: 70, height: 70, alignment: .leading)
VStack(alignment: .leading)
{
Text("Empfänger: ")
Spacer()
Text("Betreff: ")
Spacer()
Text("CC:")
}.frame(height: 70)
VStack
{
TextField("Empfänger", text: $empfaenger).lineLimit(2)
.font(.subheadline)
Spacer()
TextField("Betreff", text: $betreff).lineLimit(2)
.font(.subheadline)
Spacer()
TextField("CC", text: $cc)
.font(.subheadline)
}.frame(height: 70)
}
.foregroundColor(.black)
.background(Color.white)
.font(.headline)
// Knöpfe
HStack
{
Spacer()
// Senden
Button(
action: { sendButton.toggle()
outboundMails = Mails().MailManager(inbound: false, from_to: empfaenger, cc: cc, subject: betreff, message: messageText, mailarray: outboundMails)},
label: {Image(systemName: "paperplane")})
.frame(width: 20, height: 20, alignment: .leading)
Spacer()
// Farbe bearbeiten
Button(
action: { sendButton.toggle() },
label: {Image(systemName: "pencil")})
.frame(width: 20, height: 20, alignment: .leading)
Spacer()
// Anlage hinzufügen
Button(
action: { sendButton.toggle() },
label: {Image(systemName: "doc")})
.frame(width: 20, height: 20, alignment: .leading)
Spacer()
// Verwerfen
Button(
action: { sendButton.toggle()
messageText = ""
cc = ""
betreff = ""
empfaenger = ""
},
label: {Image(systemName: "trash")})
.frame(width: 20, height: 20, alignment: .leading)
Spacer()
}.frame(height: 30, alignment: .top)
// NachichtentextFeld
TextEditor(text: $messageText)
.frame(width: 411, height: 400, alignment: .top)
.border(Color.gray)
Spacer()
}
}
}
}
// Design eines einzelnen Nachrichtenblocks
struct SendMessageView: View {
var body: some View {
HStack
{
Image(systemName: "person.circle.fill")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
.foregroundColor(.gray)
VStack(alignment: .leading)
{
HStack
{
Text("Absender")
.font(.headline)
Spacer()
Text("01-07-2020")
.font(.subheadline.monospacedDigit())
.foregroundColor(.secondary)
}
Text("Betreff")
.font(.subheadline)
.lineLimit(2)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
} ```
Thanks in advance for your help!

How can I add fixed-width space to beginning of HStack?

In SwiftUI I am adding buttons to an HStack. I want a space of a fixed width at the beginning of the HStack. Currently the buttons are directly up against the left edge of the screen and I want a space of 64px before the first button. I cannot seem to find an answer to this, my Google-Fu may be failing me.
Here is what I have:
struct MyView: View {
var body: some View {
HStack(alignment: .center, spacing: 12, content: {
Button(action: doThis) {
Image("this").resizable().aspectRatio(contentMode: .fit)
}.frame(width: 38, height: 38, alignment: .center)
Button(action: doThat) {
Image("that").resizable().aspectRatio(contentMode: .fit)
}.frame(width: 38, height: 38, alignment: .center)
Spacer()
})
}
func doThis() {}
func doThat() {}
}
Just add some padding on the left.
struct ContentView: View {
var body: some View {
HStack(alignment: .center, spacing: 12, content: {
Button(action: doThis) {
Image("this").resizable().aspectRatio(contentMode: .fit)
}.frame(width: 38, height: 38, alignment: .center)
.padding(.leading, 64) /// here!
Button(action: doThat) {
Image("that").resizable().aspectRatio(contentMode: .fit)
}.frame(width: 38, height: 38, alignment: .center)
Spacer()
})
}
func doThis() {}
func doThat() {}
}
Before
After

SwiftUI: Have button's right and left stick to parent's right and left

SwiftUI question here...
I am trying to layout my button so it has the full width of the screen minus some padding of 16. I don't want to use this UIScreen.main.bounds.width. I want it to be dynamic.
Do you guys have any idea how to do this?
Thank you!
Code sample
By using static value it works
struct TestButton : View {
var body: some View {
Button(action: {
}) {
Text("Tap me")
}
.modifier(PrimaryButton())
}
}
fileprivate struct PrimaryButton: ViewModifier {
func body(content: Content) -> some View {
content
.frame(width: 300, height: 28)
.padding()
.background(Color.yellow)
.foregroundColor(Color.white)
}
}
By using dfd's comment, does not change anything.
struct TestButton : View {
var body: some View {
Button(action: {
}) {
Text("Tap me")
}
.modifier(PrimaryButton())
}
}
fileprivate struct PrimaryButton: ViewModifier {
func body(content: Content) -> some View {
content
.relativeWidth(1.0)
.padding()
.background(Color.yellow)
.foregroundColor(Color.white)
}
}
GeometryReader may help you
for example:
SomeButton: View {
var body: some View {
GeometryReader { geometry in
VStack() {
Button(action:{}) {
Text("\(geometry.size.width)")
}.padding()
.frame(minWidth: geometry.frame(in: .global).size.width,
minHeight: geometry.frame(in: .global).size.height
)
.background(Color.red)
}
}
}
}
Have you tried .frame(minWidth: 0, maxWidth: .infinity)
Setting the frame width to ".infinity" makes it use maximum width
SwiftUI Button fill parent
Here is the complete code -
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading, spacing: CGFloat(5)){
Button(action: {}) {
Text("Button fill width")
.font(.title)
.foregroundColor(.white)
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray)
HStack(alignment: .center, spacing: CGFloat(5)){
Button(action: {}) {
Text("Btn-1")
.font(.title)
.foregroundColor(.white)
}.padding()
.background(Color.gray)
Button(action: {}) {
Text("Button fill width")
.font(.title)
.foregroundColor(.white)
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray)
}
HStack(alignment: .center, spacing: CGFloat(5)){
Button(action: {}) {
Text("B-1")
.font(.title)
.foregroundColor(.white)
}.padding()
.background(Color.gray)
Button(action: {}) {
Text("B fill")
.font(.title)
.foregroundColor(.white)
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray)
Button(action: {}) {
Text("B fill")
.font(.title)
.foregroundColor(.white)
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.gray)
}
HStack(alignment: .center, spacing: CGFloat(5)){
Spacer()
Text("Hello World...")
.font(.title)
.fontWeight(.heavy)
.frame(minWidth: 0, maxWidth: .infinity)
.padding(5)
}.background(Color.gray)
HStack(alignment: .center, spacing: CGFloat(5)){
Spacer()
Text("Hello World...")
.font(.body)
.fontWeight(.heavy)
.multilineTextAlignment(.leading)
.lineLimit(10)
.padding(5)
}.background(Color.gray)
HStack(alignment: .center, spacing: CGFloat(5)){
Button(action: {}) {
Text("1").foregroundColor(.black).bold()
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background( Image("RC_btn_default_normal")
.renderingMode( Image.TemplateRenderingMode.original))
Button(action: {}) {
Text("2").foregroundColor(.black).bold()
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background( Image("RC_btn_default_normal")
.renderingMode( Image.TemplateRenderingMode.original))
Button(action: {}) {
Text("3").foregroundColor(.black).bold()
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background(Image("RC_btn_default_normal")
.renderingMode( Image.TemplateRenderingMode.original))
Button(action: {}) {
Text("4").foregroundColor(.black).bold()
}.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.background( Image("RC_btn_default_normal")
.renderingMode( Image.TemplateRenderingMode.original))
}
Spacer()
}.background(Color.green)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}