Skip to content

Commit

Permalink
Create settings page (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
Khislatjon authored May 12, 2024
1 parent d8fdb12 commit dc0c160
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 24 deletions.
10 changes: 10 additions & 0 deletions Chess.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
01642A99251A89B400039186 /* BoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01642A98251A89B400039186 /* BoardView.swift */; };
01642A9B251A9CA600039186 /* Board.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01642A9A251A9CA600039186 /* Board.swift */; };
01C5BA58251CC44D00A53B56 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C5BA57251CC44D00A53B56 /* Game.swift */; };
0E6FCBCB2BED015E00193845 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6FCBCA2BED015E00193845 /* SettingsViewController.swift */; };
0E6FCBCD2BED202900193845 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6FCBCC2BED202900193845 /* Storage.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -32,6 +34,8 @@
01642A98251A89B400039186 /* BoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoardView.swift; sourceTree = "<group>"; };
01642A9A251A9CA600039186 /* Board.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Board.swift; sourceTree = "<group>"; };
01C5BA57251CC44D00A53B56 /* Game.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = "<group>"; };
0E6FCBCA2BED015E00193845 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
0E6FCBCC2BED202900193845 /* Storage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -71,6 +75,8 @@
01642A98251A89B400039186 /* BoardView.swift */,
01642A88251A882400039186 /* ViewController.swift */,
013499942904183F00CED6BE /* UIView+Jiggle.swift */,
0E6FCBCA2BED015E00193845 /* SettingsViewController.swift */,
0E6FCBCC2BED202900193845 /* Storage.swift */,
01642A8A251A882400039186 /* Main.storyboard */,
01642A8D251A882800039186 /* Assets.xcassets */,
01642A8F251A882800039186 /* LaunchScreen.storyboard */,
Expand Down Expand Up @@ -178,8 +184,10 @@
01C5BA58251CC44D00A53B56 /* Game.swift in Sources */,
01642A99251A89B400039186 /* BoardView.swift in Sources */,
01642A9B251A9CA600039186 /* Board.swift in Sources */,
0E6FCBCD2BED202900193845 /* Storage.swift in Sources */,
01642A85251A882400039186 /* AppDelegate.swift in Sources */,
01642A87251A882400039186 /* SceneDelegate.swift in Sources */,
0E6FCBCB2BED015E00193845 /* SettingsViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -328,6 +336,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 8VQKF583ED;
INFOPLIST_FILE = Chess/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -346,6 +355,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 8VQKF583ED;
INFOPLIST_FILE = Chess/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
47 changes: 26 additions & 21 deletions Chess/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</connections>
</segmentedControl>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="White" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BMt-yP-W2a">
<rect key="frame" x="178" y="144" width="45" height="21"/>
<rect key="frame" x="178.5" y="144.5" width="44.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
Expand All @@ -51,25 +51,33 @@
</connections>
</segmentedControl>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Black" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hkk-4j-vt4">
<rect key="frame" x="181" y="195" width="42" height="21"/>
<rect key="frame" x="181.5" y="195.5" width="41.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Eh-VO-35h">
<rect key="frame" x="141" y="705" width="132" height="38"/>
<inset key="contentEdgeInsets" minX="20" minY="10" maxX="20" maxY="10"/>
<state key="normal" title="Restart game"/>
<connections>
<action selector="resetGame" destination="BYZ-38-t0r" eventType="touchUpInside" id="D1t-IJ-d9g"/>
</connections>
</button>
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SeC-6h-Qir">
<rect key="frame" x="8" y="743" width="398" height="80"/>
<constraints>
<constraint firstAttribute="height" constant="80" id="Px5-Qo-WvQ"/>
</constraints>
</pickerView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="bottom" translatesAutoresizingMaskIntoConstraints="NO" id="khe-up-ENp">
<rect key="frame" x="75" y="705" width="264" height="38"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Eh-VO-35h">
<rect key="frame" x="0.0" y="0.0" width="132" height="38"/>
<inset key="contentEdgeInsets" minX="20" minY="10" maxX="20" maxY="10"/>
<state key="normal" title="Restart game"/>
<connections>
<action selector="resetGame" destination="BYZ-38-t0r" eventType="touchUpInside" id="D1t-IJ-d9g"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PR8-7h-n5j">
<rect key="frame" x="132" y="0.0" width="132" height="38"/>
<inset key="contentEdgeInsets" minX="20" minY="10" maxX="20" maxY="10"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Settings"/>
<connections>
<action selector="settings" destination="BYZ-38-t0r" eventType="touchUpInside" id="RWA-Dq-Pxa"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
Expand All @@ -78,16 +86,13 @@
<constraint firstItem="i6L-Bp-k19" firstAttribute="top" secondItem="wW6-Bz-2dd" secondAttribute="bottom" constant="20" id="0lc-vc-hU1"/>
<constraint firstItem="wW6-Bz-2dd" firstAttribute="top" secondItem="XI6-5z-ZD0" secondAttribute="bottom" constant="20" id="4r8-PR-mzl"/>
<constraint firstItem="i6L-Bp-k19" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="4uP-K2-bNo"/>
<constraint firstItem="0Eh-VO-35h" firstAttribute="top" secondItem="i6L-Bp-k19" secondAttribute="bottom" constant="50" id="5LE-jt-33p"/>
<constraint firstItem="SeC-6h-Qir" firstAttribute="top" secondItem="0Eh-VO-35h" secondAttribute="bottom" id="67w-kr-jOF"/>
<constraint firstItem="SeC-6h-Qir" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" constant="-8" id="6ND-sR-KKo"/>
<constraint firstItem="XI6-5z-ZD0" firstAttribute="leading" secondItem="BMt-yP-W2a" secondAttribute="trailing" constant="10" id="Cnl-fw-vvX"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="wW6-Bz-2dd" secondAttribute="trailing" constant="20" id="DoV-KX-7x0"/>
<constraint firstItem="BMt-yP-W2a" firstAttribute="centerY" secondItem="XI6-5z-ZD0" secondAttribute="centerY" id="H4b-tt-Fp6"/>
<constraint firstItem="0Eh-VO-35h" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="I2w-Km-KZV"/>
<constraint firstItem="i6L-Bp-k19" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="R8A-d7-K1j"/>
<constraint firstItem="SeC-6h-Qir" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="8" id="cP5-zZ-eYD"/>
<constraint firstItem="khe-up-ENp" firstAttribute="top" secondItem="i6L-Bp-k19" secondAttribute="bottom" constant="50" id="dCa-WX-WrC"/>
<constraint firstItem="i6L-Bp-k19" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="lDf-dw-y7R"/>
<constraint firstItem="khe-up-ENp" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="o3T-VW-Jgv"/>
<constraint firstItem="Hkk-4j-vt4" firstAttribute="centerY" secondItem="wW6-Bz-2dd" secondAttribute="centerY" id="pNF-sK-ted"/>
<constraint firstItem="i6L-Bp-k19" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="qZ6-M8-Iix"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="XI6-5z-ZD0" secondAttribute="trailing" constant="20" id="wLI-3U-Dfn"/>
Expand Down
2 changes: 1 addition & 1 deletion Chess/BoardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class BoardView: UIView {
private(set) var pieces: [String: UIImageView] = [:]
private(set) var moveIndicators: [UIView] = []

var theme: Theme = .classic {
var theme: Theme = Theme(rawValue: Storage.shared.boardTheme ?? "") ?? .classic {
didSet { updateTheme() }
}

Expand Down
79 changes: 79 additions & 0 deletions Chess/SettingsViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//
// SettingsViewController.swift
// Chess
//
// Created by Khislatjon Valijonov on 09/05/24.
// Copyright © 2024 Nick Lockwood. All rights reserved.
//

import UIKit

class SettingsViewController: UIViewController {
let tableView = UITableView(frame: .zero, style: .insetGrouped)
var selectedTheme: Theme {
didSet {
Storage.shared.boardTheme = selectedTheme.rawValue
tableView.reloadData()
}
}
var onThemeSelect: ((Theme) -> ())?

init(selectedTheme: Theme?) {
self.selectedTheme = selectedTheme ?? .classic
super.init(nibName: nil, bundle: nil)
}

deinit {
print("SettingsViewController deinit")
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()

setupTableView()
}

private func setupTableView() {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.dataSource = self
tableView.delegate = self

view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
}
}

extension SettingsViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
1
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
"Board Themes"
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
Theme.allCases.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let theme = Theme.allCases[indexPath.row]
cell.textLabel?.text = theme.rawValue
cell.accessoryType = selectedTheme == theme ? .checkmark : .none
return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedTheme = Theme.allCases[indexPath.row]
onThemeSelect?(selectedTheme)
}
}
36 changes: 36 additions & 0 deletions Chess/Storage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// Storage.swift
// Chess
//
// Created by Khislatjon Valijonov on 09/05/24.
// Copyright © 2024 Nick Lockwood. All rights reserved.
//

import Foundation

@propertyWrapper public struct UserDefaultWrapper<Value> {
public let key: String
public let storage: UserDefaults = .standard

public init(key: String) {
self.key = key
}

public var wrappedValue: Value? {
get {
storage.value(forKey: key) as? Value
}

set {
storage.setValue(newValue, forKey: key)
storage.synchronize()
}
}
}

class Storage {
static let shared = Storage()

@UserDefaultWrapper(key: "boardTheme")
var boardTheme: String?
}
9 changes: 7 additions & 2 deletions Chess/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class ViewController: UIViewController {
@IBOutlet var boardView: BoardView?
@IBOutlet var whiteToggle: UISegmentedControl?
@IBOutlet var blackToggle: UISegmentedControl?
@IBOutlet var boardThemePicker: UIPickerView?

override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -41,6 +40,12 @@ class ViewController: UIViewController {
})
setSelection(nil)
}

@IBAction private func settings() {
let vc = SettingsViewController(selectedTheme: boardView?.theme ?? .classic)
vc.onThemeSelect = { self.boardView?.theme = $0 }
self.present(vc, animated: true)
}
}

extension ViewController: BoardViewDelegate {
Expand Down Expand Up @@ -190,6 +195,6 @@ extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate {
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
boardView?.theme = Theme.allCases[row]
boardView?.theme = Theme.allCases[row]
}
}

0 comments on commit dc0c160

Please sign in to comment.