Как выровнять текст по центру кнопки при использовании произвольной длины hstack?

Я новичок в iOS и языке быстрого программирования. Я пытаюсь создать домашнюю страницу для приложения, и у меня есть две кнопки.

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

Я использую приведенный ниже класс для создания кнопок.

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

Но предварительный просмотр приложения в XCode IDE показывает кнопки без текста, как показано ниже.

Если я уменьшу интервал HStack до 75, например HStack(spacing: 75), я смогу видеть текст в кнопке, но кнопки очень маленькие. Может ли кто-нибудь сообщить мне, в чем ошибка, которую я здесь допускаю, и как я могу ее исправить?

Редактировать1

Также пробовал: .frame(width: width, height: height, alignment: .center) в классе кнопок, но результат тот же.

Не имеет отношения к вашей проблеме, но нет смысла создавать здесь экземпляр класса CustomButton (и уж точно не два). Функции могут быть static функциями для чего угодно (enum, struct, class и т. д.).

jnpdx 15.06.2024 19:56

@jnpdx Примечательно, что, делая маленькие шаги, я учту ваши замечания.

Metadata 15.06.2024 20:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Уменьшите интервал в HStack. В вашем случае интервал составляет 275, поэтому попробуйте уменьшить его до 50 или 40, и вы начнете видеть текст. Поскольку интервал 275 превышает ширину кнопки, текст выходит за пределы поля зрения кнопки и, следовательно, вы не можете его увидеть.

Код ниже представляет собой исправленный код:

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


      }
    }
  }
}

class CustomButton {
    
    func createBlueButton(withTitle title: String, height: CGFloat, width: CGFloat, color: String, systemName: String, action: @escaping () -> Void) -> some View {
            Button(action: {}) {
                HStack(spacing: 40) {
                    Image(systemName: systemName)
                        .foregroundColor(.white)
                    Text(title)
                        .fontWeight(.bold)
                        .foregroundColor(.white)
                }
                .padding()
                .frame(width: width, height: height) // Adjusted button size
                .background(Color.blue)
                .clipShape(RoundedRectangle(cornerRadius: 20)) // Squircle shape
                
            }
        }
        
        func createGreenButton(withTitle title: String, height: CGFloat, width: CGFloat, color: String, systemName: String, action: @escaping () -> Void) -> some View {
            Button(action: {}) {
                HStack(spacing: 50) {
                    Image(systemName: systemName)
                        .foregroundColor(.white)
                    Text(title)
                        .fontWeight(.bold)
                        .foregroundColor(.white)
                }
                .padding()
                .frame(width: width, height: height) // Adjusted button size
                .background(Color.green)
                .clipShape(RoundedRectangle(cornerRadius: 20)) // Squircle shape
                
            }
        }
    
}

struct HomePage_Previews: PreviewProvider {
  static var previews: some View {
    HomePage()
  }
}

В createBlueButton() я уменьшил интервал до 40, а в createBlueButton() — до 50.

И после Edit1...

Модификатор кадра должен применяться перед ClipShape RoundedRectangle и модификатором цвета фона. Это сделает кнопку нужного размера с видимым текстом.

И да, порядок модификаторов имеет большое значение при разработке компонента в SwiftUI.

Все изменения присутствуют в приведенном выше коде.

Вот результат:

Image

@Shikar, я уже пробовал это и это я уже объяснял ранее edit1 в вопросе. Я хочу, чтобы кнопки были шире. Если я увеличу ширину и высоту кадра, я не увижу желаемых результатов. Но увеличение интервала в hstack делает его шире, но текст становится невидимым.

Metadata 16.06.2024 04:46
Ответ принят как подходящий

Я бы предложил следующие изменения:

  • Вместо применения spacing к HStack используйте один или несколько Spacer(), чтобы задать интервал:
HStack {
    Image(systemName: systemName)
    Spacer()
    Text(title)
    Spacer()
}
  • Причина, по которой ваши попытки установить ширину рамки не увенчались успехом, может заключаться в том, что вам нужно установить ширину перед применением цвета фона. Таким образом, модификатор .frame должен стоять перед .background и .clipShape.

  • Ваш класс CustomButton похоже на фабрику пуговиц. Однако нет необходимости создавать экземпляр для каждой кнопки. Фактически вы создали два экземпляра с именами footballLoginButton и baseballLoginButton, но затем используете footballLoginButton для создания обеих реальных кнопок, baseballLoginButton не используется. Поэтому я бы предложил изменить функции на статические, и это тоже может быть struct вместо class.

  • Вместо использования фиксированной ширины и высоты просто позвольте содержимому найти свой собственный размер, а затем используйте отступы, чтобы добавить пробелы там, где это необходимо.

  • Когда дело доходит до стиля кнопок, лучше всего определить свой собственный ButtonStyle.

  • Модификатор .foregroundColor устарел, вместо него используйте .foregroundStyle.

Вот как все это может сочетаться:

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

Screenshot

Это ясно и просто понять. Можно ли как-нибудь увеличить размер шрифта?

Metadata 16.06.2024 11:51

@Metadata Рад, что смог помочь, спасибо, что приняли ответ. Чтобы увеличить размер шрифта надписей кнопок, просто добавьте модификатор .font внутри тела CustomButtonStyle. Прямо перед тем, как .fontWeight кажется хорошим местом.

Benzy Neez 16.06.2024 12:01

Другие вопросы по теме

Похожие вопросы

Полноразмерная кнопка SwiftUI: почему «maxWidth: .infinity»? Почему бы не «minWidth: .infinity»?
Как реализовать множественное число в каталоге строк для меток, на которых не отображаются числа?
Swift concurrency: «for await» не компилируется, «await» имеет предупреждение
Кнопка в поведении ячейки UICollectionViewCompositionalLayout
Flutter ios: универсальные ссылки не работают - ни одно устройство не загружается
Сборка Flutter для симулятора iOS
Как правильно создать строковый ключ локализации с переменными внутри него
Mach_task_self_ не является безопасным для параллелизма, поскольку он включает в себя общее изменяемое состояние
Синхронизация изолированного метода MainActor во время инициализации и обеспечение параллелизма Swift 6
Аудиоэлемент HTML5: визуальные элементы кнопки для воспроизведения звука не обновляются при нажатии, а ждут, пока звук не начнет воспроизводиться (проблема с мобильным iOS)