Mercurial > public > lazybear
view LazyBear/Views/Onboarding/Helpers/AvatarCreator.swift @ 320:e828c2b0764c
Minor update SignUpView
author | Dennis Concepción Martín <66180929+denniscm190@users.noreply.github.com> |
---|---|
date | Sat, 27 Mar 2021 20:32:45 +0100 |
parents | 62d278295bb7 |
children |
line wrap: on
line source
// // AvatarCreator.swift // LazyBear // // Created by Dennis Concepción Martín on 26/3/21. // import SwiftUI enum AvatarComponent { case hair, eyes, mouth, body } struct AvatarCreator: View { var components = ["Hair", "Eyes", "Mouth", "Body"] @State private var selectedComponent = "Hair" @Environment(\.presentationMode) var avatarGeneratorPresentation @EnvironmentObject var firstAvatar: FirstAvatar var body: some View { NavigationView { VStack { Avatar() .shadow(color: Color.gray.opacity(0.2), radius: 10) .background( Circle() .foregroundColor(Color(firstAvatar.background)) ) .padding(.top) Picker("Select a component", selection: $selectedComponent) { ForEach(components, id: \.self) { Text($0) } } .pickerStyle(SegmentedPickerStyle()) .padding() Divider() ScrollView { if selectedComponent == "Hair" { showAvatar(component: .hair) } if selectedComponent == "Eyes" { showAvatar(component: .eyes) } if selectedComponent == "Mouth" { showAvatar(component: .mouth) } if selectedComponent == "Body" { showAvatar(component: .body) } } } .navigationTitle("Create your avatar") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button(action: { avatarGeneratorPresentation.wrappedValue.dismiss() }) { Text("Done") } } } } } private func showAvatar(component: AvatarComponent) -> AnyView { switch component { case .hair: return AnyView(ComponentView(component: .hair)) case .eyes: return AnyView(ComponentView(component: .eyes)) case .mouth: return AnyView(ComponentView(component: .mouth)) case .body: return AnyView(ComponentView(component: .body)) } } } struct AvatarCreator_Previews: PreviewProvider { static var previews: some View { AvatarCreator() .environmentObject(FirstAvatar()) } } struct ComponentView: View { @EnvironmentObject var firstAvatar: FirstAvatar @EnvironmentObject var hapticsManager: HapticsManager var component: AvatarComponent let columns = [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())] var body: some View { let (componentName, maxColors, maxComponents) = getComponentInfo() VStack { // COLOR SELECTOR if maxColors != nil { ScrollView(.horizontal, showsIndicators: false) { VStack { HStack(spacing: 20) { ForEach((1..<maxColors!)) { index in Button(action: { assignSelection(componentName: "\(componentName)Color", index: index, isColor: true) self.hapticsManager.complexSuccess() }) { ColorItem(component: component, componentName: componentName, index: index) } } } .padding(.leading) } } } // COMPONENT SELECTOR LazyVGrid(columns: columns, spacing: 20) { ForEach((1..<maxComponents)) { index in Button(action: { assignSelection(componentName: componentName, index: index, isColor: false) self.hapticsManager.complexSuccess() }) { ComponentItem(component: component, componentName: componentName, index: index) } } } } } // If I need to add more items, I'll need to make this better. Maybe reading directly // a JSON file instead of manually write down the number of items and names private func getComponentInfo() -> (String, Int?, Int) { switch component { case .body: let componentName = "body" let maxColors = 8 let maxComponents = 4 return (componentName, maxColors, maxComponents) case .eyes: let componentName = "eyes" let maxComponents = 6 return (componentName, nil, maxComponents) case .hair: let componentName = "hair" let maxColors = 8 let maxComponents = 20 return (componentName, maxColors, maxComponents) case .mouth: let componentName = "mouth" let maxComponents = 6 return (componentName, nil, maxComponents) } } private func assignSelection(componentName: String, index: Int, isColor: Bool) { switch component { case .body: if isColor { let colorName = "customColor\(index)" self.firstAvatar.bodyColor = colorName } else { self.firstAvatar.body = "\(componentName)\(index)" } case .eyes: self.firstAvatar.eyes = "\(componentName)\(index)" case .hair: if isColor { self.firstAvatar.hairColor = "\(componentName)\(index)" } else { self.firstAvatar.hair = "\(componentName)\(index)" } case .mouth: self.firstAvatar.mouth = "\(componentName)\(index)" } } } struct ColorItem: View { @EnvironmentObject var firstAvatar: FirstAvatar var component: AvatarComponent var componentName: String var index: Int var body: some View { let componentColor = "\(componentName)Color\(index)" Circle() .frame(width: 50, height: 50) .foregroundColor(component == .body ? Color("customColor\(index)"): Color(componentColor)) .padding(5) .background(firstAvatar.hairColor == componentColor ? Circle() .stroke(lineWidth: 3) .foregroundColor(.gray) : nil ) .padding(.vertical) } } struct ComponentItem: View { @EnvironmentObject var firstAvatar: FirstAvatar var component: AvatarComponent var componentName: String var index: Int var body: some View { PreviewAvatar(stringComponent: "\(componentName)\(index)", component: component) .frame(height: 100) .background(checkItemSelected(componentName: "\(componentName)\(index)") ? RoundedRectangle(cornerRadius: 20) .stroke(lineWidth: 3) .foregroundColor(.gray) : nil ) .padding(.vertical) } private func checkItemSelected(componentName: String) -> Bool { if component == .body { if firstAvatar.body == componentName { return true } } else if component == .eyes { if firstAvatar.eyes == componentName { return true } } else if component == .hair { if firstAvatar.hair == componentName { return true } } else if component == .mouth { if firstAvatar.mouth == componentName { return true } } return false } } struct PreviewAvatar: View { @EnvironmentObject var firstAvatar: FirstAvatar var stringComponent: String var component: AvatarComponent var body: some View { Image("head") .componentModifier() .overlay( ZStack { if component == .body { Image(stringComponent) .componentModifier() .colorMultiply(Color(firstAvatar.bodyColor)) } else { Image(firstAvatar.body) .componentModifier() .colorMultiply(Color(firstAvatar.bodyColor)) } if component == .hair { Image(stringComponent) .componentModifier() .colorMultiply(Color(firstAvatar.hairColor)) } else { Image(firstAvatar.hair) .componentModifier() .colorMultiply(Color(firstAvatar.hairColor)) } if component == .eyes { Image(stringComponent) .componentModifier() } else { Image(firstAvatar.eyes) .componentModifier() } Image(firstAvatar.nose) .componentModifier() if component == .mouth { Image(stringComponent) .componentModifier() } else { Image(firstAvatar.mouth) .componentModifier() } } ) } }