// // GridViewController.swift // CapCollector // // Created by Christoph on 07.01.19. // Copyright © 2019 CH. All rights reserved. // import UIKit class GridViewController: UIViewController { private let columns = 40 static let len: CGFloat = 60 private lazy var rowHeight = GridViewController.len * 0.866 private lazy var margin = GridViewController.len - rowHeight private var myView: UIView! private var canvasSize: CGSize = .zero @IBOutlet weak var scrollView: UIScrollView! private var selectedTile: Int? = nil private weak var selectionView: RoundedButton! override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .portrait } override var shouldAutorotate: Bool { return true } override func viewDidLoad() { super.viewDidLoad() let width = CGFloat(columns) * GridViewController.len + GridViewController.len / 2 let height = (CGFloat(Cap.totalCapCount) / CGFloat(columns)).rounded(.up) * rowHeight + margin canvasSize = CGSize(width: width, height: height) myView = UIView(frame: CGRect(origin: .zero, size: canvasSize)) scrollView.addSubview(myView) scrollView.contentSize = canvasSize scrollView.delegate = self scrollView.zoomScale = 0.5 scrollView.maximumZoomScale = 1 setZoomRange() /* guard let image = Cap.mosaic else { error("No mosaic") return } imageView.image = image imageHeight.constant = image.size.height imageWidth.constant = image.size.width scrollView.contentSize = image.size let button = RoundedButton(frame: CGRect(origin: .zero, size: CGSize(width: Cap.mosaicCellSize, height: Cap.mosaicCellSize))) imageView.addSubview(button) selectionView = button button.borderColor = AppDelegate.tintColor button.borderWidth = 3 button.isHidden = true scrollView.delegate = self scrollView.zoomScale = 1 scrollView.maximumZoomScale = 1 setZoomRange() let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap)) scrollView.addGestureRecognizer(tapRecognizer) event("did load") */ } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) updateTiles() let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap)) myView.addGestureRecognizer(tapRecognizer) } override func viewDidLayoutSubviews() { setZoomRange() updateTiles() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) Cap.save() } private func setZoomRange() { let size = scrollView.frame.size let a = size.width / canvasSize.width let b = size.height / canvasSize.height let scale = min(a,b) scrollView.minimumZoomScale = min(a,b) if scrollView.zoomScale < scale { scrollView.setZoomScale(scale, animated: true) } } @objc func handleTap(_ sender: UITapGestureRecognizer) { let loc = sender.location(in: myView) let y = loc.y let s = y.truncatingRemainder(dividingBy: rowHeight) let row = Int(y / rowHeight) guard s > margin else { return } let column: CGFloat if row.isEven { column = loc.x / GridViewController.len } else { column = (loc.x - GridViewController.len / 2) / GridViewController.len } handleTileTapped(tile: row * columns + Int(column)) /* event("Tapped") let loc = sender.location(in: imageView) guard let tile = Cap.tile(for: loc) else { event("No tile for location \(loc)") return } handleTileTapped(tile: tile) */ } private func handleTileTapped(tile: Int) { if let selected = selectedTile { switchTiles(oldTile: selected, newTile: tile) } else { showSelection(tile: tile) } } /* private func showSelection(tile: Int) { event("Selecting tile \(tile)") let point = Cap.origin(for: tile) selectionView.frame = CGRect(origin: point, size: selectionView.frame.size) selectionView.isHidden = false selectedTile = tile } private func switchTiles(oldTile: Int, newTile: Int) { event("Switching tiles \(oldTile) and \(newTile)") selectionView.isHidden = true selectedTile = nil guard oldTile != newTile else { return } Cap.switchTiles(oldTile, newTile) Cap.switchTilesInMosaic(imageView, tile1: oldTile, tile2: newTile) } */ private var installedTiles = [Int : RoundedImageView]() private func showSelection(tile: Int) { clearTileSelection() if let view = installedTiles[tile] { view.borderWidth = 3 view.borderColor = AppDelegate.tintColor selectedTile = tile } else { selectedTile = nil } } private func tileIsVisible(tile: Int, in rect: CGRect) -> Bool { return rect.intersects(frame(for: tile)) } private func makeTile(_ tile: Int) { let view = RoundedImageView(frame: frame(for: tile)) myView.addSubview(view) view.image = Cap.tileImage(tile: tile) installedTiles[tile] = view } private func frame(for tile: Int) -> CGRect { let row = tile / columns let column = tile - row * columns let x = CGFloat(column) * GridViewController.len + (row.isEven ? 0 : GridViewController.len / 2) let y = CGFloat(row) * rowHeight return CGRect(x: x, y: y, width: GridViewController.len, height: GridViewController.len) } private func switchTiles(oldTile: Int, newTile: Int) { if oldTile != newTile { Cap.switchTiles(oldTile, newTile) installedTiles[oldTile]?.image = Cap.tileImage(tile: oldTile) installedTiles[newTile]?.image = Cap.tileImage(tile: newTile) } clearTileSelection() } private func clearTileSelection() { guard let tile = selectedTile else { return } installedTiles[tile]?.borderWidth = 0 selectedTile = nil } private func showTiles(in rect: CGRect) { for i in 0.. UIView? { return myView } func scrollViewDidScroll(_ scrollView: UIScrollView) { updateTiles() } } private extension Int { var isEven: Bool { return self % 2 == 0 } } extension GridViewController: Logger { static let logToken: String = "[Grid]" }