Hola, les saluda Luis y hoy les traigo otro tutorial.
Índice
¿Cómo implementar chips de elección de componentes de materiales con SwiftUI?
Chips UI es parte del diseño de materiales. Se utilizan ampliamente como componente de incorporación, incluida la página de inicio del medio. Primero vamos a entender qué se requiere para hacer una buena interfaz de usuario de chips.
Requisito
- Vista de fichas, que incluye imagen y texto
- Seleccionar y deseleccionar gesto
- Un contenedor de diseño automático, que puede diseñar chips
Vista de fabricación de fichas
La vista de fichas se puede construir de dos formas.
- Pila horizontal con texto e imagen.
- Usando la nueva etiqueta introducida (en iOS-14).
En esta demostración vamos a utilizar HStack ya que las etiquetas de SwiftUI todavía están en fase beta.
Fichas básicas
Salida
Contenedor de construcción para chips
Queremos diseñar vistas de chips como un flujo de texto (es decir, derecha – izquierda – Siguiente línea – repetir). Para lograr esto, necesitamos modificar la guía de diseño. También necesitaremos un lector de geometría para obtener el ancho y el alto disponibles.
import SwiftUI struct ChipsContent: View { @ObservedObject var viewModel = ChipsViewModel() var body: some View { var width = CGFloat.zero var height = CGFloat.zero return GeometryReader { geo in ZStack(alignment: .topLeading, content: { ForEach(viewModel.dataObject) { chipsData in //loop to render all chips Chips(systemImage: chipsData.systemImage, titleKey: chipsData.titleKey, isSelected: chipsData.isSelected) .padding(.all, 5) .alignmentGuide(.leading) { dimension in //update leading width for available width if (abs(width - dimension.width) > geo.size.width) { width = 0 height -= dimension.height } let result = width if chipsData.id == viewModel.dataObject.last!.id { width = 0 } else { width -= dimension.width } return result } .alignmentGuide(.top) { dimension in //update chips height origin wrt past chip let result = height if chipsData.id == viewModel.dataObject.last!.id { height = 0 } return result } } }) }.padding(.all, 10) } }
Gist de demostración completa
// // ContentView.swift // ios14-demo // // Created by Prafulla Singh on 23/6/20. // import SwiftUI struct ChipsDataModel: Identifiable { let id = UUID() @State var isSelected: Bool let systemImage: String let titleKey: LocalizedStringKey } class ChipsViewModel: ObservableObject { @Published var dataObject: [ChipsDataModel] = [ChipsDataModel.init(isSelected: false, systemImage: "pencil.circle", titleKey: "Pencil Circle")] func addChip() { dataObject.append(ChipsDataModel.init(isSelected: false, systemImage: "pencil.circle", titleKey: "Pencil")) } func removeLast() { guard dataObject.count != 0 else { return } dataObject.removeLast() } } struct ContentView: View { @StateObject var viewModel = ChipsViewModel() var body: some View { VStack { ScrollView { ChipsContent(viewModel: viewModel) } Spacer() HStack { Spacer() Button("Remove Chips") { withAnimation { viewModel.removeLast() } }.padding(.all, 40).accentColor(.red) Spacer() Button("Add Chips") { withAnimation { viewModel.addChip() } }.padding(.all, 40) Spacer() } } } } struct ChipsContent: View { @ObservedObject var viewModel = ChipsViewModel() var body: some View { var width = CGFloat.zero var height = CGFloat.zero return GeometryReader { geo in ZStack(alignment: .topLeading, content: { ForEach(viewModel.dataObject) { chipsData in Chips(systemImage: chipsData.systemImage, titleKey: chipsData.titleKey, isSelected: chipsData.isSelected) .padding(.all, 5) .alignmentGuide(.leading) { dimension in if (abs(width - dimension.width) > geo.size.width) { width = 0 height -= dimension.height } let result = width if chipsData.id == viewModel.dataObject.last!.id { width = 0 } else { width -= dimension.width } return result } .alignmentGuide(.top) { dimension in let result = height if chipsData.id == viewModel.dataObject.last!.id { height = 0 } return result } } }) }.padding(.all, 10) } } struct Chips: View { let systemImage: String let titleKey: LocalizedStringKey @State var isSelected: Bool var body: some View { HStack { Image.init(systemName: systemImage).font(.title3) Text(titleKey).font(.title3).lineLimit(1) }.padding(.all, 10) .foregroundColor(isSelected ? .white : .blue) .background(isSelected ? Color.blue : Color.white) .cornerRadius(40) .overlay( RoundedRectangle(cornerRadius: 40) .stroke(Color.blue, lineWidth: 1.5) ).onTapGesture { isSelected.toggle() } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Añadir comentario