-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from ehdrhelr/feature/iOS/game-play-view
[iOS] 로그인 화면 + 게임 선택 화면 + 게임 진행 화면
- Loading branch information
Showing
28 changed files
with
1,787 additions
and
39 deletions.
There are no files selected for viewing
193 changes: 179 additions & 14 deletions
193
iOS/baseball-game/baseball-game.xcodeproj/project.pbxproj
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file modified
BIN
+121 KB
(580%)
....xcodeproj/project.xcworkspace/xcuserdata/song.xcuserdatad/UserInterfaceState.xcuserstate
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 121 additions & 6 deletions
127
iOS/baseball-game/baseball-game/Base.lproj/Main.storyboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,139 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> | ||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="bc6-zR-OBT"> | ||
<device id="retina6_1" orientation="portrait" appearance="light"/> | ||
<dependencies> | ||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> | ||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/> | ||
<capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
<capability name="System colors in document resources" minToolsVersion="11.0"/> | ||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
</dependencies> | ||
<scenes> | ||
<!--View Controller--> | ||
<!--Login View Controller--> | ||
<scene sceneID="vgB-wA-gkL"> | ||
<objects> | ||
<viewController storyboardIdentifier="LoginViewController" id="acG-MO-tPJ" customClass="LoginViewController" customModule="baseball_game" customModuleProvider="target" sceneMemberID="viewController"> | ||
<view key="view" contentMode="scaleToFill" id="Rbm-Wg-nXP"> | ||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/> | ||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
<subviews> | ||
<textField opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="ump-1U-kn2"> | ||
<rect key="frame" x="106" y="287" width="202" height="34"/> | ||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> | ||
<fontDescription key="fontDescription" type="system" pointSize="14"/> | ||
<textInputTraits key="textInputTraits"/> | ||
</textField> | ||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="로그인 해보시지" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zsQ-El-PkC"> | ||
<rect key="frame" x="82" y="87" width="250" height="87"/> | ||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> | ||
<fontDescription key="fontDescription" type="boldSystem" pointSize="26"/> | ||
<nil key="textColor"/> | ||
<nil key="highlightedColor"/> | ||
</label> | ||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fnZ-6B-4DN"> | ||
<rect key="frame" x="161" y="358" width="92" height="66"/> | ||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> | ||
<fontDescription key="fontDescription" type="system" pointSize="17"/> | ||
<state key="normal" title="확인"/> | ||
<connections> | ||
<action selector="okButtonTouched:" destination="acG-MO-tPJ" eventType="touchUpInside" id="jde-2f-lwj"/> | ||
</connections> | ||
</button> | ||
</subviews> | ||
<viewLayoutGuide key="safeArea" id="usz-km-bvy"/> | ||
<color key="backgroundColor" systemColor="systemGray6Color"/> | ||
</view> | ||
<navigationItem key="navigationItem" id="aMp-h1-3sO"/> | ||
<connections> | ||
<outlet property="IDTextField" destination="ump-1U-kn2" id="0Xr-ng-afF"/> | ||
</connections> | ||
</viewController> | ||
<placeholder placeholderIdentifier="IBFirstResponder" id="XGK-4h-xgL" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> | ||
</objects> | ||
<point key="canvasLocation" x="84.057971014492765" y="114.50892857142857"/> | ||
</scene> | ||
<!--Selection View Controller--> | ||
<scene sceneID="tne-QT-ifu"> | ||
<objects> | ||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController"> | ||
<viewController storyboardIdentifier="SelectionViewController" id="BYZ-38-t0r" customClass="SelectionViewController" customModule="baseball_game" customModuleProvider="target" sceneMemberID="viewController"> | ||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> | ||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/> | ||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/> | ||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> | ||
<subviews> | ||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TEj-De-JFw"> | ||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/> | ||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
</view> | ||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="게임 목록" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZaK-Yz-YEw"> | ||
<rect key="frame" x="146.5" y="74" width="121.5" height="39.5"/> | ||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="33"/> | ||
<color key="textColor" systemColor="systemGray5Color"/> | ||
<nil key="highlightedColor"/> | ||
</label> | ||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="120" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Qom-Qz-GeO"> | ||
<rect key="frame" x="10" y="158.5" width="394" height="658.5"/> | ||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
<prototypes> | ||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" rowHeight="120" id="pQd-GF-lQg"> | ||
<rect key="frame" x="0.0" y="24.5" width="394" height="120"/> | ||
<autoresizingMask key="autoresizingMask"/> | ||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pQd-GF-lQg" id="l8i-ge-Lwi"> | ||
<rect key="frame" x="0.0" y="0.0" width="394" height="120"/> | ||
<autoresizingMask key="autoresizingMask"/> | ||
</tableViewCellContentView> | ||
</tableViewCell> | ||
</prototypes> | ||
</tableView> | ||
</subviews> | ||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> | ||
<color key="backgroundColor" red="0.040723347715822478" green="0.09781032958678347" blue="0.18880824850063127" alpha="1" colorSpace="custom" customColorSpace="displayP3"/> | ||
<constraints> | ||
<constraint firstItem="ZaK-Yz-YEw" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="30" id="Fs8-Bi-8jH"/> | ||
<constraint firstItem="Qom-Qz-GeO" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="10" id="Khu-x6-Cnc"/> | ||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="Qom-Qz-GeO" secondAttribute="trailing" constant="10" id="KvQ-2G-981"/> | ||
<constraint firstItem="Qom-Qz-GeO" firstAttribute="top" secondItem="ZaK-Yz-YEw" secondAttribute="bottom" constant="45" id="SgB-QY-JC0"/> | ||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="Qom-Qz-GeO" secondAttribute="bottom" constant="45" id="THc-gh-Veh"/> | ||
<constraint firstItem="ZaK-Yz-YEw" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="X5R-nH-yDi"/> | ||
<constraint firstItem="TEj-De-JFw" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="iaF-GG-hhr"/> | ||
<constraint firstAttribute="bottom" secondItem="TEj-De-JFw" secondAttribute="bottom" id="jha-K5-GAK"/> | ||
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="TEj-De-JFw" secondAttribute="trailing" id="pKw-q4-jRU"/> | ||
<constraint firstItem="TEj-De-JFw" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" id="sdR-iG-9cO"/> | ||
</constraints> | ||
</view> | ||
<navigationItem key="navigationItem" id="pCT-Ol-cD7"/> | ||
<connections> | ||
<outlet property="backgroundView" destination="TEj-De-JFw" id="msw-kk-e3V"/> | ||
<outlet property="gameListTableView" destination="Qom-Qz-GeO" id="3md-l4-Ihh"/> | ||
</connections> | ||
</viewController> | ||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> | ||
</objects> | ||
<point key="canvasLocation" x="1042.0289855072465" y="114.50892857142857"/> | ||
</scene> | ||
<!--Navigation Controller--> | ||
<scene sceneID="V5N-W2-hhL"> | ||
<objects> | ||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="bc6-zR-OBT" sceneMemberID="viewController"> | ||
<toolbarItems/> | ||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="CfT-9w-1yW"> | ||
<rect key="frame" x="0.0" y="44" width="414" height="44"/> | ||
<autoresizingMask key="autoresizingMask"/> | ||
</navigationBar> | ||
<nil name="viewControllers"/> | ||
<connections> | ||
<segue destination="acG-MO-tPJ" kind="relationship" relationship="rootViewController" id="5nd-sF-m8A"/> | ||
</connections> | ||
</navigationController> | ||
<placeholder placeholderIdentifier="IBFirstResponder" id="iIS-6P-iFA" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> | ||
</objects> | ||
<point key="canvasLocation" x="-826.08695652173924" y="114.50892857142857"/> | ||
</scene> | ||
</scenes> | ||
<resources> | ||
<systemColor name="systemGray5Color"> | ||
<color red="0.89803921568627454" green="0.89803921568627454" blue="0.91764705882352937" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||
</systemColor> | ||
<systemColor name="systemGray6Color"> | ||
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||
</systemColor> | ||
</resources> | ||
</document> |
119 changes: 119 additions & 0 deletions
119
iOS/baseball-game/baseball-game/GamePlay/GamePlayViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// | ||
// ViewController.swift | ||
// baseball-game | ||
// | ||
// Created by Song on 2021/05/03. | ||
// | ||
|
||
import UIKit | ||
import Combine | ||
|
||
class GamePlayViewController: UIViewController { | ||
|
||
@IBOutlet weak var pitchListTableView: UITableView! | ||
@IBOutlet weak var pitchButton: UIButton! | ||
@IBOutlet weak var teamScoreView: TeamScoreView! | ||
@IBOutlet weak var inningLabel: UILabel! | ||
@IBOutlet weak var turnLabel: UILabel! | ||
@IBOutlet weak var pitcherInfoView: PitcherInfoView! | ||
@IBOutlet weak var batterInfoView: PitcherInfoView! | ||
|
||
enum ViewID { | ||
static let storyboard = "GamePlay" | ||
static let controller = "gamePlay" | ||
static let segue = "selectPitcher" | ||
static let cell = "pitchListCell" | ||
} | ||
|
||
private var gamePlayViewModel: GamePlayViewModel! | ||
private var dataSource: UITableViewDiffableDataSource<Int, Pitch>! | ||
|
||
private let isUserHomeSide = true | ||
private var cancelBag = Set<AnyCancellable>() | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
self.gamePlayViewModel = GamePlayViewModel(isUserHomeSide) | ||
self.pitchButton.isHidden = true | ||
gamePlayViewModel.requestGame() | ||
configureDataSource() | ||
bind() | ||
} | ||
|
||
private func bind() { | ||
gamePlayViewModel.$gameManager | ||
.receive(on: DispatchQueue.main) | ||
.sink { [weak self] gameManager in | ||
guard let gameManager = gameManager else { return } | ||
self?.updateViews(with: gameManager) | ||
} | ||
.store(in: &cancelBag) | ||
|
||
gamePlayViewModel.$pitches | ||
.receive(on: DispatchQueue.main) | ||
.sink { [weak self] pitches in | ||
guard let pitches = pitches else { return } | ||
self?.createSnapshot(from: pitches) | ||
} | ||
.store(in: &cancelBag) | ||
|
||
gamePlayViewModel.$error | ||
.receive(on: DispatchQueue.main) | ||
.sink { error in | ||
guard let error = error else { return } | ||
print(error) ///사용자에게 에러 표시하는 부분 미구현 | ||
}.store(in: &cancelBag) | ||
} | ||
|
||
@IBAction func pitcherChangeTouched(_ sender: Any) { | ||
performSegue(withIdentifier: ViewID.segue, sender: nil) | ||
} | ||
|
||
private func updateViews(with gameManager: GameManagable) { | ||
teamScoreView.updateTeamNames(from: gameManager.teams()) | ||
teamScoreView.updateScores(from: gameManager.scores()) | ||
inningLabel.text = gameManager.inning() | ||
pitcherInfoView.updateLabels(from: gameManager.pitcher()) | ||
batterInfoView.updateLabels(from: gameManager.batter()) | ||
|
||
guard let isUserDefense = gameManager.isUserDefense() else { return } | ||
|
||
if isUserDefense { | ||
self.pitchButton.isHidden = false | ||
turnLabel.text = GameManager.Role.defense | ||
pitcherInfoView.highlight() | ||
batterInfoView.unhighlight() | ||
} else { | ||
self.pitchButton.isHidden = true | ||
turnLabel.text = GameManager.Role.offense | ||
pitcherInfoView.unhighlight() | ||
batterInfoView.highlight() | ||
} | ||
} | ||
} | ||
|
||
extension GamePlayViewController { | ||
|
||
private func configureDataSource() { | ||
self.dataSource = UITableViewDiffableDataSource.init(tableView: pitchListTableView) { | ||
(tableView, indexPath, pitch) -> UITableViewCell in | ||
|
||
guard let cell = self.pitchListTableView.dequeueReusableCell(withIdentifier: ViewID.cell) as? PitchListTableViewCell else { | ||
return PitchListTableViewCell() | ||
} | ||
|
||
let index = indexPath.row | ||
cell.updateLabels(count: index, result: pitch.result, log: pitch.log) | ||
|
||
return cell | ||
} | ||
} | ||
|
||
private func createSnapshot(from pitches: [Pitch]) { | ||
var snapshot = NSDiffableDataSourceSnapshot<Int, Pitch>() | ||
|
||
snapshot.appendSections([0]) | ||
snapshot.appendItems(pitches, toSection: 0) | ||
self.dataSource.apply(snapshot) | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
iOS/baseball-game/baseball-game/GamePlay/Model/GameManagable.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// GameManagable.swift | ||
// baseball-game | ||
// | ||
// Created by Song on 2021/05/06. | ||
// | ||
|
||
import Foundation | ||
|
||
protocol GameManagable { | ||
|
||
func teams() -> [String: String] | ||
|
||
func scores() -> [String: Int] | ||
|
||
func inning() -> String | ||
|
||
func pitcher() -> Player | ||
|
||
func batter() -> Player | ||
|
||
func isUserDefense() -> Bool? | ||
|
||
} |
Oops, something went wrong.