Fit Image & Text in Frame SwiftUI - swift

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()
}
}
}
}

Related

Content is shown behind the navigation bar when the text field is active

when I use the textfield in my View, the Content in the vstack or scrollview is seen behind the custom navigation bar. How can I fix this background problem?
Code from the Current View
import SwiftUI
import MapKit
struct address_edit_address: View {
#State private var street: String = ""
#State private var titel: String = ""
#State private var comment: String = ""
#State var topLeft: CGFloat = 0
#State var topRight: CGFloat = 50
#State var bottomLeft: CGFloat = 50
#State var bottomRight: CGFloat = 0
#State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
var body: some View {
VStack{
VStack(alignment: .leading, spacing: 20){
Map(coordinateRegion: $region).frame(minWidth: 0, idealWidth: 383, maxWidth: 383, minHeight: 0, idealHeight: 128, maxHeight: 128).cornerRadius(10)
VStack (alignment: .leading, spacing: 10){
Text("Adresse:").font(.custom("Arboria-Medium", size:13))
HStack (alignment: .center){
TextField("Straße und Hausnummer*", text: $street).frame(minWidth: 0, idealWidth: 383, maxWidth: 383, minHeight: 0, idealHeight: 54, maxHeight: 54, alignment: .center)
.foregroundColor(Color("white"))
.background(RoundedRectangle(cornerRadius:10).fill(Color("grey_dark1_bg_obj")))
.overlay(
RoundedRectangle(cornerRadius:10).stroke(Color("grey_light2_obj_font"), lineWidth: 1))
}
}
VStack (alignment: .leading, spacing: 10){
Text("Adresstitel & Typ(optional):").font(.custom("Arboria-Medium", size:13))
HStack(spacing: 0){
TextField("Titel", text: $titel).frame(minWidth: 0, idealWidth: 230, maxWidth: 230, minHeight: 0, idealHeight: 54, maxHeight: 54, alignment: .leading)
.foregroundColor(Color("white"))
.background(RoundedCornerShape(radius:10, corners: [.topLeft, .bottomLeft]).fill(Color("grey_dark1_bg_obj")))
.overlay(
RoundedCornerShape(radius: 10, corners: [.topLeft, .bottomLeft]).stroke(Color("grey_light2_obj_font"), lineWidth: 1))
HStack(spacing: 0){
Button(action: {
print("Privat")
}){ VStack {
Image(systemName: "house.fill")
Text("Privat").font(.custom("Arboria-Medium", size:12))
}
}.frame(width: 74, height: 56).background(Color("blue")).border(Color("grey_light2_obj_font"), width: 1)
Button(action: {
print("Arbeit")
}){ VStack{
Image(systemName: "briefcase.fill")
Text("Arbeit").font(.custom("Arboria-Medium", size:12))
}
}.frame(width: 74, height: 54)
.background(RoundedCornerShape(radius: 10, corners: [.topRight, .bottomRight]).fill(Color("grey_dark1_bg_obj")))
.overlay(
RoundedCornerShape(radius: 10, corners: [.topRight, .bottomRight]).stroke(Color("grey_light2_obj_font"), lineWidth: 1))
}.frame(width: 148, height: 51, alignment: .leading)
}
}
VStack (alignment: .leading, spacing: 10){
Text("Anmerkung hinzufügen(optional):").font(.custom("Arboria-Medium", size:13))
HStack{
TextField("Anmerkung zur Lieferung", text: $comment).frame(minWidth: 0, idealWidth: 383, maxWidth: 383, minHeight: 0, idealHeight: 102, maxHeight: 102, alignment: .center)
.foregroundColor(Color("white"))
.background(RoundedRectangle(cornerRadius:10).fill(Color("grey_dark1_bg_obj")))
.overlay(
RoundedRectangle(cornerRadius:10).stroke(Color("grey_light2_obj_font"), lineWidth: 1))
}
HStack{
Text("*Pflichtfelder")
Spacer()
Text("0/180")
}.font(.custom("Arboria-Medium", size:13))
}.frame(width: UIScreen.screenWidth, height: UIScreen.screenHeight - 600, alignment: .top)
}
VStack(spacing: 30){
HStack(spacing: 20){
Button("Speichern"){
}.frame(minWidth: 0, idealWidth: 160, maxWidth: 160, minHeight: 0, idealHeight: 43, maxHeight: 43, alignment: .center).background(Color("green_mid")).clipShape(RoundedRectangle(cornerRadius: 10)).font(.custom("Arboria-Medium", size: 14))
Button (action: {
print("Favorit")
}){ HStack {
Text("Favorisieren").font(.custom("Arboria-Medium", size: 14))
Image(systemName:"heart")
}.foregroundColor(Color("yellow"))
}.frame(minWidth: 0, idealWidth: 160, maxWidth: 160, minHeight: 0, idealHeight: 43, maxHeight: 43, alignment: .center).overlay(
RoundedCornerShape(radius: 10, corners: [.topRight, .bottomRight, .topLeft, .bottomLeft]).stroke(Color("yellow"), lineWidth: 1))
}
Button("Adresse entfernen"){
}.foregroundColor(Color("red")).font(.custom("Arboria-Medium", size: 14))
}
Spacer()
}.frame(width: UIScreen.screenWidth, height: UIScreen.screenHeight).background(Color.black) .foregroundColor(Color.white)
}
}
struct address_edit_address_Previews: PreviewProvider {
static var previews: some View {
address_edit_address().preferredColorScheme(.dark)
}
}
Code from the template, where the navigation bar is implemented
import SwiftUI
struct account_template<Content: View>: View {
#Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
#ViewBuilder var content: Content
var title: String
var scrollable: Bool
init(content:Content, title:String, scrollable: Bool){
self.content = content
self.title = title
self.scrollable = scrollable
}
var btnBack : some View {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}){
VStack{
ZStack{
HStack(){
Image(systemName: "arrow.left")
.aspectRatio(contentMode: .fit)
.foregroundColor(.white)
Spacer()
}.frame(width: UIScreen.screenWidth)
HStack (alignment:.center){
Text(title).foregroundColor(.white).font(.custom("Arboria-Medium", size:16))
}.frame(width: UIScreen.screenWidth)
}.frame(width: UIScreen.screenWidth, height: 50).background(Color("black"))
Divider().background(Color("white")).frame(height:2)
}.frame(height: 75, alignment: .center).background(Color.black).edgesIgnoringSafeArea(.top)
}
}
var body: some View {
VStack {
Spacer()
Divider().background(Color("white")).frame(height:2)
if scrollable {
ScrollView(showsIndicators:false){
content
}.background(Color.black) .foregroundColor(Color.white) .frame(width: UIScreen.screenWidth, height: UIScreen.screenHeight - 75, alignment: .top)
}else{
VStack{
content
}.background(Color.black) .foregroundColor(Color.white) .frame(width: UIScreen.screenWidth, height: UIScreen.screenHeight - 75, alignment: .top)
}
}.background(Color.black) .foregroundColor(Color.white) .frame(width: UIScreen.screenWidth, height: UIScreen.screenHeight, alignment: .center).navigationBarBackButtonHidden(true)
.navigationBarItems(trailing: btnBack)
}
}
struct adress_template_Previews: PreviewProvider {
static var previews: some View {
account_template(content: address_add_address(), title: "Adresse hinzufügen", scrollable: true)
}
}

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

How can I add a button in SwiftUI

How can I add a button at this location in SwiftUI? I have a textfield and a background being used, but I'm not sure how you can add a button to this location, like a bar button in swift.
My code:
struct MyTextField: View
{
#ObservedObject var model: TextFieldModel
var body: some View
{
VStack(spacing: 0)
{
Color.black
.frame(height: 100)
.overlay(Image(("appIconLogo")).resizable().frame(width: 70, height: 70),
alignment: .bottom)
.edgesIgnoringSafeArea(.top)
VStack(alignment: .leading, spacing: 10)
{
Text("Welcome!")
.font(.system(size: 60, design: .rounded))
.foregroundColor(.black)
.padding(.leading)
iTextField("Search Your Ticker", text: $model.text, isEditing: $model.isEditing)
.foregroundColor(.black)
.showsClearButton(true)
.autocapitalization(.allCharacters)
.disableAutocorrection(true)
.returnKeyType(.search)
.onReturn
{
print($model.text)
NotificationCenter.default.post(name: Notification.Name(rawValue: "isValidTicker"), object: nil)
}
.foregroundColor(.black)
.style(height: 58, font: nil, paddingLeading: 25, cornerRadius: 6, hasShadow: true, image: Image(systemName: "magnifyingglass"))
.foregroundColor(.black)
}.frame(maxWidth: .infinity, alignment: .leading)
}.frame(maxHeight: .infinity, alignment: .top)
}
}
I assume you wanted something like this
Color.black
.frame(height: 100)
.overlay(Image(("appIconLogo")).resizable().frame(width: 70, height: 70), alignment: .bottom)
.overlay(Button("Perform") {}.padding(), alignment: .leading) // << here!!
.edgesIgnoringSafeArea(.top)
Any particular reason you have the Color.black with an overlay for the logo? Using your code, wrapping it in a ZStack should work
ZStack(alignment: .leading) {
Color.black
.frame(height: 100)
.overlay(Image(("appIconLogo")).resizable().frame(width: 70, height: 70), alignment: .bottom)
.edgesIgnoringSafeArea(.top)
Button(action:{}) {
Text("Button Text")
}
}

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()
}
}