SwiftUI уроки (часть 5)

ссылка на 4ю часть

Buttons, Labels, Gradients

f091ccf26f1683f1b03b226c27d4fcee.png

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

Снимок экрана 2024-02-28 в 16.54.59.png

Button (кнопка) является одним из ключевых элементов пользовательского интерфейса, предоставляющим возможность взаимодействия пользователя с приложением. Она представляет собой виджет, на который пользователь может нажать для выполнения определенного действия. 


Нам предоставляют множество различных инициализаторов для кнопки, но давайте воспользуемся одним из самых распространенных вариантов, поместите этот код в свой ContentView

struct ContentView: View {

    var body: some View {

		Button(action: {

			// Здесь можно поместить то, что должно произойти по нажатию на кнопку

		}, label: {

			// Здесь помещаем то, как выглядит наша кнопка

		})

    }
}

Как вы понимаете эти два блока можно использовать под задачи которые решает кнопка, давайте реализуем простую кнопку на которую можно нажимать и получать вывод информации об этом в консоль

struct ContentView: View {
    var body: some View {
		Button(action: {
			// Здесь можно поместить то, что должно произойти по нажатию на кнопку
			print("Нажал кнопку")
		}, label: {
			// Здесь помещаем то, как выглядит наша кнопка
			Text("Нажми меня")
		})
    }
}

2f8ffdf315b31212ad5b561979a9894f.png

Попробуйте понажимать на кнопку и посмотрите на результат который выводится в консоль

47f153e23d1d696b2b70b87c92020593.png

Кстати хочу заметить, что есть еще более удобный вариант создания кнопки который выглядит чище:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
		}
    }
}

Результат как вы понимаете будет идентичным.

Теперь, когда вы знаете, как создать простую кнопку, давайте настроим ее внешний вид с помощью встроенных модификаторов. Чтобы изменить цвет фона и текста, вы можете использовать модификаторы background и foregroundStyle, например так:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.background(Color.purple)
				.foregroundStyle(.blue)
		}
    }
}

Если вы хотите изменить тип шрифта, вы можете использовать модификатор font и указать тип шрифта (например, .title), как в следующем примере:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.background(Color.purple)
				.foregroundStyle(.blue)
				.font(.title)
		}
    }
}

После изменения ваша кнопка должна выглядеть примерно так, как показано на скриншоте.

fa35d500a814bd385818469e1d978c0b.png

Как видите, кнопка выглядит не очень хорошо. Кажется, что кнопке нужно дополнительное пространство вокруг текста. Для этого вы можете использовать модификатор padding, как показано ниже:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.padding()
				.background(Color.purple)
				.foregroundStyle(.blue)
				.font(.title)
		}
    }
}

После внесения изменений канвас обновит кнопку соответствующим образом. Теперь кнопка должна выглядеть намного лучше.

Порядок модификаторов важен

Вы наверное заметили что я добавил  padding не в конце, а почему-то первым модификатором. Давайте просто попробуем поменять место этого модификатора и поместим его в конец.

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.background(Color.purple)
				.foregroundStyle(.blue)
				.font(.title)
				.padding()
		}
    }
}

7156e59bd87fcb9f70b40fec8bc951b6.png

Если вы разместите модификатор padding после модификатора background, вы все равно сможете добавить некоторый отступ к кнопке, но при этом цвет фона не будет затронут. Если вам интересно, почему, модификаторы будут работать так:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.background(Color.purple)  // 1. Изменить цвет фона на фиолетовый
				.foregroundStyle(.blue)    // 2. Установить цвет переднего плана/шрифта на синий
				.font(.title)			   // 3. Изменить тип шрифта
				.padding()				   // 4. Добавить отступы с основным цветом (т.е. синим)
		}
    }
}

Соответственно, модификаторы будут работать так, если модификатор отступа размещен перед модификатором фона:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.padding()				   // 1. Добавить отступы
				.background(Color.purple)  // 2. Изменить цвет фона на фиолетовый включая отступ
				.foregroundStyle(.blue)    // 3. Установить цвет переднего плана/шрифта на синий
				.font(.title)			   // 4. Изменить тип шрифта
		}
    }
}

Добавление границ (border) к кнопке

Это не означает, что модификатор отступа всегда должен быть размещен в самом начале. Многое зависит от дизайна вашей кнопки. Допустим, вы хотите создать кнопку с границами, как здесь:

cfcee95e211ffa1c71590673398b499b.png

Вы можете изменить код элемента Text следующим образом:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.padding()
				.foregroundStyle(.purple)
				.font(.title)
				.border(.purple, width: 5)
		}
    }
}

Здесь мы устанавливаем цвет переднего плана на фиолетовый, затем добавляем некоторые пустые отступы c помощью padding вокруг текста. Модификатор border используется для определения ширины и цвета границы. Попробуйте поиграть со значением параметра width, чтобы увидеть, как это работает.


Давайте рассмотрим еще один пример. Предположим, дизайнер показывает вам следующий дизайн кнопки. 

a61b8d1d511758cabcd56bc067185394.png

Как бы вы сделали такую кнопку? Попробуйте реализовать ее самостоятельно, если не получится — то давайте делать это вместе.

На самом деле все не так сложно, давайте поменяем код на следующий и посмотрим на комментарии которые я для вас оставил.

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.fontWeight(.bold) // меняем наш шрифт на жирный
				.font(.title) // делаем наш шрифт под размеры оглавления
				.padding() // создаем первый отступ вокруг текста
				.background(Color.purple) // красим бэкграунд с учетом отступа который создали строчкой выше
				.foregroundStyle(.white) // меняем шрифт на белый
				.padding(10) // создаем еще один отступ уже поверх того который создали двумя строчками выше (получается он будет такого же цвета какой он был до покраски и это будет та самая разница от границы которую создадим на следующей строчке и до покрашеного бэкграунда)
				.border(Color.purple, width: 5) // создаем новую границу поверх всех предыдущих настроек
		}
    }
}

Добавьте этот код к себе, прочитайте комментарии и попробуйте поиграться с этими модификаторами в том числе включая и выключая те или иные из них

Хорошо, давайте попробуем более сложный пример, что если нам нужна круглая кнопка и тоже с границами?

e5ff34b134fbccb8f0f084ff54874ed2.png

Давайте разберемся в этом вопросе также построчно:

struct ContentView: View {
    var body: some View {
		Button {
			print("Нажал кнопку")
		} label: {
			Text("Нажми меня")
				.fontWeight(.bold) // жирный шрифт
				.font(.title) // размер шрифта
				.padding() // первый отступ
				.background(.purple) // красим в фиолетовый с учетом отступа
				.cornerRadius(40) // скругляем кнопку
				.foregroundStyle(.white) // шрифт белый
				.padding(10) // еще один отступ (начиная отсюда фон становится белым)
				.overlay { // накладываем оверлей поверх нашей кнонпки
				RoundedRectangle(cornerRadius: 40) // делаем еще один квадрат со скругленным краям
				.stroke(.purple, lineWidth: 5) // вырезаем изнутри  этот квадрат красим его в фиолетовый и оставляем линию равную 5 поинтам
				}
		}
    }
}

Чтобы еще лучше понять что произошло в момент когда мы добавили overlay попробуйте удалить строчку  .stroke (.purple, lineWidth: 5)

Создаем кнопку с картинкой

До сих пор мы работали только с текстовыми кнопками. В реальном проекте вы или ваш дизайнер может захотеть отобразить кнопку с изображением. Синтаксис создания кнопки с изображением точно такой же, за исключением того, что вы используете элемент управления Image вместо элемента управления Text, как в следующем примере:

struct ContentView: View {
    var body: some View {
		Button(action: {
			print("Нажал кнопку удаления")
		}) {
			Image(systemName: "trash")
		}
		.font(.largeTitle)
		.foregroundColor(.red)
    }
}

Для удобства мы используем встроенные символы SF (т.е. trash) для создания кнопки изображения. Мы указываем .largeTitle в модификаторе шрифта, чтобы сделать изображение немного больше. Ваша кнопка должна выглядеть следующим образом:

4a6e8dcd94bb533d79e4afd10b5af10b.png

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

struct ContentView: View {
    var body: some View {
		Button(action: {
			print("Нажал кнопку удаления")
		}) {
			Image(systemName: "trash")
		}
		.padding()
		.background(.red)
		.clipShape(Circle())
		.font(.largeTitle)
		.foregroundColor(.white)
    }
}

В итоге мы получим круглую кнопку с красным фоном и белым цветом самой иконки

79f14cf0585d12ab511565a77ad38422.png

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

struct ContentView: View {
    var body: some View {
		Button(action: {
			print("Нажал кнопку удаления")
		}) {
			HStack {
				Text("Удалить")
					.font(.title)
				Image(systemName: "trash")
					.font(.title)
			}
			.padding()
			.foregroundColor(.white)
			.background(Color.red)
			.cornerRadius(40)
			}
    }
}

1c1c17895804b9ed290c02c6cca08c95.png

Используем Label

Начиная с iOS 14, фреймворк SwiftUI представил новый элемент под названием Label, который позволяет размещать изображение и текст в одном отображении. Таким образом, вместо использования HStack вы можете использовать Label для создания того же макета.

struct ContentView: View {
	var body: some View {
		Button(action: {
			print("Нажал кнопку удаления")
		}) {
			Label(
				title: {
					Text("Удалить")
						.fontWeight(.semibold)
						.font(.title)
				}, icon: {
					Image(systemName: "trash")
						.font(.title)
				} )
			.padding()
			.foregroundColor(.white)
			.background(.red)
			.cornerRadius(40)
		}
	}
}

1627701b2bed9baaf7e6121ea5e440fb.png

Не могу сказать что лично мне нравятся лейблы потому что они забирают гибкость, но если вам подходит такой вариант — то вы должны о нем знать.

Создание кнопки с градиентным фоном и тенью

С помощью SwiftUI вы можете легко оформить кнопку с градиентным фоном. Вы можете не только определить определенный цвет для модификатора фона, но и легко применить градиентный эффект к любой кнопке. Все, что вам нужно сделать, это заменить следующую строку кода:

.background(.red)

На

.background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing))

SwiftUI поставляется с несколькими встроенными градиентными эффектами. Приведенный выше код применяет линейный градиент слева (.leading) направо (.trailing). Он начинается с красного слева и заканчивается синим справа.

6a97ba54a5f7b49e2477249383d5d771.png

Если вы хотите применить градиент сверху вниз, вы заменяете .leading на .top, а .trailing на .bottom следующим образом:

8cdedd55d94efc76d4ee45d3dc698787.png

Разумеется мы можем использовать градиенты с нашими кастомными цветами, давайте создадим нечто вроде такого

fdd3d48fa5c24a92b114106b7afb72a1.png

Перейдем в наш каталог ассетов и создадим там новый Color Set

1950ddb110bcaa9155650ec858b33d4e.png

Выделите Any Appearance и задайте цвет который вы бы хотели в правой панели инспекторов

1b49ae6546dc6c7ecfac95605e436c2a.png71ec3843aac077ee94025cec1d761774.png

И создайте еще один цвет другого оттенка

e432685b0b33182d495d37f293fc639f.png

Возвращаемся обратно в наш ContentView и меняем наш градиент на следующий:

.background(LinearGradient(gradient: Gradient(colors: [Color.brightGreen, Color.darkGreen]), startPoint: .top, endPoint: .bottom))

Как вы видите Xcode уже сгенерировал для вас два новых свойства в соответствии с созданными нами цветами, иногда из за этого появляются коллизии если вы пытаетесь использовать название цвета такое же которое уже заложено в фреймворке, но Xcode подскажет вам с помощью warning что вы добавили цвет со схожим именем, так что не переживайте на этот счет.

В итоге у нас получился такой результат

3729a7855c87ba7afcdf826602140078.png

Ну и наконец чтобы добавить нашей кнопке немного больше объемности, давайте добавим тень прямо под модификатором радиуса угла.

.shadow(color: .gray, radius: 20.0, x: 20, y: 10)

Итоговый код ContentView должен выглядит следующим образом:

struct ContentView: View {
	var body: some View {
		Button(action: {
			print("Нажал кнопку удаления")
		}) {
			Label(
				title: {
					Text("Удалить")
						.fontWeight(.semibold)
						.font(.title)
				}, icon: {
					Image(systemName: "trash")
						.font(.title)
				} )
			.padding()
			.foregroundColor(.white)
			.background(LinearGradient(gradient: Gradient(colors: [Color.brightGreen, Color.darkGreen]), startPoint: .top, endPoint: .bottom))
			.cornerRadius(40)
			.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
		}
	}
}

6efd745663220f993f62af038757a25d.png

Создание кнопки в полную ширину экрана

Большие кнопки обычно акцентируют внимание пользователя. Иногда может потребоваться создать кнопку на всю ширину экрана. Модификатор frame предназначен для управления размером элемента. Независимо от того, хотите ли вы создать кнопку с фиксированным размером или кнопку с динамической шириной, можно использовать этот модификатор. Чтобы создать кнопку которая займет всю ширину экрана, вы можете изменить код кнопки следующим образом:

struct ContentView: View {
	var body: some View {
		Button(action: {
			print("Нажал кнопку удаления")
		}) {
			Label(
				title: {
					Text("Удалить")
						.fontWeight(.semibold)
						.font(.title)
				}, icon: {
					Image(systemName: "trash")
						.font(.title)
				} )
			.frame(minWidth: 0, maxWidth: .infinity)
			.padding()
			.foregroundColor(.white)
			.background(LinearGradient(gradient: Gradient(colors: [Color.brightGreen, Color.darkGreen]),
									   startPoint: .top, endPoint: .bottom))
			.cornerRadius(40)
			.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
		}
	}
}

c23d7c771b5d356750e5c72a440f4057.png

Мы добавили модификатор frame перед padding и в нем мы определяем гибкую ширину для кнопки. Мы устанавливаем параметр maxWidth в .infinity. Это приведет к тому, что кнопка заполнит ширину всего контейнера. 

Установив maxWidth равным .infinity, ширина кнопки будет автоматически адаптироваться в зависимости от ширины экрана устройства. Если вы хотите предоставить кнопке дополнительные отступы по горизонтали, вставьте модификатор padding после .cornerRadius (40):

.padding(.horizontal, 20)

Соответственно мы получим следующее отображение:

7a4f9472152381026b78ca944d79f93e.png

Настройка кнопки с помощью ButtonStyle

В реальном приложении один и тот же дизайн кнопки будет использоваться для сразу нескольких кнопок. Предположим, вы создаете три кнопки: Удалить, Изменить и Поделиться, которые все имеют одинаковый стиль кнопки, как этот:

e9c460cba5576797f36eecb9e4335e2e.png

Приготовьтесь сейчас будет большой фрагмент кода.

Вполне вероятно, что сейчас вы напишите примерно такое полотно:

struct ContentView: View {
	var body: some View {
		VStack {
			Button(action: {
				print("Нажал кнопку удаления")
			}) {
				Label(
					title: {
						Text("Удалить")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "trash")
							.font(.title)
					} )
				.frame(minWidth: 0, maxWidth: .infinity)
				.padding()
				.foregroundColor(.white)
				.background(LinearGradient(gradient: Gradient(colors: [Color.brightGreen, Color.darkGreen]),
										   startPoint: .top, endPoint: .bottom))
				.cornerRadius(40)
				.padding(.horizontal, 20)
				.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
			}
			Button(action: {
				print("Нажал кнопку Изменить")
			}) {
				Label(
					title: {
						Text("Изменить")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "square.and.pencil")
							.font(.title)
					} )
				.frame(minWidth: 0, maxWidth: .infinity)
				.padding()
				.foregroundColor(.white)
				.background(LinearGradient(gradient: Gradient(colors: [Color.brightGreen, Color.darkGreen]),
										   startPoint: .top, endPoint: .bottom))
				.cornerRadius(40)
				.padding(.horizontal, 20)
				.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
			}
			Button(action: {
				print("Нажал кнопку Поделиться")
			}) {
				Label(
					title: {
						Text("Поделиться")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "square.and.arrow.up")
							.font(.title)
					} )
				.frame(minWidth: 0, maxWidth: .infinity)
				.padding()
				.foregroundColor(.white)
				.background(LinearGradient(gradient: Gradient(colors: [Color.brightGreen, Color.darkGreen]),
										   startPoint: .top, endPoint: .bottom))
				.cornerRadius(40)
				.padding(.horizontal, 20)
				.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
			}
		}
	}
}

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

SwiftUI предоставляет протокол ButtonStyle, с помощью которого вы можете создать свой собственный стиль кнопки. Чтобы создать повторно используемый стиль для наших кнопок, создайте новую структуру с именем GradientBackgroundStyle, которая соответствует протоколу ButtonStyle. Вставьте следующий фрагмент кода:

struct GradientBackgroundStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View { configuration.label
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.foregroundColor(.white)
.background(LinearGradient(gradient: Gradient(colors: [Color.darkGreen, Color.brightGreen]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(40)
.padding(.horizontal, 20)
.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
} }

Протокол требует, чтобы мы предоставили реализацию функции makeBody, которая принимает параметр configuration. Параметр configuration включает свойство label, которое применяет модификаторы для изменения стиля кнопки. В приведенном выше коде мы применяем тот же набор модификаторов, который использовали ранее.

Как применить пользовательский стиль к кнопке? SwiftUI предоставляет модификатор .buttonStyle, с помощью которого можно применить стиль кнопки следующим образом:

			Button(action: {
				print("Нажал кнопку Поделиться")
			}) {
				Label(
					title: {
						Text("Поделиться")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "square.and.arrow.up")
							.font(.title)
					} )
			}
			.buttonStyle(GradientBackgroundStyle())

Таким образом мы сильно упростили наш код, сократили его и что самое важное мы сделали так — что если кто-то захочет поменять у этих кнопок стиль, то сделать это будет нужно лишь в одном месте в нашем случае в GradientBackgroundStyle.

В итоговом варианте ContentView будет выглядеть так

struct ContentView: View {
	var body: some View {
		VStack {
			Button(action: {
				print("Нажал кнопку удаления")
			}) {
				Label(
					title: {
						Text("Удалить")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "trash")
							.font(.title)
					} )
			}
			.buttonStyle(GradientBackgroundStyle())
			Button(action: {
				print("Нажал кнопку Изменить")
			}) {
				Label(
					title: {
						Text("Изменить")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "square.and.pencil")
							.font(.title)
					} )
			}
			.buttonStyle(GradientBackgroundStyle())
			Button(action: {
				print("Нажал кнопку Поделиться")
			}) {
				Label(
					title: {
						Text("Поделиться")
							.fontWeight(.semibold)
							.font(.title)
					}, icon: {
						Image(systemName: "square.and.arrow.up")
							.font(.title)
					} )
			}
			.buttonStyle(GradientBackgroundStyle())
		}
	}
}

Вы также можете определить, нажата ли кнопка, обратившись к свойству isPressed. Это позволит изменить стиль кнопки, когда пользователь касается ее. Например, предположим, мы хотим уменьшить кнопку немного, когда кто-то нажимает на нее. Для этого вы добавляете строку кода вроде этой:

.scaleEffect(configuration.isPressed ? 0.9 : 1.0)
struct GradientBackgroundStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View { configuration.label
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.foregroundColor(.white)
.background(LinearGradient(gradient: Gradient(colors: [Color.darkGreen, Color.brightGreen]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(40)
.padding(.horizontal, 20)
.shadow(color: .gray, radius: 20.0, x: 20, y: 10)
.scaleEffect(configuration.isPressed ? 0.9 : 1.0)
} }

5c202351c765cd91e27cd8754d1ba22f.png

Модификатор scaleEffect позволяет масштабировать кнопку (и вообще любую View). Чтобы увеличить размер кнопки, вы указываете значение больше 1.0. Чтобы уменьшить кнопку, введите значение меньше 1.0.

Таким образом, эта строка кода масштабирует кнопку в меньшую сторону (то есть 0.9), когда кнопка нажата, и возвращает ее к исходному размеру (то есть 1.0), когда пользователь отпускает палец. Запустите приложение, и вы увидите красивую анимацию при масштабировании кнопки. В этом сила SwiftUI. Вам не нужно писать дополнительных строк кода, и он поставляется с встроенной анимацией.

Давайте представим что вам нужно добиться эффекта — чтобы при нажатой кнопке она прокрутилась на 90 градусов, как можно реализовать это если пользоваться ButtonStyle и модификатором rotationEffect. Попробуйте сами, если не получится — результат как это можно сделать будет ниже.

2e5b748c6cf1f0aeedae43d1fe2b020e.png

Решение:

struct ContentView: View {
	var body: some View {
		VStack{
			Button(action: {
				
			}, label: {
				Image(systemName: "plus")
			})
			.buttonStyle(RotatingPlusButton())
		}
	}
}

struct RotatingPlusButton: ButtonStyle {
	func makeBody(configuration: Configuration) -> some View {
		configuration.label
			.padding()
			.background(Color.red)
			.foregroundStyle(.green)
			.font(.title)
			.fontWeight(.bold)
			.clipShape(Circle())
			.rotationEffect(configuration.isPressed ? .degrees(-90) : .degrees(0))
	}
}

Стилизация кнопки в iOS 15

Мы с вами изучили различные способы модификации нашей кнопки да и вообще разобрались с хорошим количеством модификаторов, но на само деле конкретно для кнопок есть свои собственные очень удобные модификаторы которые появились начиная с IOS 15, давайте на них посмотрим

struct ContentView: View {
	var body: some View {
		VStack{
			Button {
			} label: {
				Text("Привет IOS 15")
			}
			.tint(.purple) // можно использольвать вместо бэкграунд
			.buttonStyle(.borderedProminent) // меняет стиль кнопки, есть четыре стиля которые подготовили для нас в Apple, но также можно добавлять и свои собстенные кастомные
			.buttonBorderShape(.roundedRectangle(radius: 5)) // можно использовать вместо clipshape
			.controlSize(.large) // отвечает за размер кнопки, от совсем маленькой до очень большой
		}
	}
}

Я отставил для вас комментарии, что за что отвечает, попробуйте поиграть с параметрами этих модификаторов и посмотреть на что они способны. Помимо этих модификаторов в IOS 15 также появился такой аргумент кнопки как роль (role), нам предоставлено всего две роли на выбор, это .destructive и .cancel, в принципе они нужны просто для удобного и быстрого создания системных кнопок которые должны привлечь внимание пользователя, приведу пример обеих:

struct ContentView: View {
	var body: some View {
		VStack{
			Button("destructive", role: .destructive) {
				
			}
			.buttonStyle(.borderedProminent)
			Button("cancel", role: .cancel) {
				
			}
			.buttonStyle(.borderedProminent)
		}
	}
}

b2f650c436386881815552b6f56e23c7.png

Итоги

В этой части мы рассмотрели основы создания кнопок в SwiftUI. Кнопки играют ключевую роль в любом пользовательском интерфейсе приложения. Хорошо спроектированные кнопки не только делают ваш интерфейс более привлекательным, но и повышают пользовательский опыт от вашего приложения. Смешивая вместе символы SF, градиенты и анимации, вы легко можете создать стильные и полезные кнопки.

В следующей части мы наконец дойдем до темы State и Binding

Как и прежде подписывайтесь на мой телеграм канал — https://t.me/swiftexplorer

Буду рад вашим комментариям и лайкам!

Спасибо за прочтение!

© Habrahabr.ru