SampleApp/ThemeAndResourceViewController.swift (151 lines of code) (raw):
//
// Copyright (c) 2018. Uber Technologies
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
class ThemeEditorViewController: ViewController<ThemeEditorView>,
UITableViewDelegate,
UITableViewDataSource,
ColorEditorListener{
let theme: Theme
let resources: Resources
let preferences: Preferences
private let reuseID = "reuseID"
enum Section: Int, CaseIterable {
case theme
case resource
init(from rawValue: Int) {
if let new = Section(rawValue: rawValue) {
self = new
} else {
fatalError("Invalid Section Index: \"\(rawValue)\"")
}
}
}
init(preferences: Preferences) {
self.preferences = preferences
self.theme = preferences.theme
self.resources = preferences.resources
super.init(viewCreator: ThemeEditorView.init)
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
switch Section(from: section) {
case .theme: return theme.colors.count
case .resource: return resources.colors.count
}
}
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath)
cell.textLabel?.text = provider(for: indexPath).colors[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
let provider = self.provider(for: indexPath)
let color = provider.colors[indexPath.row]
showColorEditor(for: color,
in: provider)
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch Section(from: section) {
case .theme: return "Theme"
case .resource: return "Resources"
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .delete
}
func tableView(_ tableView: UITableView,
commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
provider(for: indexPath).removeColor(at: indexPath.row)
writePreferenes()
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath],
with: .bottom)
tableView.endUpdates()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return Section.allCases.count
}
func provider(for indexPath: IndexPath) -> ColorProvider {
switch Section(from: indexPath.section) {
case .theme: return theme
case .resource: return resources
}
}
override func viewDidLoad() {
super.viewDidLoad()
specializedView.table.register(UITableViewCell.self,
forCellReuseIdentifier: reuseID)
specializedView.table.dataSource = self
specializedView.table.delegate = self
specializedView.addButton.addTarget(self,
action: #selector(addNewColorPressed),
for: .touchUpInside)
}
@objc
func addNewColorPressed() {
let bottomSheet = UIAlertController(title: "Where Should the Color be Added?",
message: "",
preferredStyle: .actionSheet)
func showEditor(for provider: ColorProvider) -> (UIAlertAction) -> () {
return { (action) in
self.showColorEditor(for: NamedColor(name: "",
hex: 0),
in: provider)
}
}
bottomSheet.addAction(UIAlertAction(title: "Theme",
style: .default,
handler: showEditor(for: theme)))
bottomSheet.addAction(UIAlertAction(title: "Resource",
style: .default,
handler: showEditor(for: resources)))
present(bottomSheet, animated: true, completion: nil)
}
private func showColorEditor(for color: NamedColor,
in provider: ColorProvider) {
let colorEditorViewController = ColorEditorViewController(color: color,
in: provider)
colorEditorViewController.listener = self
navigationController
.orAssert("This view controller requires a navigation controller to function correctly")?
.pushViewController(colorEditorViewController,
animated: true)
}
func finishedEditingColor(_ color: NamedColor) {
writePreferenes()
specializedView.table.reloadData()
}
func writePreferenes() {
preferences.theme = theme
preferences.resources = resources
}
}
class ThemeEditorView: View {
let addButton: Button = {
let button = Button()
button.setTitle("Add new Color",
for: .normal)
return button
}()
let table = UITableView()
override init() {
super.init()
addSubview(table)
table.translatesAutoresizingMaskIntoConstraints = false
addSubview(addButton)
addButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint
.activate([
table.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
table.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
table.topAnchor.constraint(equalTo: topAnchor),
table.bottomAnchor.constraint(equalTo: bottomAnchor),
addButton.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
addButton.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),
addButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
])
}
}