Продолжаем серию публикаций, посвященных нововведениям в SwiftUI для Swift 5.5. В этой подборке поговорим о том, как кастомизировать разделители строк для списков, про рендеринг Markdown в тексте и про выделение текста. Так же рассмотрим новые бейджи для TabView и новые стили для отображения кнопок. А так же поработаем с кнопкой, отвечающей за запрос местоположения пользователя.
SwiftUI 3.0. List. Кастомизация разделителя для строк списков.
В SwiftUI для iOS 15 появилось два новых модификатора, позволяющих управлять внешним видом разделителя для строк списков. Чтобы скрыть разделители используется модификатор listRowSeparator():
List(1..<100) { index in
Text("Row \\(index)")
.listRowSeparator(.hidden)
}
А модификатор listRowSeparatorTint() позволяет настроить цвет разделителей:
List(1..<100) { index in
Text("Row \\(index)")
.listRowSeparatorTint(.red)
}
Данные модификаторы также можно использовать для отдельных строк списка.
SwiftUI 3.0. Отображение бейджей в TabView и строках List
В SwiftUI 3.0 появился новый модификатор badge(), который позволяет отображать бейджи (красные уведомления о непрочитанных сообщениях) на иконках вкладок TabView:
TabView {
Text("Your home screen here")
.tabItem {
Label("Home", systemImage: "house")
}
.badge(5)
}
Бейджи также можно отображать и для строк списка, подставляя в параметр модификатора badge() не число, а текст, который автоматически выравнивается по правому краю и имеет серый цвет:
List {
Text("Wi-Fi")
.badge("LAN Solo")
Text("Bluetooth")
.badge("On")
}
SwiftUI 3.0. Отображение содержимого Markdown в тексте
В SwiftUI 3.0 появилась встроенная поддержка рендеринга текста, написанного с использованием Markdown:
VStack {
Text("This is regular text.")
Text("* This is **bold** text, this is *italic* text, and this is ***bold, italic*** text.")
Text("~~A strikethrough example~~")
Text("`Monospaced works too`")
Text("Visit Apple: [click here](https://apple.com)")
}
Рендеринг изображений пока не поддерживается.
SwiftUI 3.0. Выделение текста
Такой тип данных, как Text в SwiftUI является статичным и по умолчанию его нельзя выделить и скопировать в буфер. Начиная с версии iOS 15 это можно исправить, если вы примените для текста такой модификатор, как textSelection() с со значением .enabled:
VStack(spacing: 50) {
Text("You can't touch this")
Text("Break it down!")
.textSelection(.enabled)
}
В приведенном примере первую строку текста выделить не получится, тогда как вторую можно будет выделить и скопировать в буфер обмена:
На данный момент нельзя выделить определенную часть текста. При удержании пальца на строке выйдет меню, позволяющее скопировать весь текст целиком без возможности выбрать отдельные слова.
Параметр textSelection() можно применять для любой группы представлений и он автоматически сделает весь текст доступным для выбора внутри этой группы. Например, мы могли бы сделать оба текстовых представления в нашем предыдущем примере доступными для выбора, переместив модификатор в стек:
VStack(spacing: 50) {
Text("You can't touch this")
Text("Break it down!")
}
.textSelection(.enabled)
textSelection() можно применить и к списку. В этом случае текстовые строки списка будут доступны для выделения:
List(0..<100) { index in
Text("Row \(index)")
}
.textSelection(.enabled)
Чтобы вызвать контекстное меню из текста строки нужно нажать и удерживать палец непосредственно на самом тексте в строке.
SwiftUI 3.0. Новые стили кнопок
В SwiftUI добавили различные стили для кнопок, которые можно устанавливать модификаторов buttonStyle() и tint(). Рассмотрим базовый шаблон для обычной кнопки:
Button("Buy: $0.99") {
print("Buying…")
}
.buttonStyle(.bordered)
Чтобы выделить кнопку и сделать её более яркой можно использовать параметр .borderedProminent:
Button("Buy: $0.99") {
print("Buying for $0.99")
}
.buttonStyle(.borderedProminent)
Важно: не стоит использовать большое количество таких ярких кнопок, так как это не является хорошей практикой для пользовательского интерфейса.
Цвет кнопок можно изменять при помощи модификатора tint():
Button("Submit") {
print("Submitting…")
}
.tint(.indigo)
.buttonStyle(.borderedProminent)
Кроме того для кнопок можно применять роли:
Button("Delete", role: .destructive) {
print("Deleting…")
}
.buttonStyle(.borderedProminent)
SwiftUI 3.0. Использование кнопки LocationButton для определения местоположения пользователя
В SwiftUI появилась специальная кнопка LocationButton, позволяющая отобразить стандартный запрос для определения местоположения пользователя. К сожалению никакой логики по получению непосредственно самого местоположения в этом представлении не реализовано. Все что оно представляет, так это форму запроса и ничего более.
Для работы с представлением необходимо импортировать два фреймворка: для чтения местоположения и для отображения кнопки.
import CoreLocation
import CoreLocationUI
Затем нам надо подписать класс, отвечающий за работу с локацией под протокол ObservableObject и CLLocationManagerDelegate. Для создания запроса о местоположении нужно вызвать метод requestLocation() из экземпляра класса CLLocationManager. После чего объект этого запроса нужно поместить в представление LocationButton. Это если вкратце, теперь давай взглянем на то, как это может выглядеть на практике:
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
let manager = CLLocationManager()
@Published var location: CLLocationCoordinate2D?
override init() {
super.init()
manager.delegate = self
}
func requestLocation() {
manager.requestLocation()
}
// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
location = locations.first?.coordinate
}
}
struct ContentView: View {
@StateObject var locationManager = LocationManager()
var body: some View {
VStack {
if let location = locationManager.location {
Text("Your location: \(location.latitude), \(location.longitude)")
}
LocationButton {
locationManager.requestLocation()
}
.frame(height: 44)
.padding()
}
}
}
Apple предоставляет несколько вариантов дизайна для кнопки, активируемой путем передачи в инициализатор одного из параметров:
В статье использованы материалы из:
- https://www.hackingwithswift.com/quick-start/swiftui/how-to-adjust-list-row-separator-visibility-and-color
- https://www.hackingwithswift.com/quick-start/swiftui/how-to-render-markdown-content-in-text
- https://www.hackingwithswift.com/quick-start/swiftui/how-to-add-a-badge-to-tabview-items-and-list-rows
- https://www.hackingwithswift.com/quick-start/swiftui/how-to-read-the-users-location-using-locationbutton
- https://www.hackingwithswift.com/quick-start/swiftui/how-to-let-users-select-text
- https://www.hackingwithswift.com/quick-start/swiftui/how-to-get-bordered-buttons-that-stand-out