Complete Challenge 2

> Change project 5 (Word Scramble) so that words towards the bottom of the list slide in from the right as you scroll. Ideally at least the top 8-10 words should all be positioned normally, but after that they should be offset increasingly to the right.
This commit is contained in:
CypherPoet 2020-01-25 05:29:49 -06:00
parent 98ce158a31
commit 8154a404de
3 changed files with 86 additions and 31 deletions

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
F331C42E23DC5D400061925E /* GameView+UsedWordListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F331C42D23DC5D400061925E /* GameView+UsedWordListItem.swift */; };
F3660D9B235EC5B000FAF849 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3660D9A235EC5B000FAF849 /* AppDelegate.swift */; };
F3660D9D235EC5B000FAF849 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3660D9C235EC5B000FAF849 /* SceneDelegate.swift */; };
F3660DA1235EC5B100FAF849 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F3660DA0235EC5B100FAF849 /* Assets.xcassets */; };
@ -21,6 +22,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
F331C42D23DC5D400061925E /* GameView+UsedWordListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GameView+UsedWordListItem.swift"; sourceTree = "<group>"; };
F3660D97235EC5B000FAF849 /* WordScramble.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WordScramble.app; sourceTree = BUILT_PRODUCTS_DIR; };
F3660D9A235EC5B000FAF849 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F3660D9C235EC5B000FAF849 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@ -125,6 +127,7 @@
F367BF232360873600FDEB0C /* GameViewModel.swift */,
F367BF2523608A4500FDEB0C /* GameContainerView.swift */,
F367BF2723608B1600FDEB0C /* GameView.swift */,
F331C42D23DC5D400061925E /* GameView+UsedWordListItem.swift */,
);
path = Game;
sourceTree = "<group>";
@ -212,6 +215,7 @@
files = (
F3660DB5235EC9D000FAF849 /* Bundle+DecodeFromFileName.swift in Sources */,
F3660D9B235EC5B000FAF849 /* AppDelegate.swift in Sources */,
F331C42E23DC5D400061925E /* GameView+UsedWordListItem.swift in Sources */,
F367BF242360873600FDEB0C /* GameViewModel.swift in Sources */,
F3660D9D235EC5B000FAF849 /* SceneDelegate.swift in Sources */,
F367BF2A23609FC400FDEB0C /* Appearance.swift in Sources */,

View File

@ -0,0 +1,55 @@
//
// GameView+UsedWordListItem.swift
// WordScramble
//
// Created by CypherPoet on 1/25/20.
//
//
import SwiftUI
extension GameView {
struct UsedWordListItem {
let word: String
let listGeometry: GeometryProxy
}
}
// MARK: - View
extension GameView.UsedWordListItem: View {
var body: some View {
GeometryReader { geometry in
HStack {
Text(self.word)
Spacer()
Image(systemName: "\(self.word.count).circle")
.imageScale(.large)
}
.offset(x: self.xOffset(forItemWith: geometry))
.animation(.easeOut(duration: 0.4))
}
.accessibilityElement(children: .ignore)
.accessibility(label: Text("\(word). \(word.count) letters."))
}
}
// MARK: - Private Helpers
extension GameView.UsedWordListItem {
func xOffset(forItemWith geometry: GeometryProxy) -> CGFloat {
let listWidth = listGeometry.size.width
let listHeight = listGeometry.size.height
let listStartY = listGeometry.frame(in: .global).minY
let itemGlobalEndY = geometry.frame(in: .global).maxY
let itemHeight = geometry.size.height
let yPercentageInList = (itemGlobalEndY - listStartY - (itemHeight * 2)) / listHeight
return yPercentageInList > 1.0 ? listWidth : 0.0
}
}

View File

@ -9,6 +9,11 @@
import SwiftUI
enum CoordinateSpaceName {
static let gameViewList = "Game View List"
}
struct GameView: View {
@ObservedObject var viewModel: GameViewModel
}
@ -37,27 +42,33 @@ extension GameView {
text: $viewModel.currentGuess,
onCommit: viewModel.checkNewWord
)
.textFieldStyle(RoundedBorderTextFieldStyle())
.autocapitalization(.none)
.disableAutocorrection(true)
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
.autocapitalization(.none)
.disableAutocorrection(true)
.padding()
Form {
Section(
header: HStack {
Text("Used Words")
Spacer()
Text("Current Score: \(viewModel.currentScore)")
}
.font(.headline)
.padding()
) {
List(viewModel.usedWords, id: \.self) { word in
UsedWordListItem(word: word)
GeometryReader { geometry in
List {
Section(
header: HStack {
Text("Used Words")
Spacer()
Text("Current Score: \(self.viewModel.currentScore)")
}
.font(.headline)
.padding()
) {
ForEach(self.viewModel.usedWords, id: \.self) { word in
UsedWordListItem(
word: word,
listGeometry: geometry
)
}
}
}
}
.coordinateSpace(name: CoordinateSpaceName.gameViewList)
}
.navigationBarTitle("Anagrams")
.navigationBarItems(leading: restartButton)
@ -93,18 +104,3 @@ struct GameView_Previews: PreviewProvider {
}
private struct UsedWordListItem: View {
let word: String
var body: some View {
HStack {
Text(word)
Spacer()
Image(systemName: "\(word.count).circle")
.imageScale(.large)
}
.accessibilityElement(children: .ignore)
.accessibility(label: Text("\(word). \(word.count) letters."))
}
}