diff --git a/Rick-and-Morty/Rick And Morty.xcodeproj/project.pbxproj b/Rick-and-Morty/Rick And Morty.xcodeproj/project.pbxproj index dc2182e..615eeff 100644 --- a/Rick-and-Morty/Rick And Morty.xcodeproj/project.pbxproj +++ b/Rick-and-Morty/Rick And Morty.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 1711B39E26B1898100BE935B /* CharacterListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1711B39D26B1898100BE935B /* CharacterListView.swift */; }; 17588BAC26C1750B008ECC31 /* Character.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17588BAB26C1750B008ECC31 /* Character.swift */; }; + 17588BAF26C273BB008ECC31 /* CharacterCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17588BAE26C273BB008ECC31 /* CharacterCard.swift */; }; 17588BB226C2B126008ECC31 /* RickAndMortyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17588BB126C2B126008ECC31 /* RickAndMortyService.swift */; }; 179D2D7626C3D24B008E1B3A /* RickAndMortyServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179D2D7526C3D24B008E1B3A /* RickAndMortyServiceProtocol.swift */; }; B811686D1CFF1C9900301A0A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B811686C1CFF1C9900301A0A /* AppDelegate.swift */; }; @@ -30,6 +31,7 @@ /* Begin PBXFileReference section */ 1711B39D26B1898100BE935B /* CharacterListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterListView.swift; sourceTree = ""; }; 17588BAB26C1750B008ECC31 /* Character.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Character.swift; sourceTree = ""; }; + 17588BAE26C273BB008ECC31 /* CharacterCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCard.swift; sourceTree = ""; }; 17588BB126C2B126008ECC31 /* RickAndMortyService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RickAndMortyService.swift; sourceTree = ""; }; 179D2D7526C3D24B008E1B3A /* RickAndMortyServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RickAndMortyServiceProtocol.swift; sourceTree = ""; }; B81168691CFF1C9900301A0A /* Rick And Morty.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Rick And Morty.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -68,6 +70,13 @@ path = Model; sourceTree = ""; }; + 17588BAD26C273A2008ECC31 /* Views */ = { + isa = PBXGroup; + children = ( + 1711B39D26B1898100BE935B /* CharacterListView.swift */, + 17588BAE26C273BB008ECC31 /* CharacterCard.swift */, + ); + path = Views; 17588BB026C2B112008ECC31 /* Services */ = { isa = PBXGroup; children = ( @@ -98,10 +107,10 @@ B811686B1CFF1C9900301A0A /* Rick And Morty */ = { isa = PBXGroup; children = ( + 17588BAD26C273A2008ECC31 /* Views */, 17588BB026C2B112008ECC31 /* Services */, 17588BAA26C174FB008ECC31 /* Model */, B811686C1CFF1C9900301A0A /* AppDelegate.swift */, - 1711B39D26B1898100BE935B /* CharacterListView.swift */, B81168751CFF1C9900301A0A /* Assets.xcassets */, B81168771CFF1C9900301A0A /* LaunchScreen.storyboard */, B811687A1CFF1C9900301A0A /* Info.plist */, @@ -222,6 +231,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 17588BAF26C273BB008ECC31 /* CharacterCard.swift in Sources */, 17588BB226C2B126008ECC31 /* RickAndMortyService.swift in Sources */, 17588BAC26C1750B008ECC31 /* Character.swift in Sources */, 179D2D7626C3D24B008E1B3A /* RickAndMortyServiceProtocol.swift in Sources */, diff --git a/Rick-and-Morty/Rick And Morty/Assets.xcassets/morty-image.imageset/2.jpeg b/Rick-and-Morty/Rick And Morty/Assets.xcassets/morty-image.imageset/2.jpeg new file mode 100644 index 0000000..3863908 Binary files /dev/null and b/Rick-and-Morty/Rick And Morty/Assets.xcassets/morty-image.imageset/2.jpeg differ diff --git a/Rick-and-Morty/Rick And Morty/Assets.xcassets/morty-image.imageset/Contents.json b/Rick-and-Morty/Rick And Morty/Assets.xcassets/morty-image.imageset/Contents.json new file mode 100644 index 0000000..ca5656d --- /dev/null +++ b/Rick-and-Morty/Rick And Morty/Assets.xcassets/morty-image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "2.jpeg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Rick-and-Morty/Rick And Morty/Views/CharacterCard.swift b/Rick-and-Morty/Rick And Morty/Views/CharacterCard.swift new file mode 100644 index 0000000..47384f3 --- /dev/null +++ b/Rick-and-Morty/Rick And Morty/Views/CharacterCard.swift @@ -0,0 +1,94 @@ +// +// CharacterTileView.swift +// Rick And Morty +// +// Created by Scottie Gray on 2021-08-10. +// Copyright © 2021 Novoda. All rights reserved. +// + +import SwiftUI +import Foundation + +struct CharacterCardState { + var id: Int + var name: String + var image: UIImage + var isAlive: Bool + var species: String + var lastLocation: String + var firstEpisode: String +} + +private struct Constants { + let cornerRadius: CGFloat = 10 + let noSpacing: CGFloat = 0 + let VSpacing: CGFloat = 10 + let borderWidth: CGFloat = 0.25 + let cardHeight: CGFloat = 200 + let lastLocationCaption = "Last known location:" + let firstEpisodeCaption = "First seen in:" +} + +struct CharacterCard: View { + var characterCardState: CharacterCardState + private let constants: Constants = Constants() + + var body: some View { + HStack(alignment: .top) { + Image(uiImage: characterCardState.image) + .resizable() + .aspectRatio(contentMode: .fit) + + VStack(alignment: .leading, spacing: constants.VSpacing) { + VStack(alignment: .leading, spacing: constants.noSpacing) { + Text(characterCardState.name) + .font(.title) + .fontWeight(.black) + HStack { + Circle() + .foregroundColor(characterCardState.isAlive ? .green : .red) + .frame(width: 10, height: 10) + Text(characterCardState.isAlive ? "Alive - \(characterCardState.species)" : "Dead - \(characterCardState.species)") + } + } + + characterDetailsVStack(caption: constants.lastLocationCaption, text: characterCardState.lastLocation) + + characterDetailsVStack(caption: constants.firstEpisodeCaption, text: characterCardState.firstEpisode) + } + Spacer() + } + .cornerRadius(constants.cornerRadius) + .overlay( + RoundedRectangle(cornerRadius: constants.cornerRadius) + .stroke(Color(.lightGray), lineWidth: constants.borderWidth) + ) + .padding() + .frame(height: constants.cardHeight) + } + + func characterDetailsVStack(caption: String, text: String) -> some View { + return VStack(alignment: .leading, spacing: constants.noSpacing) { + Text(caption) + .font(.caption) + .foregroundColor(.secondary) + Text(text) + } + } +} + +struct CharacterTileView_Previews: PreviewProvider { + static var previews: some View { + Group { + VStack { + CharacterCard(characterCardState: CharacterCardState(id: 2, name: "Morty", image: UIImage(named: "morty-image")!, isAlive: true, species: "Human", lastLocation: "Earth", firstEpisode: "Episode 1")) + } + .preferredColorScheme(.light) + VStack { + CharacterCard(characterCardState: CharacterCardState(id: 2, name: "Morty", image: UIImage(named: "morty-image")!, isAlive: true, species: "Human", lastLocation: "Earth", firstEpisode: "Episode 1")) + } + .preferredColorScheme(.dark) + + } + } +} diff --git a/Rick-and-Morty/Rick And Morty/CharacterListView.swift b/Rick-and-Morty/Rick And Morty/Views/CharacterListView.swift similarity index 100% rename from Rick-and-Morty/Rick And Morty/CharacterListView.swift rename to Rick-and-Morty/Rick And Morty/Views/CharacterListView.swift