I am a novice to iOS and swift programming language. I am trying to create a home page for an app and I have two buttons in it.
import SwiftUI
struct HomePage: View {
var body: some View {
ZStack {
// Background gradient
LinearGradient(gradient: Gradient(colors: [.blue, .green]), startPoint: .topLeading, endPoint: .bottomTrailing)
.ignoresSafeArea()
let footballLoginButton = CustomButton()
let baseballLoginButton = CustomButton()
VStack(spacing: 40) {
// App Logo (replace with your actual logo)
Image("your_app_logo")
.resizable()
.scaledToFit()
.frame(width: 150, height: 70)
Text("Select your sport:")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.white)
footballLoginButton.createBlueButton(withTitle: "football Login", height: 70, width: 250, color: "blue", systemName: "football", action: {
// Your football login action code here
})
footballLoginButton.createGreenButton(withTitle: "baseball Login", height: 70, width: 250, color: "green", systemName: "baseball", action: {
// Your football login action code here
})
}
}
}
}
struct HomePage_Previews: PreviewProvider {
static var previews: some View {
HomePage()
}
}
I am using the below class to create buttons.
class CustomButton {
func createBlueButton(withTitle title: String, height: CGFloat, width: CGFloat, color: String, systemName: String, action: @escaping () -> Void) -> some View {
Button(action: {}) {
HStack(spacing: 275) {
Image(systemName: systemName)
.foregroundColor(.white)
Text(title)
.fontWeight(.bold)
.foregroundColor(.white)
}
.padding()
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 20)) // Squircle shape
.frame(width: width, height: height) // Adjusted button size
}
}
func createGreenButton(withTitle title: String, height: CGFloat, width: CGFloat, color: String, systemName: String, action: @escaping () -> Void) -> some View {
Button(action: {}) {
HStack(spacing: 275) {
Image(systemName: systemName)
.foregroundColor(.white)
Text(title)
.fontWeight(.bold)
.foregroundColor(.white)
}
.padding()
.background(Color.green)
.clipShape(RoundedRectangle(cornerRadius: 20)) // Squircle shape
.frame(width: width, height: height) // Adjusted button size
}
}
}
But the app preview on XCode IDE shows buttons without text in it as below.
If I reduce the HStack's spacing to 75 like HStack(spacing: 75)
I am able to see the text in button but the buttons are very small. Could anyone let me know what is the mistake I am making here and how can I correct it?
Edit1
Also tried: .frame(width: width, height: height, alignment: .center)
in the button class but the result is same.
I would suggest the following changes:
spacing
to the HStack
, use one or more Spacer()
to provide the spacing:HStack {
Image(systemName: systemName)
Spacer()
Text(title)
Spacer()
}
The reason why your attempts to set a frame width didn't seem to be working may be because you need to set the width before you apply the background color. So the .frame
modifier needs to come before the .background
and .clipShape
.
Your class CustomButton
appears to be a button factory. However, there is no need to create an instance for each button. In fact, you have created two instances called footballLoginButton
and baseballLoginButton
, but you then use footballLoginButton
to create both of the actual buttons, baseballLoginButton
is not being used. So I would suggest changing the functions into static functions, and it can be a struct
instead of a class
too.
Instead of using a fixed width and height, just let the content find its own size and then use padding to add spacing where needed.
When it comes to button styling, it works well to define your own ButtonStyle
.
The modifier .foregroundColor
is deprecated, use .foregroundStyle
instead.
Here's how it can all come together:
struct HomePage: View {
var body: some View {
ZStack {
// Background gradient
LinearGradient(gradient: Gradient(colors: [.blue, .green]), startPoint: .topLeading, endPoint: .bottomTrailing)
.ignoresSafeArea()
VStack(spacing: 40) {
// App Logo (replace with your actual logo)
Image("your_app_logo")
.resizable()
.scaledToFit()
.frame(width: 150, height: 70)
Text("Select your sport:")
.font(.title)
.fontWeight(.bold)
.foregroundStyle(.white)
CustomButton.createBlueButton(withTitle: "football Login", systemName: "football") {
// Your football login action code here
}
CustomButton.createGreenButton(withTitle: "baseball Login", systemName: "baseball") {
// Your baseball login action code here
}
}
.padding(.horizontal, 30)
}
}
}
class CustomButton {
private struct CustomButtonStyle: ButtonStyle {
let color: Color
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundStyle(.white)
.fontWeight(.bold)
.padding()
.background(color)
.clipShape(RoundedRectangle(cornerRadius: 20)) // Squircle shape
}
}
private static func createButton(withTitle title: String, systemName: String, color: Color, action: @escaping () -> Void) -> some View {
Button(action: action) {
HStack {
Image(systemName: systemName)
Spacer()
Text(title)
Spacer()
}
}
.buttonStyle(CustomButtonStyle(color: color))
}
static func createBlueButton(withTitle title: String, systemName: String, action: @escaping () -> Void) -> some View {
CustomButton.createButton(withTitle: title, systemName: systemName, color: .blue, action: action)
}
static func createGreenButton(withTitle title: String, systemName: String, action: @escaping () -> Void) -> some View {
CustomButton.createButton(withTitle: title, systemName: systemName, color: .green, action: action)
}
}