parent
4225a3b3cb
commit
749d4fbaf0
@ -0,0 +1,63 @@ |
||||
// |
||||
// Array+UITableDataSource.swift |
||||
// TournamentStats |
||||
// |
||||
// Created by Laurent Morvillier on 05/08/2019. |
||||
// Copyright © 2019 Stax River. All rights reserved. |
||||
// |
||||
|
||||
import Foundation |
||||
import UIKit |
||||
|
||||
|
||||
|
||||
|
||||
class DataSourceWrapper<T : ColumnRepresentable> : NSObject, UITableViewDataSource, UITableViewDelegate { |
||||
|
||||
var columnRepresentables: [T] |
||||
|
||||
init(array: [T]) { |
||||
self.columnRepresentables = array |
||||
} |
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
||||
print("numberOfRowsInSection = \(self.columnRepresentables.count)") |
||||
return self.columnRepresentables.count + 1 // + 1 for header |
||||
} |
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! StackTableCell |
||||
|
||||
var columns: [String] |
||||
var font: UIFont |
||||
switch indexPath.row { |
||||
case 0: |
||||
columns = T.headers() |
||||
font = UIFont.boldSystemFont(ofSize: 16.0) |
||||
default: |
||||
let cr = self.columnRepresentables[indexPath.row - 1] |
||||
columns = cr.colums() |
||||
font = UIFont.systemFont(ofSize: 16.0) |
||||
} |
||||
|
||||
columns.forEach { value in |
||||
let label: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 30)) |
||||
label.textColor = UIColor.black |
||||
label.backgroundColor = UIColor.white |
||||
label.text = value |
||||
label.font = font |
||||
cell.stackView.addArrangedSubview(label) |
||||
} |
||||
|
||||
return cell |
||||
} |
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { |
||||
return 32.0 |
||||
} |
||||
|
||||
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { |
||||
return 0.1 |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,21 @@ |
||||
// |
||||
// StackTableCell.swift |
||||
// TournamentStats |
||||
// |
||||
// Created by Laurent Morvillier on 05/08/2019. |
||||
// Copyright © 2019 Stax River. All rights reserved. |
||||
// |
||||
|
||||
import Foundation |
||||
import UIKit |
||||
|
||||
class StackTableCell: UITableViewCell { |
||||
|
||||
@IBOutlet weak var stackView: UIStackView! |
||||
|
||||
override func awakeFromNib() { |
||||
self.backgroundColor = UIColor.clear |
||||
self.stackView.distribution = .fillEqually |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> |
||||
<device id="retina6_1" orientation="portrait"> |
||||
<adaptation id="fullscreen"/> |
||||
</device> |
||||
<dependencies> |
||||
<deployment identifier="iOS"/> |
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/> |
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> |
||||
</dependencies> |
||||
<objects> |
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> |
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> |
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="aT2-pS-Iqw" customClass="StackTableCell" customModule="TournamentStats" customModuleProvider="target"> |
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/> |
||||
<autoresizingMask key="autoresizingMask"/> |
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="aT2-pS-Iqw" id="n6c-N8-BIo"> |
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/> |
||||
<autoresizingMask key="autoresizingMask"/> |
||||
<subviews> |
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zyP-u3-Lbn"> |
||||
<rect key="frame" x="8" y="0.0" width="398" height="43.5"/> |
||||
</stackView> |
||||
</subviews> |
||||
<constraints> |
||||
<constraint firstItem="zyP-u3-Lbn" firstAttribute="leading" secondItem="n6c-N8-BIo" secondAttribute="leading" constant="8" id="36S-42-88h"/> |
||||
<constraint firstAttribute="bottom" secondItem="zyP-u3-Lbn" secondAttribute="bottom" id="9Fi-3O-haC"/> |
||||
<constraint firstAttribute="trailing" secondItem="zyP-u3-Lbn" secondAttribute="trailing" constant="8" id="Aja-gu-ofx"/> |
||||
<constraint firstItem="zyP-u3-Lbn" firstAttribute="top" secondItem="n6c-N8-BIo" secondAttribute="top" id="nko-dF-Ksc"/> |
||||
</constraints> |
||||
</tableViewCellContentView> |
||||
<connections> |
||||
<outlet property="stackView" destination="zyP-u3-Lbn" id="Odj-c0-t9N"/> |
||||
</connections> |
||||
<point key="canvasLocation" x="-57" y="102"/> |
||||
</tableViewCell> |
||||
</objects> |
||||
</document> |
||||
@ -0,0 +1,99 @@ |
||||
// |
||||
// UIView+Extensions.swift |
||||
// TournamentStats |
||||
// |
||||
// Created by Laurent Morvillier on 05/08/2019. |
||||
// Copyright © 2019 Stax River. All rights reserved. |
||||
// |
||||
|
||||
import Foundation |
||||
import UIKit |
||||
|
||||
extension UIView { |
||||
|
||||
func toImage() -> UIImage? { |
||||
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0) |
||||
if let context = UIGraphicsGetCurrentContext() { |
||||
self.layer.render(in: context) |
||||
if let image = UIGraphicsGetImageFromCurrentImageContext() { |
||||
UIGraphicsEndImageContext() |
||||
return image |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
|
||||
// MARK: - Constraints |
||||
|
||||
@objc public func addMaxConstraints(view: UIView) { |
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
view.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true |
||||
view.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true |
||||
if #available(iOS 11.0, *) { |
||||
view.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor).isActive = true |
||||
} else { |
||||
view.topAnchor.constraint(equalTo: self.topAnchor).isActive = true |
||||
} |
||||
if #available(iOS 11.0, *) { |
||||
view.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor).isActive = true |
||||
} else { |
||||
view.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true |
||||
} |
||||
} |
||||
|
||||
@objc public func addCenterConstraints(view: UIView) { |
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
view.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true |
||||
view.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true |
||||
view.heightAnchor.constraint(equalToConstant: view.frame.size.height).isActive = true |
||||
view.widthAnchor.constraint(equalToConstant: view.frame.size.width).isActive = true |
||||
} |
||||
|
||||
@objc public func addTopStickyConstraintsWithHeight(_ height: CGFloat, view: UIView) { |
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
view.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true |
||||
view.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true |
||||
if #available(iOS 11.0, *) { |
||||
view.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor).isActive = true |
||||
} else { |
||||
view.topAnchor.constraint(equalTo: self.topAnchor).isActive = true |
||||
} |
||||
view.heightAnchor.constraint(equalToConstant: height).isActive = true |
||||
} |
||||
|
||||
@objc public func addBottomStickyConstraintsWithHeight(_ height: CGFloat, view: UIView) { |
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
view.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true |
||||
view.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true |
||||
if #available(iOS 11.0, *) { |
||||
view.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor).isActive = true |
||||
} else { |
||||
view.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true |
||||
} |
||||
view.heightAnchor.constraint(equalToConstant: height).isActive = true |
||||
} |
||||
|
||||
@objc public func addMaxConstraintsToTopView(_ topView: UIView, forView view: UIView) { |
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = false |
||||
|
||||
view.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true |
||||
view.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true |
||||
view.topAnchor.constraint(equalTo: topView.bottomAnchor).isActive = true |
||||
if #available(iOS 11.0, *) { |
||||
view.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor).isActive = true |
||||
} else { |
||||
view.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true |
||||
} |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue