Extract competitor logic to a new competitor view controller and updated dependencies

This commit is contained in:
Raimund Wege
2017-09-13 11:00:17 +02:00
parent e444e4d2bc
commit d505c8a1c7
8 changed files with 499 additions and 264 deletions
@@ -370,8 +370,8 @@
C8CF22AD1F668BAB00A01E0A /* TrainingMarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CF22AC1F668BAB00A01E0A /* TrainingMarkViewController.swift */; };
C8CF22B41F67C4D800A01E0A /* RegattaRaceColumnAddData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CF22B31F67C4D800A01E0A /* RegattaRaceColumnAddData.swift */; };
C8CF22B81F68133000A01E0A /* TrainingRaceData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CF22B71F68133000A01E0A /* TrainingRaceData.swift */; };
C8CF22BA1F690FB300A01E0A /* CompetitorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8CF22B91F690FB300A01E0A /* CompetitorView.xib */; };
C8CF22BC1F69105800A01E0A /* CompetitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CF22BB1F69105800A01E0A /* CompetitorView.swift */; };
C8CF22BE1F69187800A01E0A /* CompetitorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CF22BD1F69187800A01E0A /* CompetitorViewController.swift */; };
C8CF22C01F6926E500A01E0A /* CompetitorSessionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CF22BF1F6926E500A01E0A /* CompetitorSessionViewController.swift */; };
C8D5E81D1D479FA800DA0D61 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C8D5E81C1D479FA800DA0D61 /* Main.storyboard */; };
C8E0BD0A1F39A08B002FCCA5 /* FormularViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E0BD091F39A08B002FCCA5 /* FormularViewController.swift */; };
C8E0BD0D1F39ADAD002FCCA5 /* KeychainPasswordItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E0BD0C1F39ADAD002FCCA5 /* KeychainPasswordItem.swift */; };
@@ -785,8 +785,8 @@
C8CF22AC1F668BAB00A01E0A /* TrainingMarkViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrainingMarkViewController.swift; sourceTree = "<group>"; };
C8CF22B31F67C4D800A01E0A /* RegattaRaceColumnAddData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegattaRaceColumnAddData.swift; sourceTree = "<group>"; };
C8CF22B71F68133000A01E0A /* TrainingRaceData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrainingRaceData.swift; sourceTree = "<group>"; };
C8CF22B91F690FB300A01E0A /* CompetitorView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CompetitorView.xib; sourceTree = "<group>"; };
C8CF22BB1F69105800A01E0A /* CompetitorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompetitorView.swift; sourceTree = "<group>"; };
C8CF22BD1F69187800A01E0A /* CompetitorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompetitorViewController.swift; sourceTree = "<group>"; };
C8CF22BF1F6926E500A01E0A /* CompetitorSessionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompetitorSessionViewController.swift; sourceTree = "<group>"; };
C8D5E81C1D479FA800DA0D61 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
C8D938B11EB9AFDB00B1B4BC /* CoreData 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "CoreData 3.xcdatamodel"; sourceTree = "<group>"; };
C8E0BD091F39A08B002FCCA5 /* FormularViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormularViewController.swift; sourceTree = "<group>"; };
@@ -1398,8 +1398,6 @@
7F193A901A39E54600D71773 /* GPSAccuracyView.swift */,
C89C5FC41D06A289002AAAD2 /* GradientView.swift */,
C8BFCCCB1D523C5D00FC1A27 /* TitleView.swift */,
C8CF22B91F690FB300A01E0A /* CompetitorView.xib */,
C8CF22BB1F69105800A01E0A /* CompetitorView.swift */,
);
name = Views;
sourceTree = "<group>";
@@ -1444,6 +1442,8 @@
C8CF22B11F669DA700A01E0A /* Regatta */,
C89C5FC61D06CE62002AAAD2 /* Tracking */,
C8CF22B21F669DB100A01E0A /* Training */,
C8CF22BD1F69187800A01E0A /* CompetitorViewController.swift */,
C8CF22BF1F6926E500A01E0A /* CompetitorSessionViewController.swift */,
);
name = Session;
sourceTree = "<group>";
@@ -1856,7 +1856,6 @@
7F14A20E1A13B9A6001C1ECB /* ZM.png in Resources */,
7F14A20B1A13B9A6001C1ECB /* YE.png in Resources */,
7F14A1181A13B9A6001C1ECB /* _somaliland.png in Resources */,
C8CF22BA1F690FB300A01E0A /* CompetitorView.xib in Resources */,
7F14A1931A13B9A6001C1ECB /* KP.png in Resources */,
7F14A1971A13B9A6001C1ECB /* KZ.png in Resources */,
7F14A1201A13B9A6001C1ECB /* AG.png in Resources */,
@@ -2091,6 +2090,7 @@
7F99DE3C1A126554009B3619 /* RegattaCompetitorViewController.swift in Sources */,
C843D4841EBC54A300250F01 /* CheckIn.swift in Sources */,
C8BFCCCC1D523C5D00FC1A27 /* TitleView.swift in Sources */,
C8CF22C01F6926E500A01E0A /* CompetitorSessionViewController.swift in Sources */,
C8F71EF31D86A15F00826DE4 /* SMTWiFiStatus.m in Sources */,
7F8CC2081A10D47A00C56D7F /* SettingsViewController.swift in Sources */,
C8739E0D1D2AA2A500A89F3C /* Event.swift in Sources */,
@@ -2126,7 +2126,6 @@
C8739E061D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift in Sources */,
7F193A8F1A39ACF500D71773 /* TimerViewController.swift in Sources */,
C8739E181D2BF2DC00A89F3C /* BaseData.swift in Sources */,
C8CF22BC1F69105800A01E0A /* CompetitorView.swift in Sources */,
C8CF22B41F67C4D800A01E0A /* RegattaRaceColumnAddData.swift in Sources */,
7F83F15619F154F000C53328 /* AppDelegate.swift in Sources */,
C867BD0F1F4B0A4B007E78E0 /* TrainingCoreDataManager.swift in Sources */,
@@ -2144,6 +2143,7 @@
7F0658FF19F7EE910077FF95 /* CheckInData.swift in Sources */,
7F193A911A39E54600D71773 /* GPSAccuracyView.swift in Sources */,
C8E0BD0A1F39A08B002FCCA5 /* FormularViewController.swift in Sources */,
C8CF22BE1F69187800A01E0A /* CompetitorViewController.swift in Sources */,
C8F71EE41D8691F700826DE4 /* SVProgressAnimatedView.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -0,0 +1,62 @@
//
// CompetitorSessionViewController.swift
// SAPTracker
//
// Created by Raimund Wege on 13.09.17.
// Copyright © 2017 com.sap.sailing. All rights reserved.
//
import UIKit
class CompetitorSessionViewController: SessionViewController {
struct CompetitorSessionSegue {
static let EmbedCompetitor = "EmbedCompetitor"
}
weak var competitorCheckIn: CompetitorCheckIn!
weak var competitorViewController: CompetitorViewController?
weak var competitorCoreDataManager: CoreDataManager!
// MARK: - OptionSheet
func makeCompetitorOptionSheet() -> UIAlertController {
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = self.optionButton
}
alertController.addAction(self.makeActionSettings())
alertController.addAction(self.makeActionCheckOut())
alertController.addAction(self.makeActionReplaceImage())
alertController.addAction(self.makeActionUpdate())
alertController.addAction(self.makeActionInfo())
alertController.addAction(self.makeActionCancel())
return alertController
}
fileprivate func makeActionReplaceImage() -> UIAlertAction {
return UIAlertAction(title: Translation.CompetitorView.OptionSheet.ReplaceImageAction.Title.String, style: .default) { [weak self] action in
self?.competitorViewController?.showSelectImageAlert()
}
}
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == CompetitorSessionSegue.EmbedCompetitor) {
if let competitorViewController = segue.destination as? CompetitorViewController {
competitorViewController.competitorCheckIn = competitorCheckIn
competitorViewController.competitorSessionController = competitorSessionController
competitorViewController.competitorCoreDataManager = competitorCoreDataManager
self.competitorViewController = competitorViewController
}
}
}
// MARK: - Properties
lazy var competitorSessionController: CompetitorSessionController = {
return CompetitorSessionController(checkIn: self.competitorCheckIn, coreDataManager: self.competitorCoreDataManager)
}()
}
@@ -1,44 +0,0 @@
//
// CompetitorView.swift
// SAPTracker
//
// Created by Raimund Wege on 13.09.17.
// Copyright © 2017 com.sap.sailing. All rights reserved.
//
import UIKit
class CompetitorView: UIView {
@IBOutlet var view: UIView!
@IBOutlet weak var teamImageView: UIImageView!
@IBOutlet weak var teamImageAddButton: UIButton!
@IBOutlet weak var teamImageEditButton: UIButton!
@IBOutlet weak var teamImageRetryButton: UIButton!
@IBOutlet weak var competitorNameLabel: UILabel!
@IBOutlet weak var competitorFlagImageView: UIImageView!
@IBOutlet weak var competitorSailLabel: UILabel!
convenience init() {
self.init(frame: CGRect.zero)
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
Bundle.main.loadNibNamed("CompetitorView", owner: self, options: nil)
addSubview(view)
view.frame = self.bounds
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}
@@ -1,169 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
<array key="OpenSans-Bold.ttf">
<string>OpenSans-Bold</string>
</array>
<array key="OpenSans-Regular.ttf">
<string>OpenSans</string>
</array>
</customFonts>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CompetitorView" customModule="SAPTracker" customModuleProvider="target">
<connections>
<outlet property="competitorFlagImageView" destination="v4i-Ig-NwN" id="Fxa-OA-PXE"/>
<outlet property="competitorNameLabel" destination="Jk9-A8-a0b" id="D4S-Id-aUb"/>
<outlet property="competitorSailLabel" destination="Pbz-tz-ziS" id="iEc-Gs-UYC"/>
<outlet property="teamImageAddButton" destination="4tT-cp-31g" id="mYL-cI-kYB"/>
<outlet property="teamImageEditButton" destination="Usl-VJ-yvz" id="ica-74-lqE"/>
<outlet property="teamImageRetryButton" destination="T1N-kX-2Xq" id="ZYW-rL-dlA"/>
<outlet property="teamImageView" destination="n1N-E4-y9h" id="MK0-DK-qY4"/>
<outlet property="view" destination="iN0-l3-epB" id="IZ6-9I-SZU"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" image="profile_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="n1N-E4-y9h">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hgy-O7-hOz" userLabel="Button View">
<rect key="frame" x="0.0" y="0.0" width="375" height="629"/>
<subviews>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Usl-VJ-yvz">
<rect key="frame" x="334" y="588" width="33" height="33"/>
<constraints>
<constraint firstAttribute="height" constant="33" id="GEg-Hd-3dr"/>
<constraint firstAttribute="width" constant="33" id="aeL-LL-XoO"/>
</constraints>
<state key="normal" image="edit">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1" verticalHuggingPriority="1" horizontalCompressionResistancePriority="999" verticalCompressionResistancePriority="999" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="wordWrap" translatesAutoresizingMaskIntoConstraints="NO" id="T1N-kX-2Xq">
<rect key="frame" x="34" y="294.5" width="308" height="40"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="18"/>
<inset key="contentEdgeInsets" minX="8" minY="8" maxX="8" maxY="8"/>
<state key="normal" title="Team Image Upload Retry Button" image="retry">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
<real key="value" value="0.5"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1" verticalHuggingPriority="1" horizontalCompressionResistancePriority="999" verticalCompressionResistancePriority="999" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="clip" translatesAutoresizingMaskIntoConstraints="NO" id="4tT-cp-31g">
<rect key="frame" x="66" y="294" width="243" height="41"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="18"/>
<inset key="contentEdgeInsets" minX="8" minY="8" maxX="8" maxY="8"/>
<state key="normal" title="Team Image Add Button" image="camera">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
<real key="value" value="0.5"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
</subviews>
<constraints>
<constraint firstItem="T1N-kX-2Xq" firstAttribute="centerY" secondItem="hgy-O7-hOz" secondAttribute="centerY" id="BtM-u2-Pcx"/>
<constraint firstItem="4tT-cp-31g" firstAttribute="centerY" secondItem="hgy-O7-hOz" secondAttribute="centerY" id="E1F-Yb-XhW"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="T1N-kX-2Xq" secondAttribute="trailing" constant="20" id="GUb-nU-bN5"/>
<constraint firstAttribute="trailing" secondItem="Usl-VJ-yvz" secondAttribute="trailing" constant="8" id="IZR-Xx-Dk6"/>
<constraint firstAttribute="bottom" secondItem="Usl-VJ-yvz" secondAttribute="bottom" constant="8" id="Nob-gF-H5Q"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="4tT-cp-31g" secondAttribute="trailing" constant="20" id="QG8-1h-eYg"/>
<constraint firstItem="4tT-cp-31g" firstAttribute="centerX" secondItem="hgy-O7-hOz" secondAttribute="centerX" id="Rje-hb-px6"/>
<constraint firstItem="4tT-cp-31g" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="hgy-O7-hOz" secondAttribute="leading" constant="20" id="pYr-ZS-NKH"/>
<constraint firstItem="T1N-kX-2Xq" firstAttribute="centerX" secondItem="hgy-O7-hOz" secondAttribute="centerX" id="vhl-vu-qb4"/>
<constraint firstItem="T1N-kX-2Xq" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="hgy-O7-hOz" secondAttribute="leading" constant="20" id="w6p-PZ-idc"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lnY-aH-7lf" userLabel="Competitor View">
<rect key="frame" x="0.0" y="629" width="375" height="38"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sail ID Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Pbz-tz-ziS">
<rect key="frame" x="258" y="8.5" width="97" height="22"/>
<fontDescription key="fontDescription" name="OpenSans-Bold" family="Open Sans" pointSize="16"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="DE.png" translatesAutoresizingMaskIntoConstraints="NO" id="v4i-Ig-NwN">
<rect key="frame" x="226" y="7" width="24" height="24"/>
<constraints>
<constraint firstAttribute="height" constant="24" id="kZT-Rx-VG0"/>
<constraint firstAttribute="width" constant="24" id="sUv-Y4-eVq"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Competitor Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Jk9-A8-a0b" userLabel="Name Label">
<rect key="frame" x="20" y="8.5" width="139" height="22"/>
<fontDescription key="fontDescription" name="OpenSans-Bold" family="Open Sans" pointSize="16"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Name, Sail ID"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="v4i-Ig-NwN" secondAttribute="centerY" id="DF8-o7-Ct4"/>
<constraint firstItem="Jk9-A8-a0b" firstAttribute="leading" secondItem="lnY-aH-7lf" secondAttribute="leading" constant="20" id="OuI-tk-M1P"/>
<constraint firstAttribute="trailing" secondItem="Pbz-tz-ziS" secondAttribute="trailing" constant="20" id="VYQ-Bn-u6W"/>
<constraint firstAttribute="centerY" secondItem="Jk9-A8-a0b" secondAttribute="centerY" id="das-Sd-yZz"/>
<constraint firstAttribute="centerY" secondItem="Pbz-tz-ziS" secondAttribute="centerY" id="gYb-22-Ss8"/>
<constraint firstAttribute="height" constant="38" id="hUi-QY-pKu"/>
<constraint firstItem="Pbz-tz-ziS" firstAttribute="leading" secondItem="v4i-Ig-NwN" secondAttribute="trailing" constant="8" symbolic="YES" id="qFA-La-ReA"/>
<constraint firstItem="v4i-Ig-NwN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Jk9-A8-a0b" secondAttribute="trailing" id="w0E-NH-Q4H"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="lnY-aH-7lf" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="0sT-4c-6JH"/>
<constraint firstItem="lnY-aH-7lf" firstAttribute="top" secondItem="hgy-O7-hOz" secondAttribute="bottom" id="5ki-S3-N7o"/>
<constraint firstAttribute="bottom" secondItem="lnY-aH-7lf" secondAttribute="bottom" id="7AD-sh-Muu"/>
<constraint firstAttribute="trailing" secondItem="hgy-O7-hOz" secondAttribute="trailing" id="AkV-q5-ogg"/>
<constraint firstAttribute="trailing" secondItem="n1N-E4-y9h" secondAttribute="trailing" id="DVx-e6-fcd"/>
<constraint firstItem="n1N-E4-y9h" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Dbc-Q2-Xkh"/>
<constraint firstAttribute="trailing" secondItem="lnY-aH-7lf" secondAttribute="trailing" id="O1g-G2-p0M"/>
<constraint firstAttribute="bottom" secondItem="n1N-E4-y9h" secondAttribute="bottom" id="gHE-Oo-Hjn"/>
<constraint firstItem="n1N-E4-y9h" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="p88-WM-DwV"/>
<constraint firstItem="hgy-O7-hOz" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="u48-Yf-Dgu"/>
<constraint firstItem="hgy-O7-hOz" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="xTN-0u-JcC"/>
</constraints>
<point key="canvasLocation" x="32.5" y="53.5"/>
</view>
</objects>
<resources>
<image name="DE.png" width="64" height="64"/>
<image name="camera" width="24" height="24"/>
<image name="edit" width="33" height="33"/>
<image name="profile_placeholder" width="360" height="256"/>
<image name="retry" width="24" height="24"/>
</resources>
</document>
@@ -0,0 +1,235 @@
//
// CompetitorViewController.swift
// SAPTracker
//
// Created by Raimund Wege on 13.09.17.
// Copyright © 2017 com.sap.sailing. All rights reserved.
//
import UIKit
class CompetitorViewController: UIViewController {
weak var competitorCheckIn: CompetitorCheckIn!
weak var competitorSessionController: CompetitorSessionController!
weak var competitorCoreDataManager: CoreDataManager!
@IBOutlet weak var teamImageView: UIImageView!
@IBOutlet weak var teamImageAddButton: UIButton!
@IBOutlet weak var teamImageEditButton: UIButton!
@IBOutlet weak var teamImageRetryButton: UIButton!
@IBOutlet weak var competitorNameLabel: UILabel!
@IBOutlet weak var competitorFlagImageView: UIImageView!
@IBOutlet weak var competitorSailIDLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
// MARK: - Setup
fileprivate func setup() {
setupLocalization()
}
fileprivate func setupLocalization() {
teamImageAddButton.setTitle(Translation.CompetitorView.TeamImageAddButton.Title.String, for: .normal)
teamImageRetryButton.setTitle(Translation.CompetitorView.TeamImageUploadRetryButton.Title.String, for: .normal)
}
// MARK: - Refresh
func refresh() {
refreshCompetitor()
refreshTeamImage()
}
fileprivate func refreshCompetitor() {
competitorNameLabel.text = competitorCheckIn.name
competitorFlagImageView.image = UIImage(named: competitorCheckIn.countryCode)
competitorSailIDLabel.text = competitorCheckIn.sailID
}
fileprivate func refreshTeamImage() {
if let imageData = competitorCheckIn.teamImageData {
teamImageView.image = UIImage(data: imageData as Data)
if competitorCheckIn.teamImageRetry {
refreshTeamImageButtons(showAddButton: false, showEditButton: true, showRetryButton: true)
} else {
refreshTeamImageButtons(showAddButton: false, showEditButton: true, showRetryButton: false)
setTeamImageWithURLRequest(urlString: competitorCheckIn.teamImageURL, completion: { (withSuccess) in
self.refreshTeamImageButtons(showAddButton: false, showEditButton: true, showRetryButton: false)
})
}
} else {
self.refreshTeamImageButtons(showAddButton: true, showEditButton: false, showRetryButton: false)
setTeamImageWithURLRequest(urlString: competitorCheckIn.teamImageURL, completion: { (withSuccess) in
self.refreshTeamImageButtons(showAddButton: !withSuccess, showEditButton: withSuccess, showRetryButton: false)
})
}
}
fileprivate func refreshTeamImageButtons(showAddButton: Bool, showEditButton: Bool, showRetryButton: Bool) {
teamImageAddButton.isHidden = !showAddButton
teamImageEditButton.isHidden = !showEditButton
teamImageRetryButton.isHidden = !showRetryButton
}
// MARK: - TeamImage
fileprivate func setTeamImageWithURLRequest(urlString: String?, completion: @escaping (_ withSuccess: Bool) -> Void) {
setTeamImageWithURLRequest(urlString: urlString, success: { () in
completion(true)
}) {
completion(false)
}
}
fileprivate func setTeamImageWithURLRequest(urlString: String?, success: @escaping () -> Void, failure: @escaping () -> Void) {
guard let string = urlString else { failure(); return }
guard let url = URL(string: string) else { failure(); return }
teamImageView.setImageWith(URLRequest(url: url), placeholderImage: nil, success: { (request, response, image) in
self.setTeamImageWithURLSuccess(image: image, success: success)
}) { (request, response, error) in
self.setTeamImageWithURLFailure(error: error, failure: failure)
}
}
fileprivate func setTeamImageWithURLSuccess(image: UIImage, success: () -> Void) {
teamImageView.image = image
competitorCheckIn.teamImageRetry = false
competitorCheckIn.teamImageData = UIImageJPEGRepresentation(image, 0.8)
competitorCoreDataManager.saveContext()
success()
}
fileprivate func setTeamImageWithURLFailure(error: Error, failure: () -> Void) {
logError(name: "\(#function)", error: error)
failure()
}
// MARK: - Actions
@IBAction func teamImageAddButtonTapped(_ sender: AnyObject) {
showSelectImageAlert()
}
@IBAction func teamImageEditButtonTapped(_ sender: AnyObject) {
showSelectImageAlert()
}
@IBAction func teamImageRetryButtonTapped(_ sender: AnyObject) {
if let data = competitorCheckIn.teamImageData {
uploadTeamImageData(imageData: data)
}
}
// MARK: - Alerts
func showSelectImageAlert() {
if UIImagePickerController.isSourceTypeAvailable(.camera) && UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let alertController = UIAlertController(
title: Translation.CompetitorView.SelectImageAlert.Title.String,
message: Translation.CompetitorView.SelectImageAlert.Message.String,
preferredStyle: .alert
)
let cameraAction = UIAlertAction(title: Translation.CompetitorView.SelectImageAlert.CameraAction.Title.String, style: .default) { [weak self] (action) in
self?.showImagePicker(sourceType: .camera)
}
let photoLibraryAction = UIAlertAction(title: Translation.CompetitorView.SelectImageAlert.PhotoLibraryAction.Title.String, style: .default) { [weak self] (action) in
self?.showImagePicker(sourceType: .photoLibrary)
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
alertController.addAction(cameraAction)
alertController.addAction(photoLibraryAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
} else if UIImagePickerController.isSourceTypeAvailable(.camera) {
showImagePicker(sourceType: .camera)
} else if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
showImagePicker(sourceType: .photoLibrary)
}
}
}
// MARK: - UINavigationControllerDelegate
extension CompetitorViewController: UINavigationControllerDelegate {
}
// MARK: - UIImagePickerControllerDelegate
extension CompetitorViewController: UIImagePickerControllerDelegate {
fileprivate func showImagePicker(sourceType: UIImagePickerControllerSourceType) {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
imagePickerController.sourceType = sourceType;
imagePickerController.mediaTypes = [kUTTypeImage as String];
imagePickerController.allowsEditing = false
present(imagePickerController, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
dismiss(animated: true) { self.pickedImage(image: image) }
} else {
dismiss(animated: true, completion: nil)
}
}
fileprivate func pickedImage(image: UIImage) {
teamImageView.image = image
competitorCheckIn.teamImageData = UIImageJPEGRepresentation(image, 0.8)
competitorCoreDataManager.saveContext()
if let data = competitorCheckIn.teamImageData {
uploadTeamImageData(imageData: data)
}
}
// MARK: - Upload
fileprivate func uploadTeamImageData(imageData: Data!) {
SVProgressHUD.show()
competitorSessionController.postTeamImageData(imageData: imageData, competitorID: competitorCheckIn.competitorID, success: { (teamImageURL) in
SVProgressHUD.popActivity()
self.uploadTeamImageDataSuccess(teamImageURL: teamImageURL)
}) { (error) in
SVProgressHUD.popActivity()
self.uploadTeamImageDataFailure(error: error)
}
}
fileprivate func uploadTeamImageDataSuccess(teamImageURL: String) {
competitorCheckIn.teamImageRetry = false
competitorCheckIn.teamImageURL = teamImageURL
competitorCoreDataManager.saveContext()
refreshTeamImage()
}
fileprivate func uploadTeamImageDataFailure(error: Error) {
competitorCheckIn.teamImageRetry = true
competitorCoreDataManager.saveContext()
showUploadTeamImageFailureAlert(error: error)
refreshTeamImage()
}
// MARK: - Alerts
fileprivate func showUploadTeamImageFailureAlert(error: Error) {
let alertController = UIAlertController(
title: Translation.CompetitorView.UploadTeamImageFailureAlert.Title.String,
message: error.localizedDescription,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default, handler: nil)
alertController.addAction(okAction)
present(alertController, animated: true, completion: nil)
}
}
@@ -318,7 +318,7 @@
<scene sceneID="e3W-CJ-soQ">
<objects>
<navigationController storyboardIdentifier="rootViewController" id="pqQ-jd-OwW" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" translucent="NO" id="x3H-m5-yJB">
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="x3H-m5-yJB">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
@@ -456,7 +456,7 @@
<scene sceneID="6Ty-cK-spl">
<objects>
<navigationController id="Pn3-0n-ZdQ" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" translucent="NO" id="McN-2f-sK6">
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="McN-2f-sK6">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
@@ -571,12 +571,14 @@
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="siT-ZL-pju" customClass="CompetitorView" customModule="SAPTracker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="475"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cOY-Xs-ep7">
<rect key="frame" x="0.0" y="0.0" width="375" height="463"/>
<connections>
<segue destination="b2Z-q5-zaZ" kind="embed" identifier="EmbedCompetitor" id="LhS-FE-OSU"/>
</connections>
</containerView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3jK-ek-md2" userLabel="Training View">
<rect key="frame" x="0.0" y="475" width="375" height="128"/>
<rect key="frame" x="0.0" y="463" width="375" height="140"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="68H-E2-rnx">
<rect key="frame" x="129" y="8" width="117" height="22"/>
@@ -614,7 +616,7 @@
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="e6j-2H-QrX" secondAttribute="bottom" constant="8" id="3lA-ah-B1K"/>
<constraint firstAttribute="bottom" secondItem="e6j-2H-QrX" secondAttribute="bottom" constant="20" id="3lA-ah-B1K"/>
<constraint firstItem="e6j-2H-QrX" firstAttribute="leading" secondItem="3jK-ek-md2" secondAttribute="leading" constant="20" id="3tt-of-GG5"/>
<constraint firstAttribute="trailing" secondItem="e6j-2H-QrX" secondAttribute="trailing" constant="20" id="40l-3I-K9K"/>
<constraint firstItem="e6j-2H-QrX" firstAttribute="top" secondItem="68H-E2-rnx" secondAttribute="bottom" constant="8" id="6DO-rw-ZV7"/>
@@ -625,12 +627,12 @@
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="3jK-ek-md2" firstAttribute="top" secondItem="siT-ZL-pju" secondAttribute="bottom" id="BAZ-3B-4GU"/>
<constraint firstItem="3jK-ek-md2" firstAttribute="leading" secondItem="N8Q-Eb-vTK" secondAttribute="leading" id="Eb1-gf-rir"/>
<constraint firstItem="cOY-Xs-ep7" firstAttribute="top" secondItem="dS6-Pi-1JW" secondAttribute="bottom" id="HSg-BY-SFX"/>
<constraint firstItem="21h-Jd-SOp" firstAttribute="top" secondItem="3jK-ek-md2" secondAttribute="bottom" id="JKH-uA-v4m"/>
<constraint firstItem="siT-ZL-pju" firstAttribute="top" secondItem="dS6-Pi-1JW" secondAttribute="bottom" id="NUl-yk-7fe"/>
<constraint firstItem="siT-ZL-pju" firstAttribute="leading" secondItem="N8Q-Eb-vTK" secondAttribute="leading" id="cf7-wm-155"/>
<constraint firstAttribute="trailing" secondItem="siT-ZL-pju" secondAttribute="trailing" id="f0b-Mh-8fZ"/>
<constraint firstItem="3jK-ek-md2" firstAttribute="top" secondItem="cOY-Xs-ep7" secondAttribute="bottom" id="KJh-B4-SnW"/>
<constraint firstItem="cOY-Xs-ep7" firstAttribute="leading" secondItem="N8Q-Eb-vTK" secondAttribute="leading" id="axM-JJ-Ytm"/>
<constraint firstAttribute="trailing" secondItem="cOY-Xs-ep7" secondAttribute="trailing" id="fb7-kv-mya"/>
<constraint firstAttribute="trailing" secondItem="3jK-ek-md2" secondAttribute="trailing" id="x3N-9Z-4LV"/>
</constraints>
</view>
@@ -863,7 +865,7 @@
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Mark Name Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumFontSize="12" adjustsLetterSpacingToFitWidth="YES" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="BQe-Id-ec3">
<rect key="frame" x="101" y="290.5" width="173" height="22"/>
<rect key="frame" x="101.5" y="290.5" width="173" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="g3A-7J-yFy"/>
</constraints>
@@ -1070,7 +1072,7 @@
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6rV-hv-c3D" userLabel="Countdown View">
<rect key="frame" x="6.5" y="38" width="363" height="50"/>
<rect key="frame" x="6" y="38" width="363" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pjH-rV-MGI" userLabel="Days View">
<rect key="frame" x="0.0" y="0.0" width="121" height="50"/>
@@ -1386,7 +1388,7 @@
<scene sceneID="s4S-5p-4o1">
<objects>
<navigationController id="I54-NN-JAf" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" translucent="NO" id="Qb2-vc-6Pl">
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="Qb2-vc-6Pl">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
@@ -1486,13 +1488,13 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Status Title Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="r6d-OU-cRI">
<rect key="frame" x="20" y="14.5" width="134.5" height="23.5"/>
<rect key="frame" x="20" y="14" width="134.5" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Status Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="5Xu-6g-tqP">
<rect key="frame" x="259" y="14.5" width="96" height="23.5"/>
<rect key="frame" x="259" y="14" width="96" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
@@ -1518,13 +1520,13 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Mode Title Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Xww-rc-pOA">
<rect key="frame" x="20" y="14.5" width="130.5" height="23.5"/>
<rect key="frame" x="20" y="14" width="130.5" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Mode Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="tJY-RR-vpe">
<rect key="frame" x="262" y="14.5" width="93" height="23.5"/>
<rect key="frame" x="262" y="14" width="93" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
@@ -1550,13 +1552,13 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GPS Fixes Title Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Ujw-jg-ilY">
<rect key="frame" x="20" y="14.5" width="161" height="23.5"/>
<rect key="frame" x="20" y="14" width="161" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GPS Fixes Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="dz3-w7-CCh">
<rect key="frame" x="232" y="14.5" width="123" height="23.5"/>
<rect key="frame" x="232" y="14" width="123" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<nil key="highlightedColor"/>
</label>
@@ -1582,13 +1584,13 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GPS Accuracy Title Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Z1d-5I-pbj">
<rect key="frame" x="20" y="14.5" width="191.5" height="23.5"/>
<rect key="frame" x="20" y="14" width="191.5" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GPS Accuracy Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="DiM-MR-SGV">
<rect key="frame" x="181.5" y="14.5" width="153.5" height="23.5"/>
<rect key="frame" x="181.5" y="14" width="153.5" height="23.5"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -1700,7 +1702,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Value Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="48" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="mUm-EE-6Is" userLabel="Time Label">
<rect key="frame" x="3" y="244" width="369" height="98.5"/>
<rect key="frame" x="3" y="243.5" width="369" height="98.5"/>
<fontDescription key="fontDescription" name="OpenSans-Light" family="Open Sans" pointSize="72"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -1742,7 +1744,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Value Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l5u-i3-029">
<rect key="frame" x="3" y="244" width="369" height="98.5"/>
<rect key="frame" x="3" y="243.5" width="369" height="98.5"/>
<fontDescription key="fontDescription" name="OpenSans-Light" family="Open Sans" pointSize="72"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -1783,7 +1785,7 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Value Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sGK-xV-9a0">
<rect key="frame" x="3" y="243.5" width="369" height="98.5"/>
<rect key="frame" x="3" y="244" width="369" height="98.5"/>
<fontDescription key="fontDescription" name="OpenSans-Light" family="Open Sans" pointSize="72"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -2148,7 +2150,7 @@
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="4Fb-v3-mkB" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" translucent="NO" id="opw-zV-Qak">
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="opw-zV-Qak">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
@@ -2166,7 +2168,7 @@
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="dfN-Ch-vpm" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" translucent="NO" id="IvG-lp-FEV">
<navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="IvG-lp-FEV">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
@@ -2234,7 +2236,7 @@
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="Njg-ZD-Ycd" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" id="bNh-Bg-ROM">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="bNh-Bg-ROM">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
@@ -2329,6 +2331,162 @@
</objects>
<point key="canvasLocation" x="1970" y="-2582"/>
</scene>
<!--Competitor View Controller-->
<scene sceneID="T01-po-oc2">
<objects>
<viewController id="b2Z-q5-zaZ" customClass="CompetitorViewController" customModule="SAPTracker" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="vV5-mZ-1WQ">
<rect key="frame" x="0.0" y="0.0" width="375" height="463"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" image="profile_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="KlN-FI-d4m">
<rect key="frame" x="0.0" y="0.0" width="375" height="463"/>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iwM-mY-oZT" userLabel="Button View">
<rect key="frame" x="0.0" y="0.0" width="375" height="425"/>
<subviews>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NN8-QQ-TQB">
<rect key="frame" x="334" y="384" width="33" height="33"/>
<constraints>
<constraint firstAttribute="height" constant="33" id="9j5-Jx-rb6"/>
<constraint firstAttribute="width" constant="33" id="h8u-PR-H5K"/>
</constraints>
<state key="normal" image="edit">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="teamImageEditButtonTapped:" destination="b2Z-q5-zaZ" eventType="touchUpInside" id="oXP-LX-4Da"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1" verticalHuggingPriority="1" horizontalCompressionResistancePriority="999" verticalCompressionResistancePriority="999" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="wordWrap" translatesAutoresizingMaskIntoConstraints="NO" id="bhL-2M-5XL">
<rect key="frame" x="34" y="192.5" width="308" height="40"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="18"/>
<inset key="contentEdgeInsets" minX="8" minY="8" maxX="8" maxY="8"/>
<state key="normal" title="Team Image Upload Retry Button" image="retry">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
<real key="value" value="0.5"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="teamImageRetryButtonTapped:" destination="b2Z-q5-zaZ" eventType="touchUpInside" id="BGc-Ed-2Ug"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1" verticalHuggingPriority="1" horizontalCompressionResistancePriority="999" verticalCompressionResistancePriority="999" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="clip" translatesAutoresizingMaskIntoConstraints="NO" id="LGR-3t-JL4">
<rect key="frame" x="66" y="192" width="243" height="41"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" name="OpenSans" family="Open Sans" pointSize="18"/>
<inset key="contentEdgeInsets" minX="8" minY="8" maxX="8" maxY="8"/>
<state key="normal" title="Team Image Add Button" image="camera">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="layer.borderWidth">
<real key="value" value="0.5"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="color" keyPath="layer.borderUIColor">
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="teamImageAddButtonTapped:" destination="b2Z-q5-zaZ" eventType="touchUpInside" id="lhk-d6-upy"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="NN8-QQ-TQB" secondAttribute="trailing" constant="8" id="2sh-sE-6uK"/>
<constraint firstItem="LGR-3t-JL4" firstAttribute="centerX" secondItem="iwM-mY-oZT" secondAttribute="centerX" id="CXp-qA-Ajf"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="bhL-2M-5XL" secondAttribute="trailing" constant="20" id="K21-QC-T7D"/>
<constraint firstAttribute="bottom" secondItem="NN8-QQ-TQB" secondAttribute="bottom" constant="8" id="MLS-BW-Q1Y"/>
<constraint firstItem="LGR-3t-JL4" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="iwM-mY-oZT" secondAttribute="leading" constant="20" id="O61-Gf-BKa"/>
<constraint firstItem="bhL-2M-5XL" firstAttribute="centerX" secondItem="iwM-mY-oZT" secondAttribute="centerX" id="Q3G-HZ-ioT"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="LGR-3t-JL4" secondAttribute="trailing" constant="20" id="UKL-Q2-04G"/>
<constraint firstItem="bhL-2M-5XL" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="iwM-mY-oZT" secondAttribute="leading" constant="20" id="V8v-Iy-R4G"/>
<constraint firstItem="bhL-2M-5XL" firstAttribute="centerY" secondItem="iwM-mY-oZT" secondAttribute="centerY" id="fq2-j0-GOe"/>
<constraint firstItem="LGR-3t-JL4" firstAttribute="centerY" secondItem="iwM-mY-oZT" secondAttribute="centerY" id="juW-E8-Uk2"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pAh-lZ-ZxJ" userLabel="Competitor View">
<rect key="frame" x="0.0" y="425" width="375" height="38"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sail ID Label" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="k06-sH-apv">
<rect key="frame" x="258" y="8.5" width="97" height="22"/>
<fontDescription key="fontDescription" name="OpenSans-Bold" family="Open Sans" pointSize="16"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="DE.png" translatesAutoresizingMaskIntoConstraints="NO" id="Fnk-q4-SIu">
<rect key="frame" x="226" y="7" width="24" height="24"/>
<constraints>
<constraint firstAttribute="height" constant="24" id="rl1-Od-zsZ"/>
<constraint firstAttribute="width" constant="24" id="yve-sJ-dOC"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Competitor Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="tbo-Yh-Fzh" userLabel="Name Label">
<rect key="frame" x="20" y="8.5" width="139" height="22"/>
<fontDescription key="fontDescription" name="OpenSans-Bold" family="Open Sans" pointSize="16"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Name, Sail ID"/>
<constraints>
<constraint firstAttribute="centerY" secondItem="tbo-Yh-Fzh" secondAttribute="centerY" id="Gi2-UR-mSR"/>
<constraint firstAttribute="centerY" secondItem="k06-sH-apv" secondAttribute="centerY" id="MuN-xP-EFX"/>
<constraint firstItem="k06-sH-apv" firstAttribute="leading" secondItem="Fnk-q4-SIu" secondAttribute="trailing" constant="8" symbolic="YES" id="O62-LI-oZR"/>
<constraint firstAttribute="centerY" secondItem="Fnk-q4-SIu" secondAttribute="centerY" id="hk3-vc-3Yd"/>
<constraint firstItem="Fnk-q4-SIu" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="tbo-Yh-Fzh" secondAttribute="trailing" id="jmw-h5-qBG"/>
<constraint firstAttribute="trailing" secondItem="k06-sH-apv" secondAttribute="trailing" constant="20" id="nE3-vO-cJa"/>
<constraint firstItem="tbo-Yh-Fzh" firstAttribute="leading" secondItem="pAh-lZ-ZxJ" secondAttribute="leading" constant="20" id="nHA-Az-QDf"/>
<constraint firstAttribute="height" constant="38" id="uYB-XY-nU1"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="pAh-lZ-ZxJ" secondAttribute="trailing" id="3eY-F3-3k7"/>
<constraint firstItem="pAh-lZ-ZxJ" firstAttribute="top" secondItem="iwM-mY-oZT" secondAttribute="bottom" id="9tr-c8-Pav"/>
<constraint firstItem="iwM-mY-oZT" firstAttribute="top" secondItem="vV5-mZ-1WQ" secondAttribute="top" id="B9L-6W-OXO"/>
<constraint firstAttribute="trailing" secondItem="iwM-mY-oZT" secondAttribute="trailing" id="E4p-fX-ULk"/>
<constraint firstAttribute="bottom" secondItem="KlN-FI-d4m" secondAttribute="bottom" id="Ebu-1y-0gH"/>
<constraint firstItem="KlN-FI-d4m" firstAttribute="leading" secondItem="vV5-mZ-1WQ" secondAttribute="leading" id="Jh8-Cc-gjh"/>
<constraint firstItem="pAh-lZ-ZxJ" firstAttribute="top" secondItem="iwM-mY-oZT" secondAttribute="bottom" id="Kcp-dk-ENA"/>
<constraint firstItem="KlN-FI-d4m" firstAttribute="top" secondItem="vV5-mZ-1WQ" secondAttribute="top" id="W3O-KE-1tm"/>
<constraint firstAttribute="trailing" secondItem="KlN-FI-d4m" secondAttribute="trailing" id="Wmn-HD-lQd"/>
<constraint firstAttribute="bottom" secondItem="pAh-lZ-ZxJ" secondAttribute="bottom" id="tGD-8c-hTQ"/>
<constraint firstItem="iwM-mY-oZT" firstAttribute="leading" secondItem="vV5-mZ-1WQ" secondAttribute="leading" id="uu9-C1-AlK"/>
<constraint firstItem="pAh-lZ-ZxJ" firstAttribute="leading" secondItem="vV5-mZ-1WQ" secondAttribute="leading" id="wzT-uU-vY7"/>
</constraints>
</view>
<connections>
<outlet property="competitorFlagImageView" destination="Fnk-q4-SIu" id="bZ9-aC-U2o"/>
<outlet property="competitorNameLabel" destination="tbo-Yh-Fzh" id="4Vl-8y-nbV"/>
<outlet property="competitorSailIDLabel" destination="k06-sH-apv" id="tfd-XQ-cs0"/>
<outlet property="teamImageAddButton" destination="LGR-3t-JL4" id="OxH-na-too"/>
<outlet property="teamImageEditButton" destination="NN8-QQ-TQB" id="wSA-LV-Igo"/>
<outlet property="teamImageRetryButton" destination="bhL-2M-5XL" id="UWt-DX-2xV"/>
<outlet property="teamImageView" destination="KlN-FI-d4m" id="BVJ-4q-Lyg"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="44E-7S-Xdo" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2850" y="-1810"/>
</scene>
</scenes>
<resources>
<image name="DE.png" width="64" height="64"/>
@@ -2341,9 +2499,9 @@
<image name="settings" width="22" height="22"/>
</resources>
<inferredMetricsTieBreakers>
<segue reference="gEw-ml-Ejg"/>
<segue reference="yTp-8r-iQQ"/>
<segue reference="aVN-ja-G16"/>
<segue reference="gEw-ml-Ejg"/>
</inferredMetricsTieBreakers>
<color key="tintColor" red="0.0" green="0.61568627450980395" blue="0.8784313725490196" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</document>
@@ -121,7 +121,7 @@ extension TrainingCheckInTableViewController: CheckInTableViewControllerDelegate
func checkInTableViewController(_ controller: CheckInTableViewController, prepareForSegue segue: UIStoryboardSegue, andCompetitorCheckIn competitorCheckIn: CompetitorCheckIn) {
guard let trainingCompetitorVC = segue.destination as? TrainingCompetitorViewController else { return }
trainingCompetitorVC.competitorCheckIn = competitorCheckIn
trainingCompetitorVC.trainingCoreDataManager = trainingCoreDataManager
trainingCompetitorVC.competitorCoreDataManager = trainingCoreDataManager
}
func checkInTableViewController(_ controller: CheckInTableViewController, prepareForSegue segue: UIStoryboardSegue, andMarkCheckIn markCheckIn: MarkCheckIn) {
@@ -8,12 +8,8 @@
import UIKit
class TrainingCompetitorViewController: SessionViewController {
class TrainingCompetitorViewController: CompetitorSessionViewController {
weak var competitorCheckIn: CompetitorCheckIn!
weak var trainingCoreDataManager: CoreDataManager!
@IBOutlet weak var stopTrainingButton: UIButton!
@IBOutlet weak var trainingNameLabel: UILabel!
override func viewDidLoad() {
@@ -67,12 +63,8 @@ class TrainingCompetitorViewController: SessionViewController {
// MARK: - Properties
fileprivate lazy var competitorSessionController: CompetitorSessionController = {
return CompetitorSessionController(checkIn: self.competitorCheckIn, coreDataManager: self.trainingCoreDataManager)
}()
fileprivate lazy var trainingController: TrainingController = {
return TrainingController(coreDataManager: self.trainingCoreDataManager, baseURLString: self.competitorCheckIn.serverURL)
return TrainingController(coreDataManager: self.competitorCoreDataManager, baseURLString: self.competitorCheckIn.serverURL)
}()
}
@@ -83,15 +75,16 @@ extension TrainingCompetitorViewController: SessionViewControllerDelegate {
var checkIn: CheckIn { get { return competitorCheckIn } }
var coreDataManager: CoreDataManager { get { return trainingCoreDataManager } }
var coreDataManager: CoreDataManager { get { return competitorCoreDataManager } }
var sessionController: SessionController { get { return competitorSessionController } }
func makeOptionSheet() -> UIAlertController {
return makeDefaultOptionSheet()
return makeCompetitorOptionSheet()
}
func refresh() {
competitorViewController?.refresh()
trainingNameLabel.text = competitorCheckIn.event.name
}