Compare commits
468 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce3f17d45f | |||
| e1faf6587c | |||
| 939d298809 | |||
| f179e15e5c | |||
| 6ff53717a4 | |||
| d123688395 | |||
| ca4a954d08 | |||
| 57fbde9b46 | |||
| 0dd06a572b | |||
| a2e4d559bc | |||
| f32c069be5 | |||
| c55ce91fb9 | |||
| 60d2cbeb69 | |||
| 7bd76e6b5e | |||
| 9f198a12b6 | |||
| 86634b140c | |||
| b925584f9c | |||
| 6f0decb0ff | |||
| 812151c51d | |||
| 14715e2c32 | |||
| 1a7efab0e6 | |||
| 5df57bcbda | |||
| a6cea16fef | |||
| 76d4555f74 | |||
| bb50755b2e | |||
| 32b5e37486 | |||
| 419f209346 | |||
| 2338e097c4 | |||
| c6a2660a2e | |||
| 04a1ec81d7 | |||
| a786a661b2 | |||
| db5e374880 | |||
| d2fed86772 | |||
| a8b1c3658e | |||
| 85598e297b | |||
| 71b00ba7f6 | |||
| 82acd5aedb | |||
| 81f4b1e4cc | |||
| 7c80613f1b | |||
| d2c7ac3cd8 | |||
| 2f6247a0ed | |||
| 87034055b4 | |||
| 0093289888 | |||
| f8037c08df | |||
| 24a7d469da | |||
| 2507aa5804 | |||
| 43c544b4d0 | |||
| 38e9b14a87 | |||
| be6811d311 | |||
| fb609dba72 | |||
| 7445f7388a | |||
| 0edc9292b3 | |||
| 28e1b2092e | |||
| f8f30d681f | |||
| 35471350a2 | |||
| 2da1b843d0 | |||
| f10195edc4 | |||
| 770bec9c31 | |||
| 3eea308ed4 | |||
| fda79e945f | |||
| b20fd5755b | |||
| 1d5461a037 | |||
| fab251e623 | |||
| 0d914c493a | |||
| d4a20a79d5 | |||
| 58eaa1d182 | |||
| a6f5c39e2c | |||
| 9da358a1f5 | |||
| a1db939515 | |||
| 9462839950 | |||
| 29a6e21e49 | |||
| 5739faffe6 | |||
| e6e1f49c00 | |||
| 88ea180068 | |||
| fb50458d67 | |||
| 9fd9ea3783 | |||
| 9b4aeab0a1 | |||
| 6afa92169d | |||
| b2496438bf | |||
| 238d8a17fe | |||
| cea248f433 | |||
| 1b4569f316 | |||
| 1c5cab61aa | |||
| b01c7166c4 | |||
| 49166b553f | |||
| ddb815d2cb | |||
| 30aafbd50f | |||
| 6ce92f19e0 | |||
| 18adca5396 | |||
| 5e0b696fef | |||
| adacb612a4 | |||
| f19fd6187a | |||
| 82630bdbf5 | |||
| 68e3f11a74 | |||
| 0c268974f6 | |||
| 33927b17c7 | |||
| 9f00bb182d | |||
| e69751361a | |||
| 57447fb562 | |||
| 9c022c300e | |||
| 445d8af2e3 | |||
| 2769b268e8 | |||
| 5a4c9e172e | |||
| 1c0595f1dc | |||
| 61ba198cc2 | |||
| 54d0ab0e3f | |||
| b74048502f | |||
| e86f3b6491 | |||
| 64a68729a5 | |||
| a289453eaf | |||
| ceefc62cf0 | |||
| 738c6972a4 | |||
| e8ab35abb8 | |||
| efba2dabb3 | |||
| 64cb0d88bd | |||
| 4bfed38f92 | |||
| 96fd5872a7 | |||
| b53cdbc27a | |||
| ebdd27d251 | |||
| 7b97e2d9bb | |||
| afe1d8a8ee | |||
| 8833aa841c | |||
| b6f2ce945d | |||
| 9fc539ec59 | |||
| 14e96bce38 | |||
| 9b8ae3de92 | |||
| 445eb7deb1 | |||
| 149e341352 | |||
| 1350a20f15 | |||
| aaf9d7dde4 | |||
| 852102eb99 | |||
| c1f4392dca | |||
| 335f887932 | |||
| 3ec1a1385b | |||
| d35cfaacb0 | |||
| 1ce5cedd7e | |||
| 1dc55d1a0c | |||
| 6939af6599 | |||
| 6dd1a9d3f1 | |||
| ab281c75ce | |||
| 291a6fdd0f | |||
| 9ba1f76e53 | |||
| 5abdbd97dd | |||
| b0011de863 | |||
| be8ecb84f4 | |||
| 82eb38c815 | |||
| 6d9d488fb4 | |||
| 6f995d1092 | |||
| 02603ee8d7 | |||
| 70e6a7c58e | |||
| 8ea3ef21a9 | |||
| 5f627812f5 | |||
| 758988e1e5 | |||
| a988b4dcfb | |||
| 6784af13ed | |||
| b4e9f2ef81 | |||
| 825241001b | |||
| fae45fe36a | |||
| 8716c92a30 | |||
| ae2ae485db | |||
| 8d0c13d09d | |||
| b869eebe9a | |||
| 655ff5a50e | |||
| e3bc0ecc4e | |||
| b35fbae894 | |||
| 5cb8ad525f | |||
| 586f9950d2 | |||
| 14afba5f60 | |||
| 5b0dc979de | |||
| e270ac4c4d | |||
| 3afd7ed5e4 | |||
| e8d4a17265 | |||
| 6dc4f5f714 | |||
| f2447ad1dc | |||
| 6064dc8253 | |||
| 59cbbf845a | |||
| fac25d9a1f | |||
| 3a277a1658 | |||
| d23f8ee8da | |||
| 4dde26d7fd | |||
| c3bb0ec1f8 | |||
| a36035f4fa | |||
| b4ad468974 | |||
| 04ae04d928 | |||
| 24cd69c075 | |||
| 597d3c6433 | |||
| 3b588e39b3 | |||
| 60d273db6e | |||
| 7ee10516db | |||
| 9468b6e806 | |||
| 56d76705ff | |||
| 78593561d2 | |||
| 0075ae973c | |||
| 85384bbc1d | |||
| e322c39942 | |||
| 64e8560bca | |||
| ae99b8254e | |||
| c62274c103 | |||
| 70d449ba1c | |||
| a2987a4bea | |||
| 064af84e38 | |||
| 462543c95d | |||
| b1ff602e74 | |||
| 2d80083177 | |||
| f14d775a78 | |||
| f0083a3227 | |||
| a0011f8e90 | |||
| 04ce2a3be9 | |||
| a10816efd4 | |||
| d47d1cc221 | |||
| 79a2005505 | |||
| 5f7a28ff3a | |||
| 5029179b83 | |||
| 8d65a9e01e | |||
| e00fc4461c | |||
| 1bfb6f49e1 | |||
| 40db9f36d5 | |||
| c2f1c033c8 | |||
| d8764a7be6 | |||
| 33879662e8 | |||
| 6be21169c6 | |||
| 2f00fa57b2 | |||
| 7a8780a59a | |||
| 230e07cc83 | |||
| 5dd9e4ae24 | |||
| 3194d9fcc9 | |||
| 5145a38e8d | |||
| c32eff2947 | |||
| 4070552d36 | |||
| ad1c024455 | |||
| 66b3f9689d | |||
| 7598debcf6 | |||
| 41a24aeffd | |||
| 515bf1de51 | |||
| 014be09d5b | |||
| a5072c457c | |||
| dab245a415 | |||
| ad88999c7b | |||
| 1ab959d8a8 | |||
| 92028763ad | |||
| cd43c68dc6 | |||
| 714ba82c0c | |||
| fee323588e | |||
| d906b07c55 | |||
| 20739d6df5 | |||
| ffd404ff6b | |||
| b99ec7b5ca | |||
| ee66c66521 | |||
| 6e0ee1d079 | |||
| cda4216d0d | |||
| c2dd0a827c | |||
| 9a7d04b684 | |||
| d90cd52913 | |||
| ce7ff64000 | |||
| 5f37a4d360 | |||
| 4215498fbc | |||
| f15b095e15 | |||
| 1e0c22e364 | |||
| fa66666033 | |||
| b034f195d3 | |||
| 8b943730b4 | |||
| fae4cbfb80 | |||
| a4966c12e6 | |||
| 378befbf4f | |||
| c9292ca9c3 | |||
| 579917ff58 | |||
| 399da05c61 | |||
| 09d7f1f9e4 | |||
| 7e6b7ba6f4 | |||
| aad109b533 | |||
| 61f9470d84 | |||
| 311789b4dc | |||
| 6c52fec789 | |||
| 8b18c901f4 | |||
| a50ae54c6a | |||
| 6026246a4b | |||
| 51f9006a59 | |||
| 7c37a54bb2 | |||
| 537c0a03d5 | |||
| 6e5552d929 | |||
| 58edda4a9c | |||
| 78a32cacc9 | |||
| 2a77a97cc2 | |||
| 07f41ae7d1 | |||
| f222b97ca1 | |||
| 48387caea9 | |||
| 8832fc1a0c | |||
| da76a7a174 | |||
| e5165b8aa5 | |||
| 28b52a7114 | |||
| 8f4bf262b6 | |||
| c83351c201 | |||
| e9306c8965 | |||
| b0ca0c79db | |||
| 71912aeb1d | |||
| 62827cfefe | |||
| bfd209d238 | |||
| a6359e176a | |||
| 25378ac9e0 | |||
| 0fc9bc54af | |||
| d89734a682 | |||
| 318377993c | |||
| 97ed959b62 | |||
| de40dd7802 | |||
| a6d032db7b | |||
| 9453a0c4f7 | |||
| 39138f818b | |||
| ba62daa43c | |||
| c502a8a06d | |||
| 952b837a09 | |||
| 4aa8a67e99 | |||
| 0f1a234076 | |||
| 1b61c97a44 | |||
| 43424a4727 | |||
| c5809e2f71 | |||
| 632bbd399b | |||
| 966f8e737d | |||
| d6297d2300 | |||
| a85ce60704 | |||
| b17f01425c | |||
| 1573b011b6 | |||
| 584394be4f | |||
| 5f568e7516 | |||
| 188a96bb4b | |||
| f066f4ff4b | |||
| 285a04853f | |||
| 255f810b6c | |||
| 84b8501b63 | |||
| 3e51248aae | |||
| 2054b39cc7 | |||
| 979ba19958 | |||
| 00d469ca9b | |||
| 268367bfbe | |||
| f7f6143f34 | |||
| df7428f8c0 | |||
| 019742bfc7 | |||
| 6d20008857 | |||
| 86adf5093f | |||
| 7c9ebe1960 | |||
| ef606e38ac | |||
| b6dce69805 | |||
| c005814613 | |||
| 324048d709 | |||
| 12ef17ec90 | |||
| c856b29933 | |||
| 4e56c56985 | |||
| f85964f2f9 | |||
| 548b38924b | |||
| 5665d02cab | |||
| 5ae1252bff | |||
| 3cc9ddcb02 | |||
| 8a01f9c741 | |||
| 3ed95dec20 | |||
| 3d33bb4061 | |||
| 1838ebd9cd | |||
| e7058383cf | |||
| cafbd3efb4 | |||
| 02fade4c5c | |||
| ecdfacd8e4 | |||
| 4a37a54f24 | |||
| 82d1d32149 | |||
| ea189b85c5 | |||
| 75e5f6846f | |||
| d25ee99dd6 | |||
| ffef2ffef3 | |||
| eef7a42501 | |||
| 01231010cd | |||
| 90448fe9b4 | |||
| 8808da5225 | |||
| 679f8f7f6b | |||
| e258f01e0a | |||
| da117c191f | |||
| 4072b6e285 | |||
| dfda44c635 | |||
| 130c172a6e | |||
| 926d6f4a4b | |||
| 286c26359d | |||
| bf6c081869 | |||
| 981103e54c | |||
| 16c1b736bc | |||
| 6dabdf1ec1 | |||
| d4e88e28cb | |||
| 4fad188807 | |||
| 399ea5b117 | |||
| 6fd991a0d7 | |||
| 88b1559ad9 | |||
| 197e0205c6 | |||
| bdc136b184 | |||
| f98574a483 | |||
| b4e463ed21 | |||
| 36a4d7e200 | |||
| 892404fd59 | |||
| 73bb8b00a5 | |||
| 54442f56cc | |||
| bc3640c776 | |||
| c659231e85 | |||
| 2b7efb3d9b | |||
| 6e1200ec0f | |||
| 34f63d94e1 | |||
| 23c8f0c3a1 | |||
| b7b1cc74eb | |||
| a06c6488a4 | |||
| 80bed1dec2 | |||
| e31b8f21f8 | |||
| 85cd25741a | |||
| 3c01156ea9 | |||
| 45bd2f28e3 | |||
| 71de23ce43 | |||
| e2c081dd98 | |||
| 040cd69ecf | |||
| 6f44f74028 | |||
| c4bfa99597 | |||
| 57cb115ac4 | |||
| fa5214c4bc | |||
| 84ad0d4072 | |||
| 8b9cfb3082 | |||
| df71dd575e | |||
| 23d42e1883 | |||
| 6ee6c36483 | |||
| 1e67f88a7f | |||
| d616b26fc0 | |||
| c291842226 | |||
| 544352a288 | |||
| 33e0f03c37 | |||
| 333053deb8 | |||
| 5a18717615 | |||
| 6719ad01f0 | |||
| 9d35a3842b | |||
| 5f73e4d1c2 | |||
| 0cca4e0852 | |||
| a823528eef | |||
| 3c413f3088 | |||
| d155da245a | |||
| 5908b3a07b | |||
| b09c054c32 | |||
| 88c207d285 | |||
| 442e55e14b | |||
| 3be88f7d38 | |||
| 955f1bede9 | |||
| ededc79153 | |||
| 1f3c0bd922 | |||
| 143c29ea10 | |||
| 1250da259d | |||
| 2e549a3825 | |||
| 7aa352d1ca | |||
| 94f82683de | |||
| 849b7cefa5 | |||
| f891adfaa9 | |||
| b29818cb96 | |||
| 21fdd1364c | |||
| 966790eb47 | |||
| 6b3dd56772 | |||
| 10f89bd445 | |||
| 32f580eca9 | |||
| b858656fde | |||
| accc78709c | |||
| 6c4aafb174 | |||
| 2ac8d2c5fd | |||
| fdd7a43d96 | |||
| c3cb9e042a | |||
| 1194bafcad | |||
| 22124fc530 | |||
| 39d3e3e0f2 | |||
| 9ff14d9f08 | |||
| 65a7fa342c | |||
| 360ccab3df | |||
| a05adeb264 | |||
| c14dbe8fd5 |
@@ -57,7 +57,7 @@ Develop your changes in your fork<a name="develop"></a>
|
||||
|
||||
Develop your changes using your normal development process. If you
|
||||
already have code from an existing project, you may need to adjust its
|
||||
style to more closely match that in the ResearchKit framework.
|
||||
style to more closely match the [ResearchKit framework coding style](./docs-standalone/coding-style-guide.md).
|
||||
|
||||
New components may need to expose new Public or Private
|
||||
headers. Public headers are for APIs that are likely to be a stable
|
||||
@@ -160,21 +160,22 @@ The `master` branch is used for work in progress. On `master`:
|
||||
project:
|
||||
|
||||
1. If you are submitting a patch to the existing codebase, you
|
||||
represent that you have the right to license the patch to the
|
||||
community, and agree by submitting the patch that your changes are
|
||||
represent that you have the right to license the patch, including
|
||||
all code and content, to Apple and the community, and agree by
|
||||
submitting the patch that your changes are
|
||||
licensed under the existing license terms of the file you are
|
||||
modifying (i.e., [ResearchKit BSD license](LICENSE)).
|
||||
Please also add your copyright (name and year) to the relevant
|
||||
files for changes that are more than 10 lines of code.
|
||||
2. If you are submitting a new file for inclusion in the ResearchKit framework (no
|
||||
code copied from another source), please include your copyright (name
|
||||
and year) and a copy of the ResearchKit BSD license. By submitting
|
||||
your new file you represent that you have the right to license your
|
||||
file to the community, and agree that your file is licensed under the
|
||||
ResearchKit BSD license.
|
||||
3. If you aren't the author of the patch, you agree to include the
|
||||
original copyright notices and licensing terms with it, to the extent
|
||||
that they exist. If there wasn't a copyright notice or license,
|
||||
please make a note of it. Generally we can only take in patches that
|
||||
are BSD-licensed in order to maintain license compatibility within the
|
||||
project.
|
||||
You confirm that you have added your copyright (name and year) to
|
||||
the relevant files for changes that are more than 10 lines of code.
|
||||
2. If you are submitting a new file for inclusion in the ResearchKit
|
||||
framework (no code or other content is copied from another source), you
|
||||
have included your copyright (name and year) and a copy of the ResearchKit
|
||||
BSD license. By submitting your new file you represent that you have the
|
||||
right to license your file to Apple and the community, and agree that your
|
||||
file submission is licensed under the ResearchKit BSD license.
|
||||
3. If you aren't the author of the patch, you agree that you have
|
||||
the right to submit the patch, and have included the original copyright
|
||||
notices and licensing terms with it, to the extent that they exist.
|
||||
If there wasn't a copyright notice or license, please make a note of it
|
||||
in your response. Generally we can only take in patches that are
|
||||
BSD-licensed in order to maintain license compatibility within the project.
|
||||
|
||||
@@ -55,7 +55,7 @@ Getting Started<a name="gettingstarted"></a>
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The primary ResearchKit framework codebase supports iOS and requires Xcode 6.3
|
||||
The primary ResearchKit framework codebase supports iOS and requires Xcode 7.0
|
||||
or newer. The ResearchKit framework has a Base SDK version of 8.0, meaning that apps
|
||||
using the ResearchKit framework can run on devices with iOS 8.0 or newer.
|
||||
|
||||
@@ -110,7 +110,7 @@ target as shown in the figure below.
|
||||
</figure>
|
||||
</center>
|
||||
|
||||
Note: You can also import ResearchKit into your project using a [dependency manager](./dependency_management.md) such as CocoaPods or Carthage.
|
||||
Note: You can also import ResearchKit into your project using a [dependency manager](./docs-standalone/dependency-management.md) such as CocoaPods or Carthage.
|
||||
|
||||
###2. Create a Step
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'ResearchKit'
|
||||
s.version = '1.1.1'
|
||||
s.version = '1.2.1'
|
||||
s.summary = 'ResearchKit is an open source software framework that makes it easy to create apps for medical research or for other research projects.'
|
||||
s.homepage = 'https://www.github.com/ResearchKit/ResearchKit'
|
||||
s.documentation_url = 'http://researchkit.github.io/docs/'
|
||||
|
||||
@@ -22,6 +22,16 @@
|
||||
/* End PBXAggregateTarget section */
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
10864C9E1B27146B000F4158 /* ORKPSATStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 10864C961B27146B000F4158 /* ORKPSATStep.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
10864C9F1B27146B000F4158 /* ORKPSATStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 10864C971B27146B000F4158 /* ORKPSATStep.m */; };
|
||||
10864CA01B27146B000F4158 /* ORKPSATStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 10864C981B27146B000F4158 /* ORKPSATStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
10864CA11B27146B000F4158 /* ORKPSATStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 10864C991B27146B000F4158 /* ORKPSATStepViewController.m */; };
|
||||
10864CA21B27146B000F4158 /* ORKPSATContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 10864C9A1B27146B000F4158 /* ORKPSATContentView.h */; };
|
||||
10864CA31B27146B000F4158 /* ORKPSATContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 10864C9B1B27146B000F4158 /* ORKPSATContentView.m */; };
|
||||
10864CA41B27146B000F4158 /* ORKPSATKeyboardView.h in Headers */ = {isa = PBXBuildFile; fileRef = 10864C9C1B27146B000F4158 /* ORKPSATKeyboardView.h */; };
|
||||
10864CA51B27146B000F4158 /* ORKPSATKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 10864C9D1B27146B000F4158 /* ORKPSATKeyboardView.m */; };
|
||||
10BAA2CA1B5FCB4F004FE478 /* ORKProgressView.h in Headers */ = {isa = PBXBuildFile; fileRef = 10BAA2C81B5FCB4F004FE478 /* ORKProgressView.h */; };
|
||||
10BAA2CB1B5FCB4F004FE478 /* ORKProgressView.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BAA2C91B5FCB4F004FE478 /* ORKProgressView.m */; };
|
||||
147503AF1AEE8071004B17F3 /* ORKAudioGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 147503AD1AEE8071004B17F3 /* ORKAudioGenerator.h */; };
|
||||
147503B01AEE8071004B17F3 /* ORKAudioGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 147503AE1AEE8071004B17F3 /* ORKAudioGenerator.m */; };
|
||||
147503B71AEE807C004B17F3 /* ORKToneAudiometryContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 147503B11AEE807C004B17F3 /* ORKToneAudiometryContentView.h */; };
|
||||
@@ -30,6 +40,17 @@
|
||||
147503BA1AEE807C004B17F3 /* ORKToneAudiometryStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 147503B41AEE807C004B17F3 /* ORKToneAudiometryStep.m */; };
|
||||
147503BB1AEE807C004B17F3 /* ORKToneAudiometryStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 147503B51AEE807C004B17F3 /* ORKToneAudiometryStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
147503BC1AEE807C004B17F3 /* ORKToneAudiometryStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 147503B61AEE807C004B17F3 /* ORKToneAudiometryStepViewController.m */; };
|
||||
248604061B4C98760010C8A0 /* ORKAnswerFormatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 248604051B4C98760010C8A0 /* ORKAnswerFormatTests.m */; };
|
||||
24898B0D1B7186C000B0E7E7 /* ORKScaleRangeImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 24898B0B1B7186C000B0E7E7 /* ORKScaleRangeImageView.h */; };
|
||||
24898B0E1B7186C000B0E7E7 /* ORKScaleRangeImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 24898B0C1B7186C000B0E7E7 /* ORKScaleRangeImageView.m */; };
|
||||
250F94041B4C5A6600FA23EB /* ORKTowerOfHanoiStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 250F94021B4C5A6600FA23EB /* ORKTowerOfHanoiStep.h */; };
|
||||
250F94051B4C5A6600FA23EB /* ORKTowerOfHanoiStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 250F94031B4C5A6600FA23EB /* ORKTowerOfHanoiStep.m */; };
|
||||
250F94081B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 250F94061B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.h */; };
|
||||
250F94091B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 250F94071B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.m */; };
|
||||
257FCE1F1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 257FCE1D1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.h */; };
|
||||
257FCE201B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 257FCE1E1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.m */; };
|
||||
257FCE231B4D37A80001EF06 /* ORKTowerOfHanoiTower.h in Headers */ = {isa = PBXBuildFile; fileRef = 257FCE211B4D37A80001EF06 /* ORKTowerOfHanoiTower.h */; };
|
||||
257FCE241B4D37A80001EF06 /* ORKTowerOfHanoiTower.m in Sources */ = {isa = PBXBuildFile; fileRef = 257FCE221B4D37A80001EF06 /* ORKTowerOfHanoiTower.m */; };
|
||||
25ECC0951AFBD68300F3D63B /* ORKReactionTimeStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 25ECC0931AFBD68300F3D63B /* ORKReactionTimeStep.h */; };
|
||||
25ECC0961AFBD68300F3D63B /* ORKReactionTimeStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 25ECC0941AFBD68300F3D63B /* ORKReactionTimeStep.m */; };
|
||||
25ECC09B1AFBD8B300F3D63B /* ORKReactionTimeViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 25ECC0991AFBD8B300F3D63B /* ORKReactionTimeViewController.h */; };
|
||||
@@ -40,6 +61,8 @@
|
||||
25ECC0A41AFBDD2700F3D63B /* ORKReactionTimeStimulusView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25ECC0A21AFBDD2700F3D63B /* ORKReactionTimeStimulusView.m */; };
|
||||
2EBFE11D1AE1B32D00CB8254 /* ORKUIViewAccessibilityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EBFE11C1AE1B32D00CB8254 /* ORKUIViewAccessibilityTests.m */; };
|
||||
2EBFE1201AE1B74100CB8254 /* ORKVoiceEngineTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EBFE11F1AE1B74100CB8254 /* ORKVoiceEngineTests.m */; };
|
||||
6146D0A31B84A91E0068491D /* ORKLineGraphAccessibilityElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6146D0A11B84A91E0068491D /* ORKLineGraphAccessibilityElement.h */; };
|
||||
6146D0A41B84A91E0068491D /* ORKLineGraphAccessibilityElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 6146D0A21B84A91E0068491D /* ORKLineGraphAccessibilityElement.m */; };
|
||||
618DA04E1A93D0D600E63AA8 /* ORKAccessibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 618DA0481A93D0D600E63AA8 /* ORKAccessibility.h */; };
|
||||
618DA0501A93D0D600E63AA8 /* ORKAccessibilityFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 618DA0491A93D0D600E63AA8 /* ORKAccessibilityFunctions.h */; };
|
||||
618DA0521A93D0D600E63AA8 /* ORKAccessibilityFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 618DA04A1A93D0D600E63AA8 /* ORKAccessibilityFunctions.m */; };
|
||||
@@ -51,6 +74,13 @@
|
||||
861D11AE1AA7951F003C98A7 /* ORKChoiceAnswerFormatHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 861D11AC1AA7951F003C98A7 /* ORKChoiceAnswerFormatHelper.m */; };
|
||||
861D11B51AA7D073003C98A7 /* ORKTextChoiceCellGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 861D11B31AA7D073003C98A7 /* ORKTextChoiceCellGroup.h */; };
|
||||
861D11B61AA7D073003C98A7 /* ORKTextChoiceCellGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 861D11B41AA7D073003C98A7 /* ORKTextChoiceCellGroup.m */; };
|
||||
861D2AE81B840991008C4CD0 /* ORKTimedWalkStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 861D2AE61B840991008C4CD0 /* ORKTimedWalkStep.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
861D2AE91B840991008C4CD0 /* ORKTimedWalkStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 861D2AE71B840991008C4CD0 /* ORKTimedWalkStep.m */; };
|
||||
861D2AEC1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 861D2AEA1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
861D2AED1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 861D2AEB1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.m */; };
|
||||
861D2AF01B8409D9008C4CD0 /* ORKTimedWalkContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 861D2AEE1B8409D9008C4CD0 /* ORKTimedWalkContentView.h */; };
|
||||
861D2AF11B8409D9008C4CD0 /* ORKTimedWalkContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 861D2AEF1B8409D9008C4CD0 /* ORKTimedWalkContentView.m */; };
|
||||
861D2AF71B843968008C4CD0 /* ORKCompletionStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B551A8D7C5B00081FAC /* ORKCompletionStepViewController.m */; };
|
||||
865EA1621AB8DF750037C68E /* ORKDateTimePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 865EA1601AB8DF750037C68E /* ORKDateTimePicker.h */; };
|
||||
865EA1631AB8DF750037C68E /* ORKDateTimePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 865EA1611AB8DF750037C68E /* ORKDateTimePicker.m */; };
|
||||
865EA1681ABA1AA10037C68E /* ORKPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 865EA1661ABA1AA10037C68E /* ORKPicker.h */; };
|
||||
@@ -162,7 +192,6 @@
|
||||
86C40CC01A8D7C5C00081FAC /* ORKCompletionStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B521A8D7C5B00081FAC /* ORKCompletionStep.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
86C40CC21A8D7C5C00081FAC /* ORKCompletionStep.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B531A8D7C5B00081FAC /* ORKCompletionStep.m */; };
|
||||
86C40CC41A8D7C5C00081FAC /* ORKCompletionStepViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B541A8D7C5B00081FAC /* ORKCompletionStepViewController.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
86C40CC61A8D7C5C00081FAC /* ORKCompletionStepViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B551A8D7C5B00081FAC /* ORKCompletionStepViewController.m */; };
|
||||
86C40CC81A8D7C5C00081FAC /* ORKFormItemCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B561A8D7C5B00081FAC /* ORKFormItemCell.h */; };
|
||||
86C40CCA1A8D7C5C00081FAC /* ORKFormItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 86C40B571A8D7C5B00081FAC /* ORKFormItemCell.m */; };
|
||||
86C40CCC1A8D7C5C00081FAC /* ORKImageSelectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C40B581A8D7C5B00081FAC /* ORKImageSelectionView.h */; };
|
||||
@@ -360,7 +389,7 @@
|
||||
B1A860F61A9693C400EA57B7 /* consent_06@3x.m4v in Resources */ = {isa = PBXBuildFile; fileRef = B1A860E81A9693C400EA57B7 /* consent_06@3x.m4v */; };
|
||||
B1A860F71A9693C400EA57B7 /* consent_07@3x.m4v in Resources */ = {isa = PBXBuildFile; fileRef = B1A860E91A9693C400EA57B7 /* consent_07@3x.m4v */; };
|
||||
B1C0F4E41A9BA65F0022C153 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B1C0F4E11A9BA65F0022C153 /* Localizable.strings */; };
|
||||
B1C7955E1A9FBF04007279BA /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1C7955D1A9FBF04007279BA /* HealthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
B1C7955E1A9FBF04007279BA /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1C7955D1A9FBF04007279BA /* HealthKit.framework */; settings = {ATTRIBUTES = (Required, ); }; };
|
||||
B8760F2B1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = B8760F291AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.h */; };
|
||||
B8760F2C1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = B8760F2A1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.m */; };
|
||||
BC01B0FB1B0EB99700863803 /* ORKTintedImageView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BC01B0FA1B0EB99700863803 /* ORKTintedImageView_Internal.h */; };
|
||||
@@ -375,7 +404,33 @@
|
||||
BCA5C0351AEC05F20092AC8D /* ORKStepNavigationRule.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA5C0331AEC05F20092AC8D /* ORKStepNavigationRule.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
BCA5C0361AEC05F20092AC8D /* ORKStepNavigationRule.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA5C0341AEC05F20092AC8D /* ORKStepNavigationRule.m */; };
|
||||
BCAD50E81B0201EE0034806A /* ORKTaskTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAD50E71B0201EE0034806A /* ORKTaskTests.m */; };
|
||||
BCB6E64A1B7D531C000D5B34 /* ORKPieChartView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E6481B7D531C000D5B34 /* ORKPieChartView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
BCB6E64B1B7D531C000D5B34 /* ORKPieChartView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E6491B7D531C000D5B34 /* ORKPieChartView.m */; };
|
||||
BCB6E6501B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E64C1B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.h */; };
|
||||
BCB6E6511B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E64D1B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.m */; };
|
||||
BCB6E6521B7D533B000D5B34 /* ORKPieChartLegendCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E64E1B7D533B000D5B34 /* ORKPieChartLegendCell.h */; };
|
||||
BCB6E6531B7D533B000D5B34 /* ORKPieChartLegendCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E64F1B7D533B000D5B34 /* ORKPieChartLegendCell.m */; };
|
||||
BCB6E65B1B7D534C000D5B34 /* ORKDiscreteGraphChartView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E6541B7D534C000D5B34 /* ORKDiscreteGraphChartView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
BCB6E65C1B7D534C000D5B34 /* ORKDiscreteGraphChartView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E6551B7D534C000D5B34 /* ORKDiscreteGraphChartView.m */; };
|
||||
BCB6E65D1B7D534C000D5B34 /* ORKGraphChartView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E6561B7D534C000D5B34 /* ORKGraphChartView_Internal.h */; };
|
||||
BCB6E65E1B7D534C000D5B34 /* ORKGraphChartView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E6571B7D534C000D5B34 /* ORKGraphChartView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
BCB6E65F1B7D534C000D5B34 /* ORKGraphChartView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E6581B7D534C000D5B34 /* ORKGraphChartView.m */; };
|
||||
BCB6E6601B7D534C000D5B34 /* ORKLineGraphChartView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E6591B7D534C000D5B34 /* ORKLineGraphChartView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
BCB6E6611B7D534C000D5B34 /* ORKLineGraphChartView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E65A1B7D534C000D5B34 /* ORKLineGraphChartView.m */; };
|
||||
BCB6E6661B7D535F000D5B34 /* ORKXAxisView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E6621B7D535F000D5B34 /* ORKXAxisView.h */; };
|
||||
BCB6E6671B7D535F000D5B34 /* ORKXAxisView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E6631B7D535F000D5B34 /* ORKXAxisView.m */; };
|
||||
BCB6E66C1B7D537B000D5B34 /* ORKRangedPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = BCB6E66A1B7D537B000D5B34 /* ORKRangedPoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
BCB6E66D1B7D537B000D5B34 /* ORKRangedPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB6E66B1B7D537B000D5B34 /* ORKRangedPoint.m */; };
|
||||
BCB96C131B19C0EC002A0B96 /* ORKStepTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB96C121B19C0EC002A0B96 /* ORKStepTests.m */; };
|
||||
BCC1CD9A1B7ED64F00D86886 /* ORKYAxisView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCC1CD981B7ED64F00D86886 /* ORKYAxisView.h */; };
|
||||
BCC1CD9B1B7ED64F00D86886 /* ORKYAxisView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC1CD991B7ED64F00D86886 /* ORKYAxisView.m */; };
|
||||
BCD192DF1B81240400FCC08A /* ORKPieChartPieView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD192DD1B81240400FCC08A /* ORKPieChartPieView.h */; };
|
||||
BCD192E01B81240400FCC08A /* ORKPieChartPieView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD192DE1B81240400FCC08A /* ORKPieChartPieView.m */; };
|
||||
BCD192E71B81243900FCC08A /* ORKPieChartLegendView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD192E51B81243900FCC08A /* ORKPieChartLegendView.h */; };
|
||||
BCD192E81B81243900FCC08A /* ORKPieChartLegendView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD192E61B81243900FCC08A /* ORKPieChartLegendView.m */; };
|
||||
BCD192EB1B81245500FCC08A /* ORKPieChartTitleTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD192E91B81245500FCC08A /* ORKPieChartTitleTextView.h */; };
|
||||
BCD192EC1B81245500FCC08A /* ORKPieChartTitleTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD192EA1B81245500FCC08A /* ORKPieChartTitleTextView.m */; };
|
||||
BCD192EE1B81255F00FCC08A /* ORKPieChartView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD192ED1B81255F00FCC08A /* ORKPieChartView_Internal.h */; };
|
||||
BCFF24BD1B0798D10044EC35 /* ORKResultPredicate.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFF24BC1B0798D10044EC35 /* ORKResultPredicate.m */; };
|
||||
D42FEFB81AF7557000A124F8 /* ORKImageCaptureView.h in Headers */ = {isa = PBXBuildFile; fileRef = D42FEFB61AF7557000A124F8 /* ORKImageCaptureView.h */; };
|
||||
D42FEFB91AF7557000A124F8 /* ORKImageCaptureView.m in Sources */ = {isa = PBXBuildFile; fileRef = D42FEFB71AF7557000A124F8 /* ORKImageCaptureView.m */; };
|
||||
@@ -412,6 +467,16 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
10864C961B27146B000F4158 /* ORKPSATStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPSATStep.h; sourceTree = "<group>"; };
|
||||
10864C971B27146B000F4158 /* ORKPSATStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKPSATStep.m; sourceTree = "<group>"; };
|
||||
10864C981B27146B000F4158 /* ORKPSATStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPSATStepViewController.h; sourceTree = "<group>"; };
|
||||
10864C991B27146B000F4158 /* ORKPSATStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKPSATStepViewController.m; sourceTree = "<group>"; };
|
||||
10864C9A1B27146B000F4158 /* ORKPSATContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPSATContentView.h; sourceTree = "<group>"; };
|
||||
10864C9B1B27146B000F4158 /* ORKPSATContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKPSATContentView.m; sourceTree = "<group>"; };
|
||||
10864C9C1B27146B000F4158 /* ORKPSATKeyboardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPSATKeyboardView.h; sourceTree = "<group>"; };
|
||||
10864C9D1B27146B000F4158 /* ORKPSATKeyboardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKPSATKeyboardView.m; sourceTree = "<group>"; };
|
||||
10BAA2C81B5FCB4F004FE478 /* ORKProgressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKProgressView.h; sourceTree = "<group>"; };
|
||||
10BAA2C91B5FCB4F004FE478 /* ORKProgressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKProgressView.m; sourceTree = "<group>"; };
|
||||
147503AD1AEE8071004B17F3 /* ORKAudioGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKAudioGenerator.h; sourceTree = "<group>"; };
|
||||
147503AE1AEE8071004B17F3 /* ORKAudioGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKAudioGenerator.m; sourceTree = "<group>"; };
|
||||
147503B11AEE807C004B17F3 /* ORKToneAudiometryContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKToneAudiometryContentView.h; sourceTree = "<group>"; };
|
||||
@@ -420,6 +485,17 @@
|
||||
147503B41AEE807C004B17F3 /* ORKToneAudiometryStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKToneAudiometryStep.m; sourceTree = "<group>"; };
|
||||
147503B51AEE807C004B17F3 /* ORKToneAudiometryStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKToneAudiometryStepViewController.h; sourceTree = "<group>"; };
|
||||
147503B61AEE807C004B17F3 /* ORKToneAudiometryStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKToneAudiometryStepViewController.m; sourceTree = "<group>"; };
|
||||
248604051B4C98760010C8A0 /* ORKAnswerFormatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKAnswerFormatTests.m; sourceTree = "<group>"; };
|
||||
24898B0B1B7186C000B0E7E7 /* ORKScaleRangeImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKScaleRangeImageView.h; sourceTree = "<group>"; };
|
||||
24898B0C1B7186C000B0E7E7 /* ORKScaleRangeImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKScaleRangeImageView.m; sourceTree = "<group>"; };
|
||||
250F94021B4C5A6600FA23EB /* ORKTowerOfHanoiStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTowerOfHanoiStep.h; sourceTree = "<group>"; };
|
||||
250F94031B4C5A6600FA23EB /* ORKTowerOfHanoiStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTowerOfHanoiStep.m; sourceTree = "<group>"; };
|
||||
250F94061B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTowerOfHanoiStepViewController.h; sourceTree = "<group>"; };
|
||||
250F94071B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTowerOfHanoiStepViewController.m; sourceTree = "<group>"; };
|
||||
257FCE1D1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTowerOfHanoiTowerView.h; sourceTree = "<group>"; };
|
||||
257FCE1E1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTowerOfHanoiTowerView.m; sourceTree = "<group>"; };
|
||||
257FCE211B4D37A80001EF06 /* ORKTowerOfHanoiTower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTowerOfHanoiTower.h; sourceTree = "<group>"; };
|
||||
257FCE221B4D37A80001EF06 /* ORKTowerOfHanoiTower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTowerOfHanoiTower.m; sourceTree = "<group>"; };
|
||||
25ECC0931AFBD68300F3D63B /* ORKReactionTimeStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKReactionTimeStep.h; sourceTree = "<group>"; };
|
||||
25ECC0941AFBD68300F3D63B /* ORKReactionTimeStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKReactionTimeStep.m; sourceTree = "<group>"; };
|
||||
25ECC0991AFBD8B300F3D63B /* ORKReactionTimeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKReactionTimeViewController.h; sourceTree = "<group>"; };
|
||||
@@ -431,6 +507,8 @@
|
||||
2EBFE11C1AE1B32D00CB8254 /* ORKUIViewAccessibilityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKUIViewAccessibilityTests.m; sourceTree = "<group>"; };
|
||||
2EBFE11E1AE1B68800CB8254 /* ORKVoiceEngine_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKVoiceEngine_Internal.h; sourceTree = "<group>"; };
|
||||
2EBFE11F1AE1B74100CB8254 /* ORKVoiceEngineTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKVoiceEngineTests.m; sourceTree = "<group>"; };
|
||||
6146D0A11B84A91E0068491D /* ORKLineGraphAccessibilityElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKLineGraphAccessibilityElement.h; sourceTree = "<group>"; };
|
||||
6146D0A21B84A91E0068491D /* ORKLineGraphAccessibilityElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKLineGraphAccessibilityElement.m; sourceTree = "<group>"; };
|
||||
618DA0481A93D0D600E63AA8 /* ORKAccessibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKAccessibility.h; sourceTree = "<group>"; };
|
||||
618DA0491A93D0D600E63AA8 /* ORKAccessibilityFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKAccessibilityFunctions.h; sourceTree = "<group>"; };
|
||||
618DA04A1A93D0D600E63AA8 /* ORKAccessibilityFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKAccessibilityFunctions.m; sourceTree = "<group>"; };
|
||||
@@ -443,6 +521,12 @@
|
||||
861D11AC1AA7951F003C98A7 /* ORKChoiceAnswerFormatHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKChoiceAnswerFormatHelper.m; sourceTree = "<group>"; };
|
||||
861D11B31AA7D073003C98A7 /* ORKTextChoiceCellGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKTextChoiceCellGroup.h; sourceTree = "<group>"; };
|
||||
861D11B41AA7D073003C98A7 /* ORKTextChoiceCellGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTextChoiceCellGroup.m; sourceTree = "<group>"; };
|
||||
861D2AE61B840991008C4CD0 /* ORKTimedWalkStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKTimedWalkStep.h; path = ResearchKit/ActiveTasks/ORKTimedWalkStep.h; sourceTree = SOURCE_ROOT; };
|
||||
861D2AE71B840991008C4CD0 /* ORKTimedWalkStep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKTimedWalkStep.m; path = ResearchKit/ActiveTasks/ORKTimedWalkStep.m; sourceTree = SOURCE_ROOT; };
|
||||
861D2AEA1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKTimedWalkStepViewController.h; path = ResearchKit/ActiveTasks/ORKTimedWalkStepViewController.h; sourceTree = SOURCE_ROOT; };
|
||||
861D2AEB1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKTimedWalkStepViewController.m; path = ResearchKit/ActiveTasks/ORKTimedWalkStepViewController.m; sourceTree = SOURCE_ROOT; };
|
||||
861D2AEE1B8409D9008C4CD0 /* ORKTimedWalkContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKTimedWalkContentView.h; path = ResearchKit/ActiveTasks/ORKTimedWalkContentView.h; sourceTree = SOURCE_ROOT; };
|
||||
861D2AEF1B8409D9008C4CD0 /* ORKTimedWalkContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKTimedWalkContentView.m; path = ResearchKit/ActiveTasks/ORKTimedWalkContentView.m; sourceTree = SOURCE_ROOT; };
|
||||
865EA1601AB8DF750037C68E /* ORKDateTimePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKDateTimePicker.h; sourceTree = "<group>"; };
|
||||
865EA1611AB8DF750037C68E /* ORKDateTimePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ORKDateTimePicker.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
|
||||
865EA1661ABA1AA10037C68E /* ORKPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKPicker.h; sourceTree = "<group>"; };
|
||||
@@ -809,7 +893,33 @@
|
||||
BCA5C0331AEC05F20092AC8D /* ORKStepNavigationRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKStepNavigationRule.h; sourceTree = "<group>"; };
|
||||
BCA5C0341AEC05F20092AC8D /* ORKStepNavigationRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKStepNavigationRule.m; sourceTree = "<group>"; };
|
||||
BCAD50E71B0201EE0034806A /* ORKTaskTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKTaskTests.m; sourceTree = "<group>"; };
|
||||
BCB6E6481B7D531C000D5B34 /* ORKPieChartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartView.h; path = Charts/ORKPieChartView.h; sourceTree = "<group>"; };
|
||||
BCB6E6491B7D531C000D5B34 /* ORKPieChartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKPieChartView.m; path = Charts/ORKPieChartView.m; sourceTree = "<group>"; };
|
||||
BCB6E64C1B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKCenteredCollectionViewLayout.h; path = Charts/ORKCenteredCollectionViewLayout.h; sourceTree = "<group>"; };
|
||||
BCB6E64D1B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKCenteredCollectionViewLayout.m; path = Charts/ORKCenteredCollectionViewLayout.m; sourceTree = "<group>"; };
|
||||
BCB6E64E1B7D533B000D5B34 /* ORKPieChartLegendCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartLegendCell.h; path = Charts/ORKPieChartLegendCell.h; sourceTree = "<group>"; };
|
||||
BCB6E64F1B7D533B000D5B34 /* ORKPieChartLegendCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKPieChartLegendCell.m; path = Charts/ORKPieChartLegendCell.m; sourceTree = "<group>"; };
|
||||
BCB6E6541B7D534C000D5B34 /* ORKDiscreteGraphChartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKDiscreteGraphChartView.h; path = Charts/ORKDiscreteGraphChartView.h; sourceTree = "<group>"; };
|
||||
BCB6E6551B7D534C000D5B34 /* ORKDiscreteGraphChartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKDiscreteGraphChartView.m; path = Charts/ORKDiscreteGraphChartView.m; sourceTree = "<group>"; };
|
||||
BCB6E6561B7D534C000D5B34 /* ORKGraphChartView_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKGraphChartView_Internal.h; path = Charts/ORKGraphChartView_Internal.h; sourceTree = "<group>"; };
|
||||
BCB6E6571B7D534C000D5B34 /* ORKGraphChartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKGraphChartView.h; path = Charts/ORKGraphChartView.h; sourceTree = "<group>"; };
|
||||
BCB6E6581B7D534C000D5B34 /* ORKGraphChartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKGraphChartView.m; path = Charts/ORKGraphChartView.m; sourceTree = "<group>"; };
|
||||
BCB6E6591B7D534C000D5B34 /* ORKLineGraphChartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKLineGraphChartView.h; path = Charts/ORKLineGraphChartView.h; sourceTree = "<group>"; };
|
||||
BCB6E65A1B7D534C000D5B34 /* ORKLineGraphChartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKLineGraphChartView.m; path = Charts/ORKLineGraphChartView.m; sourceTree = "<group>"; };
|
||||
BCB6E6621B7D535F000D5B34 /* ORKXAxisView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKXAxisView.h; path = Charts/ORKXAxisView.h; sourceTree = "<group>"; };
|
||||
BCB6E6631B7D535F000D5B34 /* ORKXAxisView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKXAxisView.m; path = Charts/ORKXAxisView.m; sourceTree = "<group>"; };
|
||||
BCB6E66A1B7D537B000D5B34 /* ORKRangedPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKRangedPoint.h; path = Charts/ORKRangedPoint.h; sourceTree = "<group>"; };
|
||||
BCB6E66B1B7D537B000D5B34 /* ORKRangedPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKRangedPoint.m; path = Charts/ORKRangedPoint.m; sourceTree = "<group>"; };
|
||||
BCB96C121B19C0EC002A0B96 /* ORKStepTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKStepTests.m; sourceTree = "<group>"; };
|
||||
BCC1CD981B7ED64F00D86886 /* ORKYAxisView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKYAxisView.h; path = Charts/ORKYAxisView.h; sourceTree = "<group>"; };
|
||||
BCC1CD991B7ED64F00D86886 /* ORKYAxisView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKYAxisView.m; path = Charts/ORKYAxisView.m; sourceTree = "<group>"; };
|
||||
BCD192DD1B81240400FCC08A /* ORKPieChartPieView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartPieView.h; path = Charts/ORKPieChartPieView.h; sourceTree = "<group>"; };
|
||||
BCD192DE1B81240400FCC08A /* ORKPieChartPieView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKPieChartPieView.m; path = Charts/ORKPieChartPieView.m; sourceTree = "<group>"; };
|
||||
BCD192E51B81243900FCC08A /* ORKPieChartLegendView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartLegendView.h; path = Charts/ORKPieChartLegendView.h; sourceTree = "<group>"; };
|
||||
BCD192E61B81243900FCC08A /* ORKPieChartLegendView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKPieChartLegendView.m; path = Charts/ORKPieChartLegendView.m; sourceTree = "<group>"; };
|
||||
BCD192E91B81245500FCC08A /* ORKPieChartTitleTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartTitleTextView.h; path = Charts/ORKPieChartTitleTextView.h; sourceTree = "<group>"; };
|
||||
BCD192EA1B81245500FCC08A /* ORKPieChartTitleTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORKPieChartTitleTextView.m; path = Charts/ORKPieChartTitleTextView.m; sourceTree = "<group>"; };
|
||||
BCD192ED1B81255F00FCC08A /* ORKPieChartView_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORKPieChartView_Internal.h; path = Charts/ORKPieChartView_Internal.h; sourceTree = "<group>"; };
|
||||
BCFB2EAF1AE70E4E0070B5D0 /* ORKConsentSceneViewController_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ORKConsentSceneViewController_Internal.h; sourceTree = "<group>"; };
|
||||
BCFF24BC1B0798D10044EC35 /* ORKResultPredicate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ORKResultPredicate.m; sourceTree = "<group>"; };
|
||||
D42FEFB61AF7557000A124F8 /* ORKImageCaptureView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ORKImageCaptureView.h; sourceTree = "<group>"; };
|
||||
@@ -849,6 +959,43 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
10864C951B271456000F4158 /* PSAT */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
10864C961B27146B000F4158 /* ORKPSATStep.h */,
|
||||
10864C971B27146B000F4158 /* ORKPSATStep.m */,
|
||||
10864C981B27146B000F4158 /* ORKPSATStepViewController.h */,
|
||||
10864C991B27146B000F4158 /* ORKPSATStepViewController.m */,
|
||||
10864C9A1B27146B000F4158 /* ORKPSATContentView.h */,
|
||||
10864C9B1B27146B000F4158 /* ORKPSATContentView.m */,
|
||||
10864C9C1B27146B000F4158 /* ORKPSATKeyboardView.h */,
|
||||
10864C9D1B27146B000F4158 /* ORKPSATKeyboardView.m */,
|
||||
);
|
||||
name = PSAT;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
10BAA2CC1B5FCDB1004FE478 /* Walking */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B12EFF601AB2178B00A80147 /* Short Walk */,
|
||||
10BAA2CD1B5FCDFB004FE478 /* Timed Walk */,
|
||||
);
|
||||
name = Walking;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
10BAA2CD1B5FCDFB004FE478 /* Timed Walk */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
861D2AEE1B8409D9008C4CD0 /* ORKTimedWalkContentView.h */,
|
||||
861D2AEF1B8409D9008C4CD0 /* ORKTimedWalkContentView.m */,
|
||||
861D2AEA1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.h */,
|
||||
861D2AEB1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.m */,
|
||||
861D2AE61B840991008C4CD0 /* ORKTimedWalkStep.h */,
|
||||
861D2AE71B840991008C4CD0 /* ORKTimedWalkStep.m */,
|
||||
);
|
||||
name = "Timed Walk";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
147503AC1AEE8058004B17F3 /* Tone Audiometry */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -868,6 +1015,71 @@
|
||||
name = "Tone Audiometry";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
259E76FB1AFFAEAC0070F786 /* Charts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
25BD76671B00B37100478C5D /* Pie */,
|
||||
25BD76601B00A5CF00478C5D /* Graphs */,
|
||||
);
|
||||
name = Charts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
25BD76601B00A5CF00478C5D /* Graphs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BCB6E66A1B7D537B000D5B34 /* ORKRangedPoint.h */,
|
||||
BCB6E66B1B7D537B000D5B34 /* ORKRangedPoint.m */,
|
||||
BCB6E6541B7D534C000D5B34 /* ORKDiscreteGraphChartView.h */,
|
||||
BCB6E6551B7D534C000D5B34 /* ORKDiscreteGraphChartView.m */,
|
||||
BCB6E6561B7D534C000D5B34 /* ORKGraphChartView_Internal.h */,
|
||||
BCB6E6571B7D534C000D5B34 /* ORKGraphChartView.h */,
|
||||
BCB6E6581B7D534C000D5B34 /* ORKGraphChartView.m */,
|
||||
BCB6E6591B7D534C000D5B34 /* ORKLineGraphChartView.h */,
|
||||
BCB6E65A1B7D534C000D5B34 /* ORKLineGraphChartView.m */,
|
||||
25BD76611B00A5E700478C5D /* Components */,
|
||||
);
|
||||
name = Graphs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
25BD76611B00A5E700478C5D /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BCC1CD981B7ED64F00D86886 /* ORKYAxisView.h */,
|
||||
BCC1CD991B7ED64F00D86886 /* ORKYAxisView.m */,
|
||||
BCB6E6621B7D535F000D5B34 /* ORKXAxisView.h */,
|
||||
BCB6E6631B7D535F000D5B34 /* ORKXAxisView.m */,
|
||||
);
|
||||
name = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
25BD76671B00B37100478C5D /* Pie */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BCD192ED1B81255F00FCC08A /* ORKPieChartView_Internal.h */,
|
||||
BCB6E6481B7D531C000D5B34 /* ORKPieChartView.h */,
|
||||
BCB6E6491B7D531C000D5B34 /* ORKPieChartView.m */,
|
||||
25C17CBB1B2058D4001ADDD2 /* Components */,
|
||||
);
|
||||
name = Pie;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
25C17CBB1B2058D4001ADDD2 /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BCB6E64C1B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.h */,
|
||||
BCB6E64D1B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.m */,
|
||||
BCB6E64E1B7D533B000D5B34 /* ORKPieChartLegendCell.h */,
|
||||
BCB6E64F1B7D533B000D5B34 /* ORKPieChartLegendCell.m */,
|
||||
BCD192DD1B81240400FCC08A /* ORKPieChartPieView.h */,
|
||||
BCD192DE1B81240400FCC08A /* ORKPieChartPieView.m */,
|
||||
BCD192E51B81243900FCC08A /* ORKPieChartLegendView.h */,
|
||||
BCD192E61B81243900FCC08A /* ORKPieChartLegendView.m */,
|
||||
BCD192E91B81245500FCC08A /* ORKPieChartTitleTextView.h */,
|
||||
BCD192EA1B81245500FCC08A /* ORKPieChartTitleTextView.m */,
|
||||
);
|
||||
name = Components;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
25ECC0921AFBD64800F3D63B /* Reaction Time */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -883,6 +1095,21 @@
|
||||
name = "Reaction Time";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
25F5CEDC1B4C3F1D0031E2A4 /* TowerOfHanoi */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
250F94021B4C5A6600FA23EB /* ORKTowerOfHanoiStep.h */,
|
||||
250F94031B4C5A6600FA23EB /* ORKTowerOfHanoiStep.m */,
|
||||
250F94061B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.h */,
|
||||
250F94071B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.m */,
|
||||
257FCE1D1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.h */,
|
||||
257FCE1E1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.m */,
|
||||
257FCE211B4D37A80001EF06 /* ORKTowerOfHanoiTower.h */,
|
||||
257FCE221B4D37A80001EF06 /* ORKTowerOfHanoiTower.m */,
|
||||
);
|
||||
name = TowerOfHanoi;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3FFF18341829DB1D00167070 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -920,6 +1147,8 @@
|
||||
618DA04A1A93D0D600E63AA8 /* ORKAccessibilityFunctions.m */,
|
||||
618DA04B1A93D0D600E63AA8 /* UIView+ORKAccessibility.h */,
|
||||
618DA04C1A93D0D600E63AA8 /* UIView+ORKAccessibility.m */,
|
||||
6146D0A11B84A91E0068491D /* ORKLineGraphAccessibilityElement.h */,
|
||||
6146D0A21B84A91E0068491D /* ORKLineGraphAccessibilityElement.m */,
|
||||
);
|
||||
path = Accessibility;
|
||||
sourceTree = "<group>";
|
||||
@@ -931,6 +1160,7 @@
|
||||
B1B894391A00345200C5CF2D /* ResearchKit_Private.h */,
|
||||
86C40B511A8D7C5B00081FAC /* Common */,
|
||||
86C40AF91A8D7C5B00081FAC /* ActiveTasks */,
|
||||
259E76FB1AFFAEAC0070F786 /* Charts */,
|
||||
86C40BEB1A8D7C5C00081FAC /* Consent */,
|
||||
618DA0471A93D0D600E63AA8 /* Accessibility */,
|
||||
B1A860D91A9693C400EA57B7 /* Animations */,
|
||||
@@ -949,10 +1179,12 @@
|
||||
B12EFF4E1AB2161500A80147 /* Audio */,
|
||||
B12EFF5D1AB2177700A80147 /* Fitness */,
|
||||
B12EFF5E1AB2177D00A80147 /* Spatial Span Memory */,
|
||||
25ECC0921AFBD64800F3D63B /* Reaction Time */,
|
||||
25F5CEDC1B4C3F1D0031E2A4 /* TowerOfHanoi */,
|
||||
B12EFF5F1AB2178500A80147 /* Tapping */,
|
||||
B12EFF601AB2178B00A80147 /* Walking */,
|
||||
10BAA2CC1B5FCDB1004FE478 /* Walking */,
|
||||
147503AC1AEE8058004B17F3 /* Tone Audiometry */,
|
||||
25ECC0921AFBD64800F3D63B /* Reaction Time */,
|
||||
10864C951B271456000F4158 /* PSAT */,
|
||||
);
|
||||
path = ActiveTasks;
|
||||
sourceTree = "<group>";
|
||||
@@ -992,6 +1224,7 @@
|
||||
FA7A9D351B09362D005A2BEA /* Consent */,
|
||||
86CC8EA71AC09383001CCD89 /* Info.plist */,
|
||||
86CC8EA81AC09383001CCD89 /* ORKAccessibilityTests.m */,
|
||||
248604051B4C98760010C8A0 /* ORKAnswerFormatTests.m */,
|
||||
86CC8EA91AC09383001CCD89 /* ORKChoiceAnswerFormatHelperTests.m */,
|
||||
86CC8EAB1AC09383001CCD89 /* ORKDataLoggerManagerTests.m */,
|
||||
86CC8EAC1AC09383001CCD89 /* ORKDataLoggerTests.m */,
|
||||
@@ -1055,6 +1288,8 @@
|
||||
86C40B911A8D7C5C00081FAC /* ORKImageChoiceLabel.m */,
|
||||
86C40B971A8D7C5C00081FAC /* ORKLabel.h */,
|
||||
86C40B981A8D7C5C00081FAC /* ORKLabel.m */,
|
||||
10BAA2C81B5FCB4F004FE478 /* ORKProgressView.h */,
|
||||
10BAA2C91B5FCB4F004FE478 /* ORKProgressView.m */,
|
||||
86C40BAA1A8D7C5C00081FAC /* ORKRoundTappingButton.h */,
|
||||
86C40BAB1A8D7C5C00081FAC /* ORKRoundTappingButton.m */,
|
||||
86C40BB01A8D7C5C00081FAC /* ORKScaleValueLabel.h */,
|
||||
@@ -1063,6 +1298,8 @@
|
||||
86C40BAD1A8D7C5C00081FAC /* ORKScaleRangeLabel.m */,
|
||||
B8760F291AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.h */,
|
||||
B8760F2A1AFBEFB0007FA16F /* ORKScaleRangeDescriptionLabel.m */,
|
||||
24898B0B1B7186C000B0E7E7 /* ORKScaleRangeImageView.h */,
|
||||
24898B0C1B7186C000B0E7E7 /* ORKScaleRangeImageView.m */,
|
||||
86C40BC01A8D7C5C00081FAC /* ORKSubheadlineLabel.h */,
|
||||
86C40BC11A8D7C5C00081FAC /* ORKSubheadlineLabel.m */,
|
||||
86C40BD31A8D7C5C00081FAC /* ORKTapCountLabel.h */,
|
||||
@@ -1632,7 +1869,7 @@
|
||||
name = Tapping;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B12EFF601AB2178B00A80147 /* Walking */ = {
|
||||
B12EFF601AB2178B00A80147 /* Short Walk */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
86C40B1E1A8D7C5B00081FAC /* ORKWalkingTaskStep.h */,
|
||||
@@ -1640,7 +1877,7 @@
|
||||
86C40B201A8D7C5B00081FAC /* ORKWalkingTaskStepViewController.h */,
|
||||
86C40B211A8D7C5B00081FAC /* ORKWalkingTaskStepViewController.m */,
|
||||
);
|
||||
name = Walking;
|
||||
name = "Short Walk";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B12EFF611AB217AE00A80147 /* Speech Synthesis */ = {
|
||||
@@ -1754,6 +1991,7 @@
|
||||
BCA5C0351AEC05F20092AC8D /* ORKStepNavigationRule.h in Headers */,
|
||||
BC13CE391B0660220044153C /* ORKNavigableOrderedTask.h in Headers */,
|
||||
86C40C921A8D7C5C00081FAC /* ORKAudioRecorder.h in Headers */,
|
||||
BCB6E65B1B7D534C000D5B34 /* ORKDiscreteGraphChartView.h in Headers */,
|
||||
86C40D8E1A8D7C5C00081FAC /* ORKStep.h in Headers */,
|
||||
618DA04E1A93D0D600E63AA8 /* ORKAccessibility.h in Headers */,
|
||||
86B781BB1AA668ED00688151 /* ORKTimeIntervalPicker.h in Headers */,
|
||||
@@ -1761,6 +1999,7 @@
|
||||
86C40CE41A8D7C5C00081FAC /* ORKAnswerFormat.h in Headers */,
|
||||
25ECC0951AFBD68300F3D63B /* ORKReactionTimeStep.h in Headers */,
|
||||
86C40D0A1A8D7C5C00081FAC /* ORKCustomStepView.h in Headers */,
|
||||
BCD192EE1B81255F00FCC08A /* ORKPieChartView_Internal.h in Headers */,
|
||||
86C40DCE1A8D7C5C00081FAC /* ORKTaskViewController_Internal.h in Headers */,
|
||||
25ECC09F1AFBD92D00F3D63B /* ORKReactionTimeContentView.h in Headers */,
|
||||
86C40C361A8D7C5C00081FAC /* ORKSpatialSpanGame.h in Headers */,
|
||||
@@ -1771,11 +2010,13 @@
|
||||
86C40C961A8D7C5C00081FAC /* ORKDataLogger.h in Headers */,
|
||||
BC13CE421B066A990044153C /* ORKStepNavigationRule_Internal.h in Headers */,
|
||||
86C40D781A8D7C5C00081FAC /* ORKScaleSlider.h in Headers */,
|
||||
861D2AE81B840991008C4CD0 /* ORKTimedWalkStep.h in Headers */,
|
||||
86C40D241A8D7C5C00081FAC /* ORKFormStepViewController.h in Headers */,
|
||||
86C40D6A1A8D7C5C00081FAC /* ORKResult.h in Headers */,
|
||||
86C40DD61A8D7C5C00081FAC /* ORKUnitLabel.h in Headers */,
|
||||
86C40D9C1A8D7C5C00081FAC /* ORKSubheadlineLabel.h in Headers */,
|
||||
147503BB1AEE807C004B17F3 /* ORKToneAudiometryStepViewController.h in Headers */,
|
||||
BCD192DF1B81240400FCC08A /* ORKPieChartPieView.h in Headers */,
|
||||
86C40D441A8D7C5C00081FAC /* ORKInstructionStepViewController.h in Headers */,
|
||||
86C40D841A8D7C5C00081FAC /* ORKSelectionTitleLabel.h in Headers */,
|
||||
BC13CE3C1B0662990044153C /* ORKStepNavigationRule_Private.h in Headers */,
|
||||
@@ -1784,6 +2025,7 @@
|
||||
86C40C661A8D7C5C00081FAC /* CMAccelerometerData+ORKJSONDictionary.h in Headers */,
|
||||
25ECC0A31AFBDD2700F3D63B /* ORKReactionTimeStimulusView.h in Headers */,
|
||||
86C40D701A8D7C5C00081FAC /* ORKRoundTappingButton.h in Headers */,
|
||||
BCB6E6501B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.h in Headers */,
|
||||
865EA1621AB8DF750037C68E /* ORKDateTimePicker.h in Headers */,
|
||||
86C40DA01A8D7C5C00081FAC /* ORKSurveyAnswerCell.h in Headers */,
|
||||
86C40D941A8D7C5C00081FAC /* ORKStepViewController.h in Headers */,
|
||||
@@ -1791,13 +2033,16 @@
|
||||
86C40C221A8D7C5C00081FAC /* ORKCountdownStep.h in Headers */,
|
||||
86C40DB61A8D7C5C00081FAC /* ORKSurveyAnswerCellForText.h in Headers */,
|
||||
86C40E281A8D7C5C00081FAC /* ORKSignatureView.h in Headers */,
|
||||
BCB6E65D1B7D534C000D5B34 /* ORKGraphChartView_Internal.h in Headers */,
|
||||
86C40C8C1A8D7C5C00081FAC /* ORKActiveStepViewController.h in Headers */,
|
||||
618DA0541A93D0D600E63AA8 /* UIView+ORKAccessibility.h in Headers */,
|
||||
86C40C3A1A8D7C5C00081FAC /* ORKSpatialSpanGameState.h in Headers */,
|
||||
10864CA21B27146B000F4158 /* ORKPSATContentView.h in Headers */,
|
||||
618DA0501A93D0D600E63AA8 /* ORKAccessibilityFunctions.h in Headers */,
|
||||
86C40C721A8D7C5C00081FAC /* CMPedometerData+ORKJSONDictionary.h in Headers */,
|
||||
86C40CA41A8D7C5C00081FAC /* ORKLocationRecorder.h in Headers */,
|
||||
86C40D201A8D7C5C00081FAC /* ORKFormStep.h in Headers */,
|
||||
BCD192EB1B81245500FCC08A /* ORKPieChartTitleTextView.h in Headers */,
|
||||
86C40C761A8D7C5C00081FAC /* HKSample+ORKJSONDictionary.h in Headers */,
|
||||
86C40CEA1A8D7C5C00081FAC /* ORKAnswerTextField.h in Headers */,
|
||||
B12EA0191B0D76AD00F9F554 /* ORKToneAudiometryPracticeStepViewController.h in Headers */,
|
||||
@@ -1805,6 +2050,7 @@
|
||||
86C40CE81A8D7C5C00081FAC /* ORKAnswerFormat_Internal.h in Headers */,
|
||||
86C40D021A8D7C5C00081FAC /* ORKContinueButton.h in Headers */,
|
||||
86C40D681A8D7C5C00081FAC /* ORKQuestionStepViewController_Private.h in Headers */,
|
||||
BCB6E6661B7D535F000D5B34 /* ORKXAxisView.h in Headers */,
|
||||
86C40D121A8D7C5C00081FAC /* ORKDefines.h in Headers */,
|
||||
86C40D401A8D7C5C00081FAC /* ORKInstructionStep.h in Headers */,
|
||||
147503B71AEE807C004B17F3 /* ORKToneAudiometryContentView.h in Headers */,
|
||||
@@ -1813,6 +2059,7 @@
|
||||
D42FEFB81AF7557000A124F8 /* ORKImageCaptureView.h in Headers */,
|
||||
86C40D1A1A8D7C5C00081FAC /* ORKFormItem_Internal.h in Headers */,
|
||||
86C40E1C1A8D7C5C00081FAC /* ORKConsentSection_Internal.h in Headers */,
|
||||
861D2AEC1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.h in Headers */,
|
||||
86C40C7A1A8D7C5C00081FAC /* ORKAccelerometerRecorder.h in Headers */,
|
||||
86C40D141A8D7C5C00081FAC /* ORKDefines_Private.h in Headers */,
|
||||
86C40CA81A8D7C5C00081FAC /* ORKPedometerRecorder.h in Headers */,
|
||||
@@ -1826,12 +2073,15 @@
|
||||
B11C549F1A9EF4A700265E61 /* ORKConsentSharingStepViewController.h in Headers */,
|
||||
86C40D621A8D7C5C00081FAC /* ORKQuestionStep_Internal.h in Headers */,
|
||||
86C40D641A8D7C5C00081FAC /* ORKQuestionStepViewController.h in Headers */,
|
||||
10BAA2CA1B5FCB4F004FE478 /* ORKProgressView.h in Headers */,
|
||||
BCB6E6601B7D534C000D5B34 /* ORKLineGraphChartView.h in Headers */,
|
||||
86C40E241A8D7C5C00081FAC /* ORKEAGLMoviePlayerView.h in Headers */,
|
||||
B183A4DD1A8535D100C76870 /* ResearchKit.h in Headers */,
|
||||
86C40D101A8D7C5C00081FAC /* ORKDefaultFont.h in Headers */,
|
||||
86C40E301A8D7C5C00081FAC /* ORKVisualConsentStepViewController.h in Headers */,
|
||||
86C40DCA1A8D7C5C00081FAC /* ORKTaskViewController.h in Headers */,
|
||||
86C40C7E1A8D7C5C00081FAC /* ORKActiveStep.h in Headers */,
|
||||
BCB6E65E1B7D534C000D5B34 /* ORKGraphChartView.h in Headers */,
|
||||
86C40DD21A8D7C5C00081FAC /* ORKTextButton.h in Headers */,
|
||||
86C40CD41A8D7C5C00081FAC /* ORKTableContainerView.h in Headers */,
|
||||
86C40D0E1A8D7C5C00081FAC /* ORKCustomStepView_Internal.h in Headers */,
|
||||
@@ -1839,8 +2089,11 @@
|
||||
86C40D921A8D7C5C00081FAC /* ORKStep_Private.h in Headers */,
|
||||
86C40CC41A8D7C5C00081FAC /* ORKCompletionStepViewController.h in Headers */,
|
||||
86C40D7C1A8D7C5C00081FAC /* ORKScaleValueLabel.h in Headers */,
|
||||
250F94081B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.h in Headers */,
|
||||
86C40E2C1A8D7C5C00081FAC /* ORKVisualConsentStep.h in Headers */,
|
||||
257FCE1F1B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.h in Headers */,
|
||||
86C40CB81A8D7C5C00081FAC /* ORKVoiceEngine.h in Headers */,
|
||||
BCB6E6521B7D533B000D5B34 /* ORKPieChartLegendCell.h in Headers */,
|
||||
FA7A9D331B0843A9005A2BEA /* ORKConsentSignatureFormatter.h in Headers */,
|
||||
86C40C5A1A8D7C5C00081FAC /* ORKWalkingTaskStep.h in Headers */,
|
||||
86C40E361A8D7C5C00081FAC /* ORKVisualConsentTransitionAnimator.h in Headers */,
|
||||
@@ -1852,6 +2105,7 @@
|
||||
B11C54991A9EEF8800265E61 /* ORKConsentSharingStep.h in Headers */,
|
||||
86C40DA61A8D7C5C00081FAC /* ORKSurveyAnswerCellForImageSelection.h in Headers */,
|
||||
86C40D5E1A8D7C5C00081FAC /* ORKQuestionStep.h in Headers */,
|
||||
6146D0A31B84A91E0068491D /* ORKLineGraphAccessibilityElement.h in Headers */,
|
||||
86C40C841A8D7C5C00081FAC /* ORKActiveStepTimer.h in Headers */,
|
||||
86B781BD1AA668ED00688151 /* ORKValuePicker.h in Headers */,
|
||||
86C40DE21A8D7C5C00081FAC /* ORKVerticalContainerView_Internal.h in Headers */,
|
||||
@@ -1865,15 +2119,19 @@
|
||||
D458520A1AF6CCFA00A2DE13 /* ORKImageCaptureCameraPreviewView.h in Headers */,
|
||||
D44239791AF17F5100559D96 /* ORKImageCaptureStep.h in Headers */,
|
||||
86C40CB21A8D7C5C00081FAC /* ORKRecorder_Private.h in Headers */,
|
||||
BCD192E71B81243900FCC08A /* ORKPieChartLegendView.h in Headers */,
|
||||
86C40C881A8D7C5C00081FAC /* ORKActiveStepTimerView.h in Headers */,
|
||||
86C40C161A8D7C5C00081FAC /* ORKAudioContentView.h in Headers */,
|
||||
86C40CB41A8D7C5C00081FAC /* ORKTouchRecorder.h in Headers */,
|
||||
86C40DEA1A8D7C5C00081FAC /* UIBarButtonItem+ORKBarButtonItem.h in Headers */,
|
||||
86C40CF61A8D7C5C00081FAC /* ORKBorderedButton.h in Headers */,
|
||||
86C40D4A1A8D7C5C00081FAC /* ORKLabel.h in Headers */,
|
||||
250F94041B4C5A6600FA23EB /* ORKTowerOfHanoiStep.h in Headers */,
|
||||
861D11A91AA691BB003C98A7 /* ORKScaleSliderView.h in Headers */,
|
||||
10864CA01B27146B000F4158 /* ORKPSATStepViewController.h in Headers */,
|
||||
BC13CE3E1B0662A80044153C /* ORKOrderedTask_Internal.h in Headers */,
|
||||
86C40C3E1A8D7C5C00081FAC /* ORKSpatialSpanMemoryContentView.h in Headers */,
|
||||
257FCE231B4D37A80001EF06 /* ORKTowerOfHanoiTower.h in Headers */,
|
||||
86C40CC01A8D7C5C00081FAC /* ORKCompletionStep.h in Headers */,
|
||||
86C40DF61A8D7C5C00081FAC /* ORKConsentSignatureController.h in Headers */,
|
||||
86C40CDC1A8D7C5C00081FAC /* ORKTintedImageView.h in Headers */,
|
||||
@@ -1886,9 +2144,12 @@
|
||||
86C40DC21A8D7C5C00081FAC /* ORKTapCountLabel.h in Headers */,
|
||||
86C40D301A8D7C5C00081FAC /* ORKHealthAnswerFormat.h in Headers */,
|
||||
86C40C261A8D7C5C00081FAC /* ORKCountdownStepViewController.h in Headers */,
|
||||
861D2AF01B8409D9008C4CD0 /* ORKTimedWalkContentView.h in Headers */,
|
||||
86C40E0C1A8D7C5C00081FAC /* ORKConsentReviewStepViewController.h in Headers */,
|
||||
86C40C321A8D7C5C00081FAC /* ORKFitnessStepViewController.h in Headers */,
|
||||
BCC1CD9A1B7ED64F00D86886 /* ORKYAxisView.h in Headers */,
|
||||
86C40DBE1A8D7C5C00081FAC /* ORKTableViewCell.h in Headers */,
|
||||
BCB6E64A1B7D531C000D5B34 /* ORKPieChartView.h in Headers */,
|
||||
86C40C2E1A8D7C5C00081FAC /* ORKFitnessStep.h in Headers */,
|
||||
86C40C821A8D7C5C00081FAC /* ORKActiveStep_Internal.h in Headers */,
|
||||
86C40D481A8D7C5C00081FAC /* ORKInstructionStepViewController_Internal.h in Headers */,
|
||||
@@ -1906,13 +2167,16 @@
|
||||
86C40CD81A8D7C5C00081FAC /* ORKTextFieldView.h in Headers */,
|
||||
86C40DD01A8D7C5C00081FAC /* ORKTaskViewController_Private.h in Headers */,
|
||||
86C40DAE1A8D7C5C00081FAC /* ORKSurveyAnswerCellForScale.h in Headers */,
|
||||
10864CA41B27146B000F4158 /* ORKPSATKeyboardView.h in Headers */,
|
||||
86C40CFE1A8D7C5C00081FAC /* ORKChoiceViewCell.h in Headers */,
|
||||
86C40DC61A8D7C5C00081FAC /* ORKTask.h in Headers */,
|
||||
86C40C561A8D7C5C00081FAC /* ORKTappingIntervalStepViewController.h in Headers */,
|
||||
86AD91101AB7B8A600361FEB /* ORKActiveStepView.h in Headers */,
|
||||
86C40C9C1A8D7C5C00081FAC /* ORKDeviceMotionRecorder.h in Headers */,
|
||||
86C40E1E1A8D7C5C00081FAC /* ORKConsentSignature.h in Headers */,
|
||||
24898B0D1B7186C000B0E7E7 /* ORKScaleRangeImageView.h in Headers */,
|
||||
86C40C5E1A8D7C5C00081FAC /* ORKWalkingTaskStepViewController.h in Headers */,
|
||||
BCB6E66C1B7D537B000D5B34 /* ORKRangedPoint.h in Headers */,
|
||||
86C40D2C1A8D7C5C00081FAC /* ORKHeadlineLabel.h in Headers */,
|
||||
86C40D1C1A8D7C5C00081FAC /* ORKFormSectionTitleLabel.h in Headers */,
|
||||
86C40CBC1A8D7C5C00081FAC /* UITouch+ORKJSONDictionary.h in Headers */,
|
||||
@@ -1921,6 +2185,7 @@
|
||||
86C40CB01A8D7C5C00081FAC /* ORKRecorder_Internal.h in Headers */,
|
||||
86C40E101A8D7C5C00081FAC /* ORKConsentSceneViewController.h in Headers */,
|
||||
86C40DAA1A8D7C5C00081FAC /* ORKSurveyAnswerCellForNumber.h in Headers */,
|
||||
10864C9E1B27146B000F4158 /* ORKPSATStep.h in Headers */,
|
||||
86C40D6E1A8D7C5C00081FAC /* ORKResult_Private.h in Headers */,
|
||||
86C40D161A8D7C5C00081FAC /* ORKErrors.h in Headers */,
|
||||
861D11B51AA7D073003C98A7 /* ORKTextChoiceCellGroup.h in Headers */,
|
||||
@@ -1984,7 +2249,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = ORK;
|
||||
LastUpgradeCheck = 0700;
|
||||
LastUpgradeCheck = 0640;
|
||||
ORGANIZATIONNAME = researchkit.org;
|
||||
TargetAttributes = {
|
||||
86CC8E991AC09332001CCD89 = {
|
||||
@@ -2133,6 +2398,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
86CC8EB71AC09383001CCD89 /* ORKDataLoggerTests.m in Sources */,
|
||||
248604061B4C98760010C8A0 /* ORKAnswerFormatTests.m in Sources */,
|
||||
86CC8EBA1AC09383001CCD89 /* ORKResultTests.m in Sources */,
|
||||
FA7A9D391B0969A7005A2BEA /* ORKConsentSignatureFormatterTests.m in Sources */,
|
||||
86CC8EB81AC09383001CCD89 /* ORKHKSampleTests.m in Sources */,
|
||||
@@ -2155,20 +2421,24 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
861D2AED1B8409B2008C4CD0 /* ORKTimedWalkStepViewController.m in Sources */,
|
||||
86C40C341A8D7C5C00081FAC /* ORKFitnessStepViewController.m in Sources */,
|
||||
86C40E2E1A8D7C5C00081FAC /* ORKVisualConsentStep.m in Sources */,
|
||||
86C40CA61A8D7C5C00081FAC /* ORKLocationRecorder.m in Sources */,
|
||||
86C40CB61A8D7C5C00081FAC /* ORKTouchRecorder.m in Sources */,
|
||||
B12EA0161B0D73A500F9F554 /* ORKToneAudiometryPracticeStep.m in Sources */,
|
||||
861D2AF11B8409D9008C4CD0 /* ORKTimedWalkContentView.m in Sources */,
|
||||
86C40DC41A8D7C5C00081FAC /* ORKTapCountLabel.m in Sources */,
|
||||
25ECC0A01AFBD92D00F3D63B /* ORKReactionTimeContentView.m in Sources */,
|
||||
86C40D4C1A8D7C5C00081FAC /* ORKLabel.m in Sources */,
|
||||
86C40C9E1A8D7C5C00081FAC /* ORKDeviceMotionRecorder.m in Sources */,
|
||||
86C40D961A8D7C5C00081FAC /* ORKStepViewController.m in Sources */,
|
||||
86C40DF81A8D7C5C00081FAC /* ORKConsentSignatureController.m in Sources */,
|
||||
BCB6E6531B7D533B000D5B34 /* ORKPieChartLegendCell.m in Sources */,
|
||||
86C40D8C1A8D7C5C00081FAC /* ORKSkin.m in Sources */,
|
||||
86C40D221A8D7C5C00081FAC /* ORKFormStep.m in Sources */,
|
||||
86C40CD61A8D7C5C00081FAC /* ORKTableContainerView.m in Sources */,
|
||||
257FCE201B4D14E50001EF06 /* ORKTowerOfHanoiTowerView.m in Sources */,
|
||||
861D11AE1AA7951F003C98A7 /* ORKChoiceAnswerFormatHelper.m in Sources */,
|
||||
86C40C381A8D7C5C00081FAC /* ORKSpatialSpanGame.m in Sources */,
|
||||
86C40C481A8D7C5C00081FAC /* ORKSpatialSpanMemoryStepViewController.m in Sources */,
|
||||
@@ -2192,23 +2462,32 @@
|
||||
86C40DB81A8D7C5C00081FAC /* ORKSurveyAnswerCellForText.m in Sources */,
|
||||
86C40CF01A8D7C5C00081FAC /* ORKAnswerTextView.m in Sources */,
|
||||
86C40D3E1A8D7C5C00081FAC /* ORKImageChoiceLabel.m in Sources */,
|
||||
250F94051B4C5A6600FA23EB /* ORKTowerOfHanoiStep.m in Sources */,
|
||||
86C40E0A1A8D7C5C00081FAC /* ORKConsentReviewStep.m in Sources */,
|
||||
BCD192E81B81243900FCC08A /* ORKPieChartLegendView.m in Sources */,
|
||||
86C40D1E1A8D7C5C00081FAC /* ORKFormSectionTitleLabel.m in Sources */,
|
||||
250F94091B4C5AA400FA23EB /* ORKTowerOfHanoiStepViewController.m in Sources */,
|
||||
86C40CF81A8D7C5C00081FAC /* ORKBorderedButton.m in Sources */,
|
||||
86C40E201A8D7C5C00081FAC /* ORKConsentSignature.m in Sources */,
|
||||
86C40C601A8D7C5C00081FAC /* ORKWalkingTaskStepViewController.m in Sources */,
|
||||
BCD192E01B81240400FCC08A /* ORKPieChartPieView.m in Sources */,
|
||||
866F86011A96CBF3007B282C /* ORKSurveyAnswerCell.m in Sources */,
|
||||
86C40E321A8D7C5C00081FAC /* ORKVisualConsentStepViewController.m in Sources */,
|
||||
618DA0561A93D0D600E63AA8 /* UIView+ORKAccessibility.m in Sources */,
|
||||
86C40D3A1A8D7C5C00081FAC /* ORKHTMLPDFWriter.m in Sources */,
|
||||
865EA1691ABA1AA10037C68E /* ORKPicker.m in Sources */,
|
||||
BCB6E6511B7D533B000D5B34 /* ORKCenteredCollectionViewLayout.m in Sources */,
|
||||
86C40D321A8D7C5C00081FAC /* ORKHealthAnswerFormat.m in Sources */,
|
||||
10BAA2CB1B5FCB4F004FE478 /* ORKProgressView.m in Sources */,
|
||||
86C40D861A8D7C5C00081FAC /* ORKSelectionTitleLabel.m in Sources */,
|
||||
86C40D001A8D7C5C00081FAC /* ORKChoiceViewCell.m in Sources */,
|
||||
86C40C4C1A8D7C5C00081FAC /* ORKSpatialSpanTargetView.m in Sources */,
|
||||
86C40D9E1A8D7C5C00081FAC /* ORKSubheadlineLabel.m in Sources */,
|
||||
10864CA31B27146B000F4158 /* ORKPSATContentView.m in Sources */,
|
||||
6146D0A41B84A91E0068491D /* ORKLineGraphAccessibilityElement.m in Sources */,
|
||||
D42FEFB91AF7557000A124F8 /* ORKImageCaptureView.m in Sources */,
|
||||
86C40C401A8D7C5C00081FAC /* ORKSpatialSpanMemoryContentView.m in Sources */,
|
||||
BCB6E6671B7D535F000D5B34 /* ORKXAxisView.m in Sources */,
|
||||
147503BC1AEE807C004B17F3 /* ORKToneAudiometryStepViewController.m in Sources */,
|
||||
86AD910B1AB7AD1E00361FEB /* ORKNavigationContainerView.m in Sources */,
|
||||
865EA1631AB8DF750037C68E /* ORKDateTimePicker.m in Sources */,
|
||||
@@ -2218,6 +2497,7 @@
|
||||
D458520B1AF6CCFA00A2DE13 /* ORKImageCaptureCameraPreviewView.m in Sources */,
|
||||
86C40E1A1A8D7C5C00081FAC /* ORKConsentSection.m in Sources */,
|
||||
86C40C241A8D7C5C00081FAC /* ORKCountdownStep.m in Sources */,
|
||||
BCB6E65C1B7D534C000D5B34 /* ORKDiscreteGraphChartView.m in Sources */,
|
||||
86C40CA21A8D7C5C00081FAC /* ORKHealthQuantityTypeRecorder.m in Sources */,
|
||||
86C40DC01A8D7C5C00081FAC /* ORKTableViewCell.m in Sources */,
|
||||
BC41942A1AE8453A00073D6B /* ORKObserver.m in Sources */,
|
||||
@@ -2265,7 +2545,9 @@
|
||||
86C40D761A8D7C5C00081FAC /* ORKScaleRangeLabel.m in Sources */,
|
||||
86C40C741A8D7C5C00081FAC /* CMPedometerData+ORKJSONDictionary.m in Sources */,
|
||||
86AD91151AB7B97E00361FEB /* ORKQuestionStepView.m in Sources */,
|
||||
10864CA11B27146B000F4158 /* ORKPSATStepViewController.m in Sources */,
|
||||
86C40C5C1A8D7C5C00081FAC /* ORKWalkingTaskStep.m in Sources */,
|
||||
257FCE241B4D37A80001EF06 /* ORKTowerOfHanoiTower.m in Sources */,
|
||||
86C40C3C1A8D7C5C00081FAC /* ORKSpatialSpanGameState.m in Sources */,
|
||||
86C40CF41A8D7C5C00081FAC /* ORKBodyLabel.m in Sources */,
|
||||
86C40C941A8D7C5C00081FAC /* ORKAudioRecorder.m in Sources */,
|
||||
@@ -2277,11 +2559,13 @@
|
||||
86C40C501A8D7C5C00081FAC /* ORKTappingContentView.m in Sources */,
|
||||
86C40CEC1A8D7C5C00081FAC /* ORKAnswerTextField.m in Sources */,
|
||||
86C40C441A8D7C5C00081FAC /* ORKSpatialSpanMemoryStep.m in Sources */,
|
||||
24898B0E1B7186C000B0E7E7 /* ORKScaleRangeImageView.m in Sources */,
|
||||
86C40DD81A8D7C5C00081FAC /* ORKUnitLabel.m in Sources */,
|
||||
86C40D361A8D7C5C00081FAC /* ORKHelpers.m in Sources */,
|
||||
86C40C181A8D7C5C00081FAC /* ORKAudioContentView.m in Sources */,
|
||||
86C40C8E1A8D7C5C00081FAC /* ORKActiveStepViewController.m in Sources */,
|
||||
B183A5011A8535D100C76870 /* (null) in Sources */,
|
||||
10864CA51B27146B000F4158 /* ORKPSATKeyboardView.m in Sources */,
|
||||
86C40CE61A8D7C5C00081FAC /* ORKAnswerFormat.m in Sources */,
|
||||
25ECC0961AFBD68300F3D63B /* ORKReactionTimeStep.m in Sources */,
|
||||
BC13CE3A1B0660220044153C /* ORKNavigableOrderedTask.m in Sources */,
|
||||
@@ -2289,11 +2573,15 @@
|
||||
86C40DA81A8D7C5C00081FAC /* ORKSurveyAnswerCellForImageSelection.m in Sources */,
|
||||
86C40CCE1A8D7C5C00081FAC /* ORKImageSelectionView.m in Sources */,
|
||||
86C40D461A8D7C5C00081FAC /* ORKInstructionStepViewController.m in Sources */,
|
||||
BCB6E6611B7D534C000D5B34 /* ORKLineGraphChartView.m in Sources */,
|
||||
86C40C7C1A8D7C5C00081FAC /* ORKAccelerometerRecorder.m in Sources */,
|
||||
86C40C861A8D7C5C00081FAC /* ORKActiveStepTimer.m in Sources */,
|
||||
B11C549B1A9EEF8800265E61 /* ORKConsentSharingStep.m in Sources */,
|
||||
86C40DE01A8D7C5C00081FAC /* ORKVerticalContainerView.m in Sources */,
|
||||
86C40CC61A8D7C5C00081FAC /* ORKCompletionStepViewController.m in Sources */,
|
||||
BCD192EC1B81245500FCC08A /* ORKPieChartTitleTextView.m in Sources */,
|
||||
861D2AF71B843968008C4CD0 /* ORKCompletionStepViewController.m in Sources */,
|
||||
BCB6E65F1B7D534C000D5B34 /* ORKGraphChartView.m in Sources */,
|
||||
861D2AE91B840991008C4CD0 /* ORKTimedWalkStep.m in Sources */,
|
||||
86C40D661A8D7C5C00081FAC /* ORKQuestionStepViewController.m in Sources */,
|
||||
86C40DF41A8D7C5C00081FAC /* ORKConsentReviewController.m in Sources */,
|
||||
147503BA1AEE807C004B17F3 /* ORKToneAudiometryStep.m in Sources */,
|
||||
@@ -2301,11 +2589,15 @@
|
||||
86C40D2A1A8D7C5C00081FAC /* ORKFormTextView.m in Sources */,
|
||||
86C40DD41A8D7C5C00081FAC /* ORKTextButton.m in Sources */,
|
||||
86C40C981A8D7C5C00081FAC /* ORKDataLogger.m in Sources */,
|
||||
BCB6E66D1B7D537B000D5B34 /* ORKRangedPoint.m in Sources */,
|
||||
86C40D0C1A8D7C5C00081FAC /* ORKCustomStepView.m in Sources */,
|
||||
86C40C1C1A8D7C5C00081FAC /* ORKAudioStep.m in Sources */,
|
||||
BCC1CD9B1B7ED64F00D86886 /* ORKYAxisView.m in Sources */,
|
||||
86C40D581A8D7C5C00081FAC /* ORKOrderedTask.m in Sources */,
|
||||
86C40D601A8D7C5C00081FAC /* ORKQuestionStep.m in Sources */,
|
||||
86C40E381A8D7C5C00081FAC /* ORKVisualConsentTransitionAnimator.m in Sources */,
|
||||
BCB6E64B1B7D531C000D5B34 /* ORKPieChartView.m in Sources */,
|
||||
10864C9F1B27146B000F4158 /* ORKPSATStep.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2390,6 +2682,7 @@
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
@@ -2407,6 +2700,7 @@
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TOOLCHAINS = default;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2437,6 +2731,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TOOLCHAINS = default;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
@@ -2461,6 +2756,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.apple.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -2482,6 +2778,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.apple.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
@@ -2509,6 +2806,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MODULEMAP_FILE = ResearchKit/module.modulemap;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "apple.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = ResearchKit;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
@@ -2536,6 +2834,7 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MODULEMAP_FILE = ResearchKit/module.modulemap;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "apple.${PRODUCT_NAME:rfc1034identifier}";
|
||||
PRODUCT_NAME = ResearchKit;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
version = "1.8">
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
@@ -23,10 +23,10 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -48,13 +48,15 @@
|
||||
ReferencedContainer = "container:ResearchKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
@@ -72,10 +74,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0630"
|
||||
version = "1.8">
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
@@ -23,19 +23,21 @@
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
@@ -53,10 +55,10 @@
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
|
||||
@@ -32,3 +32,4 @@
|
||||
// Shared header for accessibility functionality.
|
||||
#import "UIView+ORKAccessibility.h"
|
||||
#import "ORKAccessibilityFunctions.h"
|
||||
#import "ORKLineGraphAccessibilityElement.h"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ORKLineGraphAccessibilityElement : UIAccessibilityElement
|
||||
|
||||
- (nonnull instancetype)initWithAccessibilityContainer:(nonnull UIView *)container index:(NSInteger)index maxIndex:(NSInteger)maxIndex;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import "ORKLineGraphAccessibilityElement.h"
|
||||
|
||||
@interface ORKLineGraphAccessibilityElement()
|
||||
@property (assign, nonatomic) NSInteger index;
|
||||
@property (assign, nonatomic) NSInteger maxIndex;
|
||||
@end
|
||||
|
||||
@implementation ORKLineGraphAccessibilityElement
|
||||
|
||||
- (nonnull instancetype)initWithAccessibilityContainer:(nonnull UIView *)container index:(NSInteger)index maxIndex:(NSInteger)maxIndex {
|
||||
self = [super initWithAccessibilityContainer:container];
|
||||
if (self) {
|
||||
self.index = index;
|
||||
self.maxIndex = maxIndex;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGRect)accessibilityFrame {
|
||||
if (self.maxIndex == 0) {
|
||||
return [super accessibilityFrame];
|
||||
}
|
||||
|
||||
CGRect containerFrame = [self.accessibilityContainer frame];
|
||||
CGFloat height = CGRectGetHeight(containerFrame);
|
||||
CGFloat width = CGRectGetWidth(containerFrame) / self.maxIndex;
|
||||
CGFloat x = self.index * width;
|
||||
|
||||
return UIAccessibilityConvertFrameToScreenCoordinates(CGRectMake(x, 0, width, height), self.accessibilityContainer);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -72,7 +72,7 @@ static NSString *const kHKCorrelatedObjectsKey = @"objects";
|
||||
if ((options & ORKSampleIncludeUUID)) {
|
||||
NSUUID *uuid = [self UUID];
|
||||
if (uuid) {
|
||||
mutableDictionary[kHKUUIDKey] = [uuid UUIDString];
|
||||
mutableDictionary[kHKUUIDKey] = uuid.UUIDString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,17 +109,12 @@
|
||||
|
||||
[self.motionManager stopAccelerometerUpdates];
|
||||
|
||||
[self.motionManager
|
||||
startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
|
||||
withHandler:^(CMAccelerometerData *data, NSError *error)
|
||||
{
|
||||
[self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler:^(CMAccelerometerData *data, NSError *error) {
|
||||
BOOL success = NO;
|
||||
if (data)
|
||||
{
|
||||
if (data) {
|
||||
success = [_logger append:[data ork_JSONDictionary] error:&error];
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
if (!success) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_recordingError = error;
|
||||
[self stop];
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
#import <ResearchKit/ORKDefines.h>
|
||||
#import <ResearchKit/ORKStep.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <HealthKit/HealthKit.h>
|
||||
|
||||
@class ORKRecorderConfiguration;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -191,7 +193,7 @@ The default value of this property is `NO`.
|
||||
|
||||
See also: `ORKRecorderConfiguration` and `ORKRecorder`.
|
||||
*/
|
||||
@property (nonatomic, copy, nullable) NSArray *recorderConfigurations;
|
||||
@property (nonatomic, copy, nullable) NSArray<ORKRecorderConfiguration *> *recorderConfigurations;
|
||||
|
||||
/**
|
||||
The set of HealthKit types the step requests for reading. (read-only)
|
||||
@@ -203,7 +205,7 @@ The default value of this property is `NO`.
|
||||
By default, the property scans the recorders and collates the HealthKit
|
||||
types the recorders require. Subclasses may override this implementation.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSSet *requestedHealthKitTypesForReading;
|
||||
@property (nonatomic, readonly, nullable) NSSet<HKObjectType *> *requestedHealthKitTypesForReading;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -156,10 +156,10 @@
|
||||
(self.shouldUseNextAsSkipButton == castObject.shouldUseNextAsSkipButton));
|
||||
}
|
||||
|
||||
- (NSSet *)requestedHealthKitTypesForReading {
|
||||
NSMutableSet *set = [NSMutableSet set];
|
||||
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
|
||||
NSMutableSet<HKObjectType *> *set = [NSMutableSet set];
|
||||
for (ORKRecorderConfiguration *config in self.recorderConfigurations) {
|
||||
NSSet *subset = [config requestedHealthKitTypesForReading];
|
||||
NSSet<HKObjectType *> *subset = [config requestedHealthKitTypesForReading];
|
||||
if (subset) {
|
||||
[set unionSet:subset];
|
||||
}
|
||||
|
||||
@@ -64,23 +64,6 @@ static const CGFloat kValueLineMargin = 1.5;
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1
|
||||
constant:CGFLOAT_MAX];
|
||||
constraint1.priority = UILayoutPriorityFittingSizeLevel;
|
||||
NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:self
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1
|
||||
constant:CGFLOAT_MAX];
|
||||
constraint2.priority = UILayoutPriorityFittingSizeLevel;
|
||||
[NSLayoutConstraint activateConstraints:@[constraint1, constraint2]];
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
_values = @[@(0.2),@(0.6),@(0.55), @(0.1), @(0.75), @(0.7)];
|
||||
@@ -251,7 +234,7 @@ static const CGFloat kValueLineMargin = 1.5;
|
||||
[self applyKeyColor];
|
||||
}
|
||||
|
||||
-(void)setFailed:(BOOL)failed {
|
||||
- (void)setFailed:(BOOL)failed {
|
||||
_failed = failed;
|
||||
_alertLabel.text = failed ? ORKLocalizedString(@"AUDIO_GENERIC_ERROR_LABEL", nil) : ORKLocalizedString(@"AUDIO_TOO_LOUD_LABEL", nil);
|
||||
[self updateAlertLabelHidden];
|
||||
|
||||
@@ -149,14 +149,14 @@ OSStatus ORKAudioGeneratorRenderTone(void *inRefCon,
|
||||
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)notification {
|
||||
if (_toneUnit) {
|
||||
OSErr err = AudioOutputUnitStart(_toneUnit);
|
||||
__unused OSErr err = AudioOutputUnitStart(_toneUnit);
|
||||
NSAssert1(err == noErr, @"Error starting unit: %hd", err);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(NSNotification *)notification {
|
||||
if (_toneUnit) {
|
||||
OSErr err = AudioOutputUnitStop(_toneUnit);
|
||||
__unused OSErr err = AudioOutputUnitStop(_toneUnit);
|
||||
NSAssert1(err == noErr, @"Error stopping unit: %hd", err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
}
|
||||
|
||||
- (void)updateCountdownLabel {
|
||||
_countdownView.timeLabel.text = [NSString stringWithFormat:@"%lu", (unsigned long)_countDown];
|
||||
_countdownView.timeLabel.text = ORKLocalizedStringFromNumber(@(_countDown));
|
||||
}
|
||||
|
||||
- (void)countDownTimerFired:(ORKActiveStepTimer *)timer finished:(BOOL)finished {
|
||||
|
||||
@@ -101,6 +101,8 @@ ORK_CLASS_AVAILABLE
|
||||
*/
|
||||
+ (ORKDataLogger *)JSONDataLoggerWithDirectory:(NSURL *)url logName:(NSString *)logName delegate:(nullable id<ORKDataLoggerDelegate>)delegate;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Returns an initialized data logger using the specified URL, log name, formatter, and delegate.
|
||||
|
||||
@@ -263,7 +265,7 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
@return `YES` if removing the files succeeded; otherwise, `NO`.
|
||||
*/
|
||||
- (BOOL)removeUploadedFiles:(NSArray *)fileURLs withError:(NSError * __nullable __autoreleasing *)error;
|
||||
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs withError:(NSError * __nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Removes all files managed by this logger (files that have the `logName` prefix).
|
||||
@@ -423,6 +425,8 @@ ORK_CLASS_AVAILABLE
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKDataLoggerManager : NSObject <ORKDataLoggerDelegate>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Returns an initialized data logger manager using the specified directory and delegate.
|
||||
|
||||
@@ -489,7 +493,7 @@ ORK_CLASS_AVAILABLE
|
||||
- (void)removeDataLogger:(ORKDataLogger *)logger;
|
||||
|
||||
/// Returns the set of log names of the data loggers managed by this object.
|
||||
- (NSArray *)logNames;
|
||||
- (NSArray<NSString *> *)logNames;
|
||||
|
||||
/**
|
||||
Enumerates all the logs that need upload across all data loggers, sorted from oldest to first.
|
||||
@@ -514,7 +518,7 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
@return `YES` if the operation succeeds; otherwise, `NO`.
|
||||
*/
|
||||
- (BOOL)unmarkUploadedFiles:(NSArray *)fileURLs error:(NSError * __nullable __autoreleasing *)error;
|
||||
- (BOOL)unmarkUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Removes a set of uploaded files.
|
||||
@@ -528,7 +532,7 @@ ORK_CLASS_AVAILABLE
|
||||
|
||||
@return `YES` if the operation succeeds; otherwise, `NO`.
|
||||
*/
|
||||
- (BOOL)removeUploadedFiles:(NSArray *)fileURLs error:(NSError * __nullable __autoreleasing *)error;
|
||||
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __nullable __autoreleasing *)error;
|
||||
|
||||
/**
|
||||
Removes old and uploaded logs to bring total bytes down to a threshold.
|
||||
|
||||
@@ -446,6 +446,12 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return [[ORKDataLogger alloc] initWithDirectory:url logName:logName formatter:[ORKJSONLogFormatter new] delegate:delegate];
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDirectory:(NSURL *)url logName:(NSString *)logName formatter:(ORKLogFormatter *)formatter delegate:(id<ORKDataLoggerDelegate>)delegate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
@@ -626,7 +632,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)removeUploadedFiles:(NSArray *)fileURLs withError:(NSError * __autoreleasing *)error {
|
||||
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs withError:(NSError * __autoreleasing *)error {
|
||||
__block BOOL success = NO;
|
||||
dispatch_sync(_queue, ^{
|
||||
success = [self queue_removeUploadedFiles:fileURLs withError:error];
|
||||
@@ -942,7 +948,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)queue_removeUploadedFiles:(NSArray *)fileURLs withError:(NSError * __autoreleasing *)error {
|
||||
- (BOOL)queue_removeUploadedFiles:(NSArray<NSURL *> *)fileURLs withError:(NSError * __autoreleasing *)error {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
__block NSMutableArray *errors = [NSMutableArray array];
|
||||
BOOL success = [self queue_enumerateLogs:^(NSURL *logFileUrl, BOOL *stop) {
|
||||
@@ -1036,6 +1042,12 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
|
||||
@implementation ORKDataLoggerManager
|
||||
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDirectory:(NSURL *)directory delegate:(id<ORKDataLoggerManagerDelegate>)delegate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
@@ -1151,8 +1163,8 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return dataLogger;
|
||||
}
|
||||
|
||||
- (NSArray *)logNames {
|
||||
__block NSArray *logNames = nil;
|
||||
- (NSArray<NSString *> *)logNames {
|
||||
__block NSArray<NSString *> *logNames = nil;
|
||||
dispatch_sync(_queue, ^{
|
||||
logNames = [_records allKeys];
|
||||
});
|
||||
@@ -1210,7 +1222,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)queue_removeUploadedFiles:(NSArray *)fileURLs error:(NSError * __autoreleasing *)error {
|
||||
- (BOOL)queue_removeUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __autoreleasing *)error {
|
||||
BOOL success = YES;
|
||||
NSMutableArray *notRemoved = [NSMutableArray array];
|
||||
for (NSURL *url in fileURLs) {
|
||||
@@ -1233,7 +1245,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)removeUploadedFiles:(NSArray *)fileURLs error:(NSError * __autoreleasing *)error {
|
||||
- (BOOL)removeUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __autoreleasing *)error {
|
||||
|
||||
__block BOOL success = YES;
|
||||
dispatch_sync(_queue, ^{
|
||||
@@ -1242,9 +1254,9 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)queue_unmarkUploadedFiles:(NSArray *)fileURLs error:(NSError * __autoreleasing *)error {
|
||||
- (BOOL)queue_unmarkUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError * __autoreleasing *)error {
|
||||
BOOL success = YES;
|
||||
NSMutableArray *notRemoved = [NSMutableArray array];
|
||||
NSMutableArray<NSURL *> *notRemoved = [NSMutableArray array];
|
||||
for (NSURL *url in fileURLs) {
|
||||
NSString *logName = [url ork_logNameInDirectory:_directory];
|
||||
ORKDataLogger *logger = _records[logName];
|
||||
@@ -1265,7 +1277,7 @@ static NSInteger _ORKJSON_terminatorLength = 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
- (BOOL)unmarkUploadedFiles:(NSArray *)fileURLs error:(NSError *__autoreleasing *)error {
|
||||
- (BOOL)unmarkUploadedFiles:(NSArray<NSURL *> *)fileURLs error:(NSError *__autoreleasing *)error {
|
||||
__block BOOL success = YES;
|
||||
dispatch_sync(_queue, ^{
|
||||
success = [self queue_unmarkUploadedFiles:fileURLs error:error];
|
||||
|
||||
@@ -100,21 +100,16 @@
|
||||
|
||||
[self.motionManager stopDeviceMotionUpdates];
|
||||
|
||||
[self.motionManager
|
||||
startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]
|
||||
withHandler:^(CMDeviceMotion *data, NSError *error)
|
||||
{
|
||||
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMDeviceMotion *data, NSError *error) {
|
||||
BOOL success = NO;
|
||||
if (data)
|
||||
{
|
||||
if (data) {
|
||||
success = [_logger append:[data ork_JSONDictionary] error:&error];
|
||||
id delegate = self.delegate;
|
||||
if ([delegate respondsToSelector:@selector(deviceMotionRecorderDidUpdateWithMotion:)]) {
|
||||
[delegate deviceMotionRecorderDidUpdateWithMotion:data];
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
if (!success) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self finishRecordingWithError:error];
|
||||
});
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
|
||||
- (void)willMoveToWindow:(UIWindow *)newWindow {
|
||||
[super willMoveToWindow:newWindow];
|
||||
_screenType = ORKGetScreenTypeForWindow(newWindow);
|
||||
_screenType = ORKGetVerticalScreenTypeForWindow(newWindow);
|
||||
[self updateConstraintConstants];
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
|
||||
#import <ResearchKit/ORKRecorder.h>
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -58,6 +59,12 @@ ORK_CLASS_AVAILABLE
|
||||
step:(nullable ORKStep *)step
|
||||
outputDirectory:(nullable NSURL *)outputDirectory NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
|
||||
/**
|
||||
The location manager, if any, being used by this recorder.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable, readonly) CLLocationManager *locationManager;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
BOOL _started;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) CLLocationManager *locationManager;
|
||||
@property (nonatomic, strong, nullable) CLLocationManager *locationManager;
|
||||
|
||||
@property (nonatomic) NSTimeInterval uptime;
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit_Private.h>
|
||||
#import "ORKCustomStepView_Internal.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ORKPSATKeyboardView;
|
||||
|
||||
@interface ORKPSATContentView : ORKActiveStepCustomView
|
||||
|
||||
@property (nonatomic, strong) ORKPSATKeyboardView *keyboardView;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
|
||||
- (instancetype)initWithPresentationMode:(ORKPSATPresentationMode)presentationMode NS_DESIGNATED_INITIALIZER;
|
||||
- (void)setEnabled:(BOOL)enabled;
|
||||
- (void)setAddition:(NSUInteger)additionIndex forTotal:(NSUInteger)totalAddition withDigit:(NSNumber *)digit;
|
||||
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKPSATContentView.h"
|
||||
#import "ORKSkin.h"
|
||||
#import "ORKPSATKeyboardView.h"
|
||||
#import "ORKTapCountLabel.h"
|
||||
#import "ORKBorderedButton.h"
|
||||
#import "ORKVoiceEngine.h"
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
|
||||
@interface ORKPSATContentView ()
|
||||
|
||||
@property (nonatomic, assign, getter = isAuditory) BOOL auditory;
|
||||
@property (nonatomic, strong) UIProgressView *progressView;
|
||||
@property (nonatomic, strong) ORKTapCountLabel *digitLabel;
|
||||
@property (nonatomic, assign) ORKScreenType screenType;
|
||||
@property (nonatomic, strong) NSArray *constraints;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKPSATContentView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [self initWithPresentationMode:ORKPSATPresentationModeAuditory];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPresentationMode:(ORKPSATPresentationMode)presentationMode {
|
||||
self = [super initWithFrame:CGRectZero];
|
||||
|
||||
if (self) {
|
||||
|
||||
_screenType = ORKGetVerticalScreenTypeForWindow(self.window);
|
||||
|
||||
_digitLabel = [ORKTapCountLabel new];
|
||||
_digitLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_digitLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self addSubview:_digitLabel];
|
||||
_auditory = (presentationMode & ORKPSATPresentationModeAuditory) ? YES : NO;
|
||||
if (!(presentationMode & ORKPSATPresentationModeVisual)) {
|
||||
_digitLabel.hidden = YES;
|
||||
}
|
||||
|
||||
_progressView = [UIProgressView new];
|
||||
_progressView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
_progressView.progressTintColor = [self tintColor];
|
||||
[_progressView setAlpha:0];
|
||||
[self addSubview:_progressView];
|
||||
|
||||
_keyboardView = [ORKPSATKeyboardView new];
|
||||
_keyboardView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self addSubview:_keyboardView];
|
||||
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[self setNeedsUpdateConstraints];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled {
|
||||
self.keyboardView.enabled = enabled;
|
||||
}
|
||||
|
||||
- (void)setAddition:(NSUInteger)additionIndex forTotal:(NSUInteger)totalAddition withDigit:(NSNumber *)digit {
|
||||
if (digit.integerValue == -1) {
|
||||
self.digitLabel.textColor = [[UIColor blackColor] colorWithAlphaComponent:0.3f];
|
||||
self.digitLabel.text = ORKLocalizedString(@"PSAT_NO_DIGIT", nil);
|
||||
} else {
|
||||
[self.keyboardView.selectedAnswerButton setSelected:NO];
|
||||
self.digitLabel.textColor = nil;
|
||||
self.digitLabel.text = [NSNumberFormatter localizedStringFromNumber:digit
|
||||
numberStyle:NSNumberFormatterNoStyle];
|
||||
if (self.isAuditory) {
|
||||
[[ORKVoiceEngine sharedVoiceEngine] speakInt:digit.integerValue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated {
|
||||
[self.progressView setProgress:progress animated:animated];
|
||||
[UIView animateWithDuration:animated ? 0.2 : 0 animations:^{
|
||||
[self.progressView setAlpha:(progress == 0) ? 0 : 1];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateConstraints {
|
||||
if ([self.constraints count]) {
|
||||
[NSLayoutConstraint deactivateConstraints:self.constraints];
|
||||
self.constraints = nil;
|
||||
}
|
||||
|
||||
const CGFloat ORKPSATKeyboardWidth = ORKGetMetricForScreenType(ORKScreenMetricPSATKeyboardViewWidth, self.screenType);
|
||||
const CGFloat ORKPSATKeyboardHeight = ORKGetMetricForScreenType(ORKScreenMetricPSATKeyboardViewHeight, self.screenType);
|
||||
|
||||
NSMutableArray *constraintsArray = [NSMutableArray array];
|
||||
|
||||
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView, _digitLabel, _keyboardView);
|
||||
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_progressView]-|"
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil views:views]];
|
||||
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-[_keyboardView(==%f)]-|", ORKPSATKeyboardWidth]
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil views:views]];
|
||||
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[_keyboardView(==%f)]", ORKPSATKeyboardHeight]
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil views:views]];
|
||||
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_progressView]-[_digitLabel]-(>=10)-[_keyboardView]-|"
|
||||
options:NSLayoutFormatAlignAllCenterX
|
||||
metrics:nil views:views]];
|
||||
|
||||
self.constraints = constraintsArray;
|
||||
[self addConstraints:self.constraints];
|
||||
|
||||
[NSLayoutConstraint activateConstraints:self.constraints];
|
||||
[super updateConstraints];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ORKBorderedButton;
|
||||
@protocol ORKPSATKeyboardViewDelegate;
|
||||
|
||||
@interface ORKPSATKeyboardView : UIView
|
||||
|
||||
@property (nonatomic, weak) id<ORKPSATKeyboardViewDelegate> delegate;
|
||||
@property (nonatomic, weak) ORKBorderedButton *selectedAnswerButton;
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
|
||||
@protocol ORKPSATKeyboardViewDelegate <NSObject>
|
||||
|
||||
- (void)keyboardView:(ORKPSATKeyboardView *)keyboardView didSelectAnswer:(NSInteger)answer;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKPSATKeyboardView.h"
|
||||
#import "ORKBorderedButton.h"
|
||||
|
||||
|
||||
NSUInteger const ORKPSATMinimumAnswer = 3;
|
||||
NSUInteger const ORKPSATMaximumAnswer = 17;
|
||||
|
||||
@interface ORKPSATKeyboardView ()
|
||||
|
||||
@property (nonatomic, strong, readonly) NSArray *answerButtons;
|
||||
@property (nonatomic, strong) NSArray *constraints;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKPSATKeyboardView
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSMutableArray *buttonsArray = [[NSMutableArray alloc] initWithCapacity:(ORKPSATMaximumAnswer - ORKPSATMinimumAnswer) + 1];
|
||||
ORKBorderedButton *answerButton = nil;
|
||||
for (int i = ORKPSATMinimumAnswer; i <= ORKPSATMaximumAnswer; i++) {
|
||||
answerButton = [self answerButtonWithTitle:[NSNumberFormatter localizedStringFromNumber:@(i)
|
||||
numberStyle:NSNumberFormatterNoStyle]];
|
||||
[buttonsArray addObject:answerButton];
|
||||
[self addSubview:answerButton];
|
||||
}
|
||||
_answerButtons = [NSArray arrayWithArray:buttonsArray];
|
||||
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[self setNeedsUpdateConstraints];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (ORKBorderedButton *)answerButtonWithTitle:(NSString *)title {
|
||||
ORKBorderedButton *answerButton = [ORKBorderedButton new];
|
||||
answerButton.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[answerButton setTitle:title forState:UIControlStateNormal];
|
||||
[answerButton addTarget:self action:@selector(buttonPressed:forEvent:) forControlEvents:UIControlEventTouchUpInside];
|
||||
answerButton.accessibilityTraits |= UIAccessibilityTraitKeyboardKey;
|
||||
return answerButton;
|
||||
}
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled {
|
||||
for (ORKBorderedButton *answerButton in self.answerButtons) {
|
||||
[answerButton setEnabled:enabled];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateConstraints {
|
||||
if ([self.constraints count]) {
|
||||
[NSLayoutConstraint deactivateConstraints:self.constraints];
|
||||
self.constraints = nil;
|
||||
}
|
||||
|
||||
NSMutableArray *constraintsArray = [NSMutableArray array];
|
||||
|
||||
ORKBorderedButton *answer3Button = self.answerButtons[0];
|
||||
ORKBorderedButton *answer4Button = self.answerButtons[1];
|
||||
ORKBorderedButton *answer5Button = self.answerButtons[2];
|
||||
ORKBorderedButton *answer6Button = self.answerButtons[3];
|
||||
ORKBorderedButton *answer7Button = self.answerButtons[4];
|
||||
ORKBorderedButton *answer8Button = self.answerButtons[5];
|
||||
ORKBorderedButton *answer9Button = self.answerButtons[6];
|
||||
ORKBorderedButton *answer10Button = self.answerButtons[7];
|
||||
ORKBorderedButton *answer11Button = self.answerButtons[8];
|
||||
ORKBorderedButton *answer12Button = self.answerButtons[9];
|
||||
ORKBorderedButton *answer13Button = self.answerButtons[10];
|
||||
ORKBorderedButton *answer14Button = self.answerButtons[11];
|
||||
ORKBorderedButton *answer15Button = self.answerButtons[12];
|
||||
ORKBorderedButton *answer16Button = self.answerButtons[13];
|
||||
ORKBorderedButton *answer17Button = self.answerButtons[14];
|
||||
|
||||
|
||||
NSDictionary *views = NSDictionaryOfVariableBindings(answer3Button, answer4Button, answer5Button, answer6Button, answer7Button, answer8Button, answer9Button, answer10Button, answer11Button, answer12Button, answer13Button, answer14Button, answer15Button, answer16Button, answer17Button);
|
||||
|
||||
// First line of answer buttons
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[answer3Button]-[answer4Button(==answer3Button)]-[answer5Button(==answer3Button)]-[answer6Button(==answer3Button)]-[answer7Button(==answer3Button)]-|"
|
||||
options:NSLayoutFormatAlignAllCenterY|NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom
|
||||
metrics:nil views:views]];
|
||||
|
||||
// Second line of answer buttons
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[answer8Button]-[answer9Button(==answer8Button)]-[answer10Button(==answer8Button)]-[answer11Button(==answer8Button)]-[answer12Button(==answer8Button)]-|"
|
||||
options:NSLayoutFormatAlignAllCenterY|NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom
|
||||
metrics:nil views:views]];
|
||||
|
||||
// Third line of answer buttons
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[answer13Button]-[answer14Button(==answer13Button)]-[answer15Button(==answer13Button)]-[answer16Button(==answer13Button)]-[answer17Button(==answer13Button)]-|"
|
||||
options:NSLayoutFormatAlignAllCenterY|NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom
|
||||
metrics:nil views:views]];
|
||||
|
||||
// Align vertically
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[answer3Button]-[answer8Button(==answer3Button)]-[answer13Button(==answer3Button)]-|"
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil views:views]];
|
||||
|
||||
self.constraints = constraintsArray;
|
||||
[self addConstraints:self.constraints];
|
||||
|
||||
[NSLayoutConstraint activateConstraints:self.constraints];
|
||||
[super updateConstraints];
|
||||
}
|
||||
|
||||
#pragma mark buttonAction
|
||||
|
||||
- (IBAction)buttonPressed:(id)button forEvent:(UIEvent *)event {
|
||||
ORKBorderedButton *tappedAnswerButton = (ORKBorderedButton *)button;
|
||||
|
||||
[self.selectedAnswerButton setSelected:NO];
|
||||
self.selectedAnswerButton = tappedAnswerButton;
|
||||
[self.selectedAnswerButton setSelected:YES];
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(keyboardView:didSelectAnswer:)]) {
|
||||
NSInteger answerValue = [self.answerButtons indexOfObject:tappedAnswerButton] + ORKPSATMinimumAnswer;
|
||||
[self.delegate keyboardView:self didSelectAnswer:answerValue];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit_Private.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKPSATStep : ORKActiveStep
|
||||
|
||||
@property (nonatomic, assign) ORKPSATPresentationMode presentationMode;
|
||||
@property (nonatomic, assign) NSTimeInterval interStimulusInterval;
|
||||
@property (nonatomic, assign) NSTimeInterval stimulusDuration;
|
||||
@property (nonatomic, assign) NSInteger seriesLength;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKPSATStep.h"
|
||||
#import "ORKPSATStepViewController.h"
|
||||
|
||||
|
||||
@implementation ORKPSATStep
|
||||
|
||||
+ (Class)stepViewControllerClass {
|
||||
return [ORKPSATStepViewController class];
|
||||
}
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier {
|
||||
self = [super initWithIdentifier:identifier];
|
||||
if (self) {
|
||||
self.shouldStartTimerAutomatically = YES;
|
||||
self.shouldShowDefaultTimer = NO;
|
||||
self.shouldContinueOnFinish = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)validateParameters {
|
||||
[super validateParameters];
|
||||
|
||||
NSTimeInterval const ORKPSATInterStimulusMinimumInterval = 1.0;
|
||||
NSTimeInterval const ORKPSATInterStimulusMaximumInterval = 5.0;
|
||||
|
||||
NSTimeInterval const ORKPSATStimulusMinimumDuration = 0.2;
|
||||
|
||||
NSInteger const ORKPSATSerieMinimumLength = 10;
|
||||
NSInteger const ORKPSATSerieMaximumLength = 120;
|
||||
|
||||
NSTimeInterval totalDuration = (self.seriesLength + 1) * self.interStimulusInterval;
|
||||
if (self.stepDuration != totalDuration) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"step duration must be equal to %@ seconds.", @(totalDuration)] userInfo:nil];
|
||||
}
|
||||
|
||||
if (!(self.presentationMode & ORKPSATPresentationModeAuditory) &&
|
||||
!(self.presentationMode & ORKPSATPresentationModeVisual)) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"step presentation mode must be auditory and/or visual." userInfo:nil];
|
||||
}
|
||||
|
||||
if (self.interStimulusInterval < ORKPSATInterStimulusMinimumInterval ||
|
||||
self.interStimulusInterval > ORKPSATInterStimulusMaximumInterval) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"inter stimulus interval must be greater than or equal to %@ seconds and less than or equal to %@ seconds.", @(ORKPSATInterStimulusMinimumInterval), @(ORKPSATInterStimulusMaximumInterval)] userInfo:nil];
|
||||
}
|
||||
|
||||
if ((self.presentationMode & ORKPSATPresentationModeVisual) &&
|
||||
(self.stimulusDuration < ORKPSATStimulusMinimumDuration || self.stimulusDuration > self.interStimulusInterval)) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"stimulus duration must be greater than or equal to %@ seconds and less than or equal to %@ seconds.", @(ORKPSATStimulusMinimumDuration), @(self.interStimulusInterval)] userInfo:nil];
|
||||
}
|
||||
|
||||
if (self.seriesLength < ORKPSATSerieMinimumLength ||
|
||||
self.seriesLength > ORKPSATSerieMaximumLength) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"serie length must be greater than or equal to %@ additions and less than or equal to %@ additions.", @(ORKPSATSerieMinimumLength), @(ORKPSATSerieMaximumLength)] userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)allowsBackNavigation {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit_Private.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKPSATStepViewController : ORKActiveStepViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKPSATStepViewController.h"
|
||||
#import "ORKActiveStepViewController_Internal.h"
|
||||
#import "ORKStepViewController_Internal.h"
|
||||
#import "ORKPSATContentView.h"
|
||||
#import "ORKPSATStep.h"
|
||||
#import "ORKVerticalContainerView.h"
|
||||
#import "ORKActiveStepView.h"
|
||||
#import "ORKPSATKeyboardView.h"
|
||||
|
||||
|
||||
@interface ORKPSATStepViewController () <ORKPSATKeyboardViewDelegate>
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *samples;
|
||||
@property (nonatomic, strong) ORKPSATContentView *psatContentView;
|
||||
@property (nonatomic, strong) NSArray *digits;
|
||||
@property (nonatomic, assign) NSUInteger currentDigitIndex;
|
||||
@property (nonatomic, assign) NSInteger currentAnswer;
|
||||
@property (nonatomic, strong) ORKActiveStepTimer *clearDigitsTimer;
|
||||
@property (nonatomic, assign) NSTimeInterval answerStart;
|
||||
@property (nonatomic, assign) NSTimeInterval answerEnd;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ORKPSATStepViewController
|
||||
|
||||
- (instancetype)initWithStep:(ORKStep *)step {
|
||||
self = [super initWithStep:step];
|
||||
|
||||
if (self) {
|
||||
self.suspendIfInactive = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (ORKPSATStep *)psatStep {
|
||||
return (ORKPSATStep *)self.step;
|
||||
}
|
||||
|
||||
- (NSArray *)arrayWithPSATDigits {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:[self psatStep].seriesLength + 1];
|
||||
NSUInteger digit = 0;
|
||||
for (NSUInteger i = 0; i < [self psatStep].seriesLength + 1; i++) {
|
||||
do
|
||||
{
|
||||
digit = (arc4random() % (9)) + 1;
|
||||
} while (digit == ((NSNumber *)[array lastObject]).integerValue);
|
||||
[array addObject:@(digit)];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
- (void)initializeInternalButtonItems {
|
||||
[super initializeInternalButtonItems];
|
||||
|
||||
// Don't show buttons
|
||||
self.internalContinueButtonItem = nil;
|
||||
self.internalDoneButtonItem = nil;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.activeStepView.stepViewFillsAvailableSpace = YES;
|
||||
self.psatContentView = [[ORKPSATContentView alloc] initWithPresentationMode:[self psatStep].presentationMode];
|
||||
self.psatContentView.keyboardView.delegate = self;
|
||||
[self.psatContentView setEnabled:NO];
|
||||
self.activeStepView.activeCustomView = self.psatContentView;
|
||||
|
||||
self.timerUpdateInterval = [self psatStep].interStimulusInterval;
|
||||
}
|
||||
|
||||
- (ORKStepResult *)result {
|
||||
|
||||
ORKStepResult *sResult = [super result];
|
||||
|
||||
NSMutableArray *results = [NSMutableArray arrayWithArray:sResult.results];
|
||||
|
||||
ORKPSATResult *PSATResult = [[ORKPSATResult alloc] initWithIdentifier:(NSString *__nonnull)self.step.identifier];
|
||||
PSATResult.presentationMode = [self psatStep].presentationMode;
|
||||
PSATResult.interStimulusInterval = [self psatStep].interStimulusInterval;
|
||||
if ([self psatStep].presentationMode & ORKPSATPresentationModeVisual) {
|
||||
PSATResult.stimulusDuration = [self psatStep].stimulusDuration;
|
||||
} else {
|
||||
PSATResult.stimulusDuration = 0.0;
|
||||
}
|
||||
PSATResult.length = [self psatStep].seriesLength;
|
||||
PSATResult.initialDigit = [(NSNumber *)[self.digits objectAtIndex:0] integerValue];
|
||||
NSInteger totalCorrect = 0;
|
||||
BOOL previousAnswerCorrect = NO;
|
||||
NSInteger totalDyad = 0;
|
||||
CGFloat totalTime = 0.0;
|
||||
for (ORKPSATSample *sample in self.samples) {
|
||||
totalTime += sample.time;
|
||||
if (sample.isCorrect) {
|
||||
totalCorrect++;
|
||||
if (previousAnswerCorrect) {
|
||||
totalDyad++;
|
||||
}
|
||||
}
|
||||
previousAnswerCorrect = sample.isCorrect;
|
||||
}
|
||||
PSATResult.totalCorrect = totalCorrect;
|
||||
PSATResult.totalTime = totalTime;
|
||||
PSATResult.totalDyad = totalDyad;
|
||||
PSATResult.samples = self.samples;
|
||||
|
||||
[results addObject:PSATResult];
|
||||
|
||||
sResult.results = [results copy];
|
||||
|
||||
return sResult;
|
||||
}
|
||||
|
||||
- (void)start {
|
||||
self.digits = [self arrayWithPSATDigits];
|
||||
self.currentDigitIndex = 0;
|
||||
[self.psatContentView setAddition:self.currentDigitIndex forTotal:[self psatStep].seriesLength withDigit:[self.digits objectAtIndex:self.currentDigitIndex]];
|
||||
[self.psatContentView setProgress:0.001 animated:NO];
|
||||
self.currentAnswer = -1;
|
||||
self.samples = [NSMutableArray array];
|
||||
|
||||
if ([self psatStep].presentationMode & ORKPSATPresentationModeVisual &&
|
||||
([self psatStep].interStimulusInterval - [self psatStep].stimulusDuration) > 0.05 ) {
|
||||
|
||||
// Don't show `-` if the difference between stimulusDuration and interStimulusInterval is less than timer's resolution.
|
||||
__weak typeof(self) weakSelf = self;
|
||||
self.clearDigitsTimer = [[ORKActiveStepTimer alloc] initWithDuration:[self psatStep].stepDuration
|
||||
interval:[self psatStep].interStimulusInterval
|
||||
runtime:-[self psatStep].stimulusDuration
|
||||
handler:^(ORKActiveStepTimer *timer, BOOL finished) {
|
||||
typeof(self) strongSelf = weakSelf;
|
||||
[strongSelf clearDigitsTimerFired];
|
||||
}];
|
||||
[self.clearDigitsTimer resume];
|
||||
}
|
||||
|
||||
[super start];
|
||||
}
|
||||
|
||||
- (void)suspend {
|
||||
[self.clearDigitsTimer pause];
|
||||
[super suspend];
|
||||
}
|
||||
|
||||
- (void)resume {
|
||||
[self.clearDigitsTimer resume];
|
||||
[super resume];
|
||||
}
|
||||
|
||||
- (void)finish {
|
||||
[self.clearDigitsTimer reset];
|
||||
self.clearDigitsTimer = nil;
|
||||
[super finish];
|
||||
}
|
||||
|
||||
- (void)countDownTimerFired:(ORKActiveStepTimer *)timer finished:(BOOL)finished {
|
||||
if (self.currentDigitIndex == 0) {
|
||||
[self.psatContentView setEnabled:YES];
|
||||
[self.activeStepView updateTitle:ORKLocalizedString(@"PSAT_INSTRUCTION", nil) text:nil];
|
||||
} else {
|
||||
[self saveSample];
|
||||
}
|
||||
|
||||
self.currentDigitIndex++;
|
||||
self.answerStart = CACurrentMediaTime();
|
||||
self.answerEnd = 0;
|
||||
|
||||
if (self.currentDigitIndex <= [self psatStep].seriesLength) {
|
||||
[self.psatContentView setAddition:self.currentDigitIndex forTotal:[self psatStep].seriesLength withDigit:[self.digits objectAtIndex:self.currentDigitIndex]];
|
||||
}
|
||||
|
||||
self.currentAnswer = -1;
|
||||
|
||||
CGFloat progress = finished ? 1 : (timer.runtime / timer.duration);
|
||||
[self.psatContentView setProgress:progress animated:YES];
|
||||
|
||||
[super countDownTimerFired:timer finished:finished];
|
||||
}
|
||||
|
||||
- (void)clearDigitsTimerFired {
|
||||
[self.psatContentView setAddition:self.currentDigitIndex forTotal:[self psatStep].seriesLength withDigit:@(-1)];
|
||||
}
|
||||
|
||||
- (void)saveSample {
|
||||
ORKPSATSample *sample = [[ORKPSATSample alloc] init];
|
||||
NSInteger previousDigit = [(NSNumber *)[self.digits objectAtIndex:self.currentDigitIndex - 1] integerValue];
|
||||
NSInteger currentDigit = [(NSNumber *)[self.digits objectAtIndex:self.currentDigitIndex] integerValue];
|
||||
sample.correct = previousDigit + currentDigit == self.currentAnswer ? YES : NO;
|
||||
sample.digit = currentDigit;
|
||||
sample.answer = self.currentAnswer;
|
||||
sample.time = self.answerEnd == 0 ? [self psatStep].interStimulusInterval : self.answerEnd - self.answerStart;
|
||||
|
||||
[self.samples addObject:sample];
|
||||
}
|
||||
|
||||
#pragma mark - keyboard view delegate
|
||||
|
||||
- (void)keyboardView:(ORKPSATKeyboardView *)keyboardView didSelectAnswer:(NSInteger)answer {
|
||||
self.currentAnswer = answer;
|
||||
self.answerEnd = CACurrentMediaTime();
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -84,10 +84,8 @@ static const NSTimeInterval OutcomeAnimationDuration = 0.3;
|
||||
}
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
|
||||
{
|
||||
if(event.type == UIEventSubtypeMotionShake)
|
||||
{
|
||||
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
|
||||
if (event.type == UIEventSubtypeMotionShake) {
|
||||
if (_validResult) {
|
||||
ORKReactionTimeResult *reactionTimeResult = [[ORKReactionTimeResult alloc] initWithIdentifier:self.step.identifier];
|
||||
reactionTimeResult.timestamp = _stimulusTimestamp;
|
||||
@@ -147,7 +145,7 @@ static const NSTimeInterval OutcomeAnimationDuration = 0.3;
|
||||
|
||||
- (void)configureTitle {
|
||||
NSString *format = ORKLocalizedString(@"REACTION_TIME_TASK_ATTEMPTS_FORMAT", nil);
|
||||
NSString *text = [NSString stringWithFormat:format, _results.count + 1, [self reactionTimeStep].numberOfAttempts];
|
||||
NSString *text = [NSString stringWithFormat:format, ORKLocalizedStringFromNumber(@(_results.count + 1)), ORKLocalizedStringFromNumber(@([self reactionTimeStep].numberOfAttempts))];
|
||||
[self.activeStepView updateTitle:ORKLocalizedString(@"REACTION_TIME_TASK_ACTIVE_STEP_TITLE", nil) text:text];
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ ORK_CLASS_AVAILABLE
|
||||
If your recorder requires or would benefit from read access to HealthKit at
|
||||
runtime during the task, return the appropriate set of `HKSampleType` objects.
|
||||
*/
|
||||
- (nullable NSSet *)requestedHealthKitTypesForReading;
|
||||
- (nullable NSSet<HKObjectType *> *)requestedHealthKitTypesForReading;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -40,12 +40,14 @@
|
||||
|
||||
@implementation ORKRecorderConfiguration
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
if (nil == identifier) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"identifier cannot be nil." userInfo:nil];
|
||||
}
|
||||
ORKThrowInvalidArgumentExceptionIfNil(identifier);
|
||||
_identifier = [identifier copy];
|
||||
}
|
||||
return self;
|
||||
@@ -82,7 +84,7 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSSet *)requestedHealthKitTypesForReading {
|
||||
- (NSSet<HKObjectType *> *)requestedHealthKitTypesForReading {
|
||||
return nil;
|
||||
}
|
||||
- (ORKPermissionMask)requestedPermissionMask {
|
||||
@@ -170,7 +172,7 @@
|
||||
if (! _outputDirectory) {
|
||||
return nil;
|
||||
}
|
||||
return [NSURL fileURLWithPath:[_outputDirectory.path stringByAppendingPathComponent:[NSString stringWithFormat:@"recorder-%@",[_recorderUUID UUIDString]]]];
|
||||
return [NSURL fileURLWithPath:[_outputDirectory.path stringByAppendingPathComponent:[NSString stringWithFormat:@"recorder-%@", _recorderUUID.UUIDString]]];
|
||||
}
|
||||
|
||||
- (NSString *)recorderType {
|
||||
@@ -178,7 +180,7 @@
|
||||
}
|
||||
|
||||
- (NSString *)logName {
|
||||
return [NSString stringWithFormat:@"%@_%@", [self recorderType],self.identifier];
|
||||
return [NSString stringWithFormat:@"%@_%@", [self recorderType], _recorderUUID.UUIDString];
|
||||
}
|
||||
|
||||
- (ORKDataLogger *)makeJSONDataLoggerWithError:(NSError * __autoreleasing *)error {
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
*/
|
||||
@interface ORKSpatialSpanGame : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
Returns an initialized spatial span game using the specified game size, sequence length, and seed.
|
||||
|
||||
|
||||
@@ -30,12 +30,16 @@
|
||||
|
||||
|
||||
#import "ORKSpatialSpanGame.h"
|
||||
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
@implementation ORKSpatialSpanGame {
|
||||
NSInteger *_sequence;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (void)generateSequence {
|
||||
_sequence = calloc(_gameSize, sizeof(NSInteger));
|
||||
if (_sequence == NULL) {
|
||||
|
||||
@@ -45,6 +45,8 @@ typedef NS_ENUM(NSInteger, ORKSpatialSpanResult) {
|
||||
|
||||
@interface ORKSpatialSpanGameState : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithGame:(ORKSpatialSpanGame *)game NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, strong, readonly, nullable) ORKSpatialSpanGame *game;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#import "ORKSpatialSpanGameState.h"
|
||||
#import "ORKSpatialSpanGame.h"
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
|
||||
@implementation ORKSpatialSpanGameState {
|
||||
@@ -38,6 +39,10 @@
|
||||
ORKSpatialSpanTargetState *_states;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)initWithGame:(ORKSpatialSpanGame *)game {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
@@ -258,13 +258,19 @@
|
||||
[self updateFooterHidden];
|
||||
}
|
||||
|
||||
|
||||
- (void)updateMargins {
|
||||
self.layoutMargins = (UIEdgeInsets){.left=ORKStandardHorizMarginForView(self), .right=ORKStandardHorizMarginForView(self)};
|
||||
CGFloat margin = ORKStandardHorizontalMarginForView(self);
|
||||
self.layoutMargins = (UIEdgeInsets){.left = margin, .right = margin};
|
||||
_quantityPairView.layoutMargins = self.layoutMargins;
|
||||
}
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
||||
- (void)setFrame:(CGRect)frame {
|
||||
[super setFrame:frame];
|
||||
[self updateMargins];
|
||||
}
|
||||
|
||||
- (void)setBounds:(CGRect)bounds {
|
||||
[super setBounds:bounds];
|
||||
[self updateMargins];
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
NSArray *_constraints;
|
||||
ORKScreenType _screenType;
|
||||
UIView *_buttonContainer;
|
||||
NSNumberFormatter *_formatter;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
@@ -116,7 +117,12 @@
|
||||
}
|
||||
|
||||
- (void)setTapCount:(NSUInteger)tapCount {
|
||||
_tapCountLabel.text = [NSString stringWithFormat:@"%02lu", (unsigned long)tapCount];
|
||||
if (_formatter == nil) {
|
||||
_formatter = [NSNumberFormatter new];
|
||||
_formatter.locale = [NSLocale currentLocale];
|
||||
_formatter.minimumIntegerDigits = 2;
|
||||
}
|
||||
_tapCountLabel.text = [_formatter stringFromNumber:@(tapCount)];
|
||||
}
|
||||
|
||||
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated {
|
||||
@@ -141,10 +147,25 @@
|
||||
|
||||
- (void)willMoveToWindow:(UIWindow *)newWindow {
|
||||
[super willMoveToWindow:newWindow];
|
||||
_screenType = ORKGetScreenTypeForWindow(newWindow);
|
||||
_screenType = ORKGetVerticalScreenTypeForWindow(newWindow);
|
||||
[self setNeedsUpdateConstraints];
|
||||
}
|
||||
|
||||
- (void)updateLayoutMargins {
|
||||
CGFloat margin = ORKStandardHorizontalMarginForView(self);
|
||||
self.layoutMargins = (UIEdgeInsets) { .left=margin*2, .right=margin*2 };
|
||||
}
|
||||
|
||||
- (void)setFrame:(CGRect)frame {
|
||||
[super setFrame:frame];
|
||||
[self updateLayoutMargins];
|
||||
}
|
||||
|
||||
- (void)setBounds:(CGRect)bounds {
|
||||
[super setBounds:bounds];
|
||||
[self updateLayoutMargins];
|
||||
}
|
||||
|
||||
- (void)updateConstraints {
|
||||
if ([_constraints count]) {
|
||||
[NSLayoutConstraint deactivateConstraints:_constraints];
|
||||
@@ -154,8 +175,6 @@
|
||||
ORKScreenType screenType = _screenType;
|
||||
const CGFloat HeaderBaselineToCaptionTop = ORKGetMetricForScreenType(ORKScreenMetricCaptionBaselineToTappingLabelTop, screenType);
|
||||
const CGFloat AssumedHeaderBaselineToStepViewTop = ORKGetMetricForScreenType(ORKScreenMetricLearnMoreBaselineToStepViewTop, screenType);
|
||||
CGFloat margin = ORKStandardHorizMarginForView(self);
|
||||
self.layoutMargins = (UIEdgeInsets) { .left=margin*2, .right=margin*2 };
|
||||
|
||||
static const CGFloat CaptionBaselineToTapCountBaseline = 56;
|
||||
static const CGFloat TapButtonBottomToBottom = 36;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKCustomStepView_Internal.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface ORKTimedWalkContentView : ORKActiveStepCustomView
|
||||
|
||||
@property (nonatomic, strong, nullable) UIImage *image;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTimedWalkContentView.h"
|
||||
#import "ORKSkin.h"
|
||||
#import "ORKProgressView.h"
|
||||
#import "ORKActiveStepQuantityView.h"
|
||||
#import "ORKTintedImageView.h"
|
||||
|
||||
|
||||
@interface ORKTimedWalkContentView ()
|
||||
|
||||
@property (nonatomic, strong) ORKProgressView *progressView;
|
||||
@property (nonatomic, strong) ORKTintedImageView *imageView;
|
||||
@property (nonatomic, strong) NSLayoutConstraint *imageRatioConstraint;
|
||||
@property (nonatomic, copy) NSArray *constraints;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKTimedWalkContentView
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_progressView = [ORKProgressView new];
|
||||
_progressView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self addSubview:_progressView];
|
||||
|
||||
_imageView = [ORKTintedImageView new];
|
||||
_imageView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
_imageView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
_imageView.shouldApplyTint = YES;
|
||||
_imageView.isAccessibilityElement = NO;
|
||||
[self addSubview:_imageView];
|
||||
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[self setNeedsUpdateConstraints];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setImage:(UIImage *)image {
|
||||
_image = image;
|
||||
self.imageView.image = image;
|
||||
|
||||
self.imageRatioConstraint.active = NO;
|
||||
|
||||
CGSize size = image.size;
|
||||
if (size.width > 0 && size.height > 0) {
|
||||
self.imageRatioConstraint = [NSLayoutConstraint constraintWithItem:_imageView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:_imageView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
multiplier:size.height/size.width
|
||||
constant:0];
|
||||
self.imageRatioConstraint.active = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateConstraints {
|
||||
if ([self.constraints count]) {
|
||||
[NSLayoutConstraint deactivateConstraints:self.constraints];
|
||||
self.constraints = nil;
|
||||
}
|
||||
|
||||
NSMutableArray *constraintsArray = [NSMutableArray array];
|
||||
|
||||
NSDictionary *views = NSDictionaryOfVariableBindings(_progressView, _imageView);
|
||||
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_progressView]|"
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil views:views]];
|
||||
|
||||
[constraintsArray addObjectsFromArray:
|
||||
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_progressView]-(>=10)-[_imageView]-|"
|
||||
options:NSLayoutFormatAlignAllCenterX
|
||||
metrics:nil views:views]];
|
||||
|
||||
self.constraints = constraintsArray;
|
||||
[self addConstraints:self.constraints];
|
||||
|
||||
[NSLayoutConstraint activateConstraints:self.constraints];
|
||||
[super updateConstraints];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit_Private.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKTimedWalkStep : ORKActiveStep
|
||||
|
||||
@property (nonatomic, assign) double distanceInMeters;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTimedWalkStep.h"
|
||||
#import "ORKTimedWalkStepViewController.h"
|
||||
|
||||
|
||||
@implementation ORKTimedWalkStep
|
||||
|
||||
+ (Class)stepViewControllerClass {
|
||||
return [ORKTimedWalkStepViewController class];
|
||||
}
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier {
|
||||
self = [super initWithIdentifier:identifier];
|
||||
if (self) {
|
||||
self.shouldStartTimerAutomatically = YES;
|
||||
self.shouldShowDefaultTimer = NO;
|
||||
self.shouldPlaySoundOnStart = YES;
|
||||
self.shouldPlaySoundOnFinish = YES;
|
||||
self.shouldVibrateOnStart = YES;
|
||||
self.shouldVibrateOnFinish = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)validateParameters {
|
||||
[super validateParameters];
|
||||
|
||||
double const ORKTimedWalkMinimumDistanceInMeters = 1.0;
|
||||
double const ORKTimedWalkMaximumDistanceInMeters = 10000.0;
|
||||
|
||||
NSTimeInterval const ORKTimedWalkMinimumDuration = 1.0;
|
||||
|
||||
if (self.distanceInMeters < ORKTimedWalkMinimumDistanceInMeters ||
|
||||
self.distanceInMeters > ORKTimedWalkMaximumDistanceInMeters) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"timed walk distance must be greater than or equal to %@ meters and less than or equal to %@ meters.", @(ORKTimedWalkMinimumDistanceInMeters), @(ORKTimedWalkMaximumDistanceInMeters)] userInfo:nil];
|
||||
}
|
||||
|
||||
if (self.stepDuration < ORKTimedWalkMinimumDuration) {
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"duration can not be shorter than %@ seconds.", @(ORKTimedWalkMinimumDuration)] userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)allowsBackNavigation {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit_Private.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKTimedWalkStepViewController : ORKActiveStepViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (c) 2015, Shazino SAS. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTimedWalkStepViewController.h"
|
||||
#import "ORKTimedWalkContentView.h"
|
||||
#import "ORKTimedWalkStep.h"
|
||||
#import "ORKActiveStepViewController_Internal.h"
|
||||
#import "ORKNavigationContainerView_Internal.h"
|
||||
#import "ORKStepViewController_Internal.h"
|
||||
#import "ORKActiveStepView.h"
|
||||
|
||||
|
||||
double const kDistanceInMetersTrackingThreshold = 100.0;
|
||||
|
||||
|
||||
@interface ORKTimedWalkStepViewController ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray *samples;
|
||||
@property (nonatomic, strong) ORKTimedWalkContentView *timedWalkContentView;
|
||||
@property (nonatomic, assign) NSTimeInterval trialDuration;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKTimedWalkStepViewController
|
||||
|
||||
- (instancetype)initWithStep:(ORKStep *)step {
|
||||
self = [super initWithStep:step];
|
||||
|
||||
if (self) {
|
||||
self.suspendIfInactive = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (ORKTimedWalkStep *)timedWalkStep {
|
||||
return (ORKTimedWalkStep *)self.step;
|
||||
}
|
||||
|
||||
- (void)initializeInternalButtonItems {
|
||||
[super initializeInternalButtonItems];
|
||||
|
||||
self.internalDoneButtonItem = nil;
|
||||
self.continueButtonTitle = ORKLocalizedString(@"BUTTON_DONE", nil);
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.timedWalkContentView = [ORKTimedWalkContentView new];
|
||||
self.timedWalkContentView.image = [self timedWalkStep].image;
|
||||
self.activeStepView.activeCustomView = self.timedWalkContentView;
|
||||
self.activeStepView.stepViewFillsAvailableSpace = YES;
|
||||
self.activeStepView.continueSkipContainer.continueEnabled = YES;
|
||||
|
||||
self.timerUpdateInterval = 0.1f;
|
||||
}
|
||||
|
||||
- (void)finish {
|
||||
[super finish];
|
||||
|
||||
[self goForward];
|
||||
}
|
||||
|
||||
- (void)countDownTimerFired:(ORKActiveStepTimer *)timer finished:(BOOL)finished {
|
||||
self.trialDuration = timer.runtime;
|
||||
[super countDownTimerFired:timer finished:finished];
|
||||
}
|
||||
|
||||
- (ORKStepResult *)result {
|
||||
ORKStepResult *sResult = [super result];
|
||||
|
||||
NSMutableArray *results = [NSMutableArray arrayWithArray:sResult.results];
|
||||
|
||||
ORKTimedWalkResult *timedWalkResult = [[ORKTimedWalkResult alloc] initWithIdentifier:(NSString *__nonnull)self.step.identifier];
|
||||
timedWalkResult.distanceInMeters = [self timedWalkStep].distanceInMeters;
|
||||
timedWalkResult.timeLimit = [self timedWalkStep].stepDuration;
|
||||
timedWalkResult.duration = self.trialDuration;
|
||||
|
||||
[results addObject:timedWalkResult];
|
||||
|
||||
sResult.results = [results copy];
|
||||
|
||||
return sResult;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -51,7 +51,7 @@
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
_screenType = ORKGetScreenTypeForWindow(self.window);
|
||||
_screenType = ORKGetVerticalScreenTypeForWindow(self.window);
|
||||
_captionLabel = [ORKUnitLabel new];
|
||||
_captionLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_captionLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
@@ -101,12 +101,25 @@
|
||||
self.tapButton.enabled = NO;
|
||||
}
|
||||
|
||||
- (void)updateLayoutMargins {
|
||||
CGFloat margin = ORKStandardHorizontalMarginForView(self);
|
||||
self.layoutMargins = (UIEdgeInsets) { .left=margin*2, .right=margin*2 };
|
||||
}
|
||||
|
||||
- (void)setFrame:(CGRect)frame {
|
||||
[super setFrame:frame];
|
||||
[self updateLayoutMargins];
|
||||
}
|
||||
|
||||
- (void)setBounds:(CGRect)bounds {
|
||||
[super setBounds:bounds];
|
||||
[self updateLayoutMargins];
|
||||
}
|
||||
|
||||
- (void)setupConstraints {
|
||||
ORKScreenType screenType = _screenType;
|
||||
const CGFloat HeaderBaselineToCaptionTop = ORKGetMetricForScreenType(ORKScreenMetricCaptionBaselineToTappingLabelTop, screenType);
|
||||
const CGFloat AssumedHeaderBaselineToStepViewTop = ORKGetMetricForScreenType(ORKScreenMetricLearnMoreBaselineToStepViewTop, screenType);
|
||||
CGFloat margin = ORKStandardHorizMarginForView(self);
|
||||
self.layoutMargins = (UIEdgeInsets) { .left=margin*2, .right=margin*2 };
|
||||
|
||||
static const CGFloat TapButtonBottomToBottom = 36;
|
||||
|
||||
|
||||
@@ -159,9 +159,9 @@
|
||||
ORKToneAudiometrySample *sample = [ORKToneAudiometrySample new];
|
||||
NSUInteger frequencyIndex = (self.currentTestIndex / 2);
|
||||
NSNumber *frequency = self.testingFrequencies[frequencyIndex];
|
||||
sample.frequency = frequency;
|
||||
sample.frequency = [frequency doubleValue];
|
||||
sample.channel = ((self.currentTestIndex % 2) == 0) ? ORKAudioChannelLeft : ORKAudioChannelRight;
|
||||
sample.amplitude = @(self.audioGenerator.volumeAmplitude);
|
||||
sample.amplitude = self.audioGenerator.volumeAmplitude;
|
||||
|
||||
[self.samples addObject:sample];
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
|
||||
CGFloat progress = 0.001 + (CGFloat)testIndex / (self.testingFrequencies.count * 2);
|
||||
[self.toneAudiometryContentView setProgress:progress
|
||||
caption:(channel == ORKAudioChannelLeft) ? [NSString stringWithFormat:ORKLocalizedString(@"TONE_LABEL_%@_LEFT", nil), frequency] : [NSString stringWithFormat:ORKLocalizedString(@"TONE_LABEL_%@_RIGHT", nil), frequency]
|
||||
caption:(channel == ORKAudioChannelLeft) ? [NSString stringWithFormat:ORKLocalizedString(@"TONE_LABEL_%@_LEFT", nil), ORKLocalizedStringFromNumber(frequency)] : [NSString stringWithFormat:ORKLocalizedString(@"TONE_LABEL_%@_RIGHT", nil), ORKLocalizedStringFromNumber(frequency)]
|
||||
animated:YES];
|
||||
|
||||
[self.audioGenerator playSoundAtFrequency:frequency.doubleValue
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
@interface ORKTouchRecordingView : UIView
|
||||
|
||||
@property (nonatomic, weak) id<ORKTouchRecordingDelegate> deleagte;
|
||||
@property (nonatomic, weak) id<ORKTouchRecordingDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKTowerOfHanoiStep : ORKActiveStep
|
||||
|
||||
/**
|
||||
The number of disks in the puzzle.
|
||||
It is not recommended that you use a large number of disks. As this provides a poor user experience.
|
||||
The default value of this property is 3.
|
||||
*/
|
||||
@property (nonatomic, assign) NSUInteger numberOfDisks;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTowerOfHanoiStep.h"
|
||||
#import "ORKTowerOfHanoiStepViewController.h"
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
static const NSUInteger kMaximumNumberOfDisks = 8;
|
||||
|
||||
@implementation ORKTowerOfHanoiStep
|
||||
|
||||
+ (Class)stepViewControllerClass {
|
||||
return [ORKTowerOfHanoiViewController class];
|
||||
}
|
||||
|
||||
- (instancetype)initWithIdentifier:(NSString *)identifier {
|
||||
self = [super initWithIdentifier:identifier];
|
||||
if (self) {
|
||||
[self commonInit];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self commonInit];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)commonInit {
|
||||
self.optional = YES;
|
||||
self.numberOfDisks = 3;
|
||||
}
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [super initWithCoder:aDecoder];
|
||||
if (self) {
|
||||
ORK_DECODE_INTEGER(aDecoder, numberOfDisks);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[super encodeWithCoder:aCoder];
|
||||
ORK_ENCODE_INTEGER(aCoder, numberOfDisks);
|
||||
}
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone {
|
||||
ORKTowerOfHanoiStep *step = [super copyWithZone:zone];
|
||||
step.numberOfDisks = self.numberOfDisks;
|
||||
return step;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object {
|
||||
BOOL isParentSame = [super isEqual:object];
|
||||
|
||||
__typeof(self) castObject = object;
|
||||
return (isParentSame &&
|
||||
(self.numberOfDisks == castObject.numberOfDisks));
|
||||
}
|
||||
|
||||
- (void)validateParameters {
|
||||
[super validateParameters];
|
||||
if (self.numberOfDisks > kMaximumNumberOfDisks) {
|
||||
ORK_Log_Oops(@"Having a large number of disks provides a poor user experience, consider reducing the number below %@.", @(kMaximumNumberOfDisks));
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)allowsBackNavigation {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)startsFinished {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)shouldContinueOnFinish {
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <ResearchKit/ResearchKit.h>
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKTowerOfHanoiViewController : ORKActiveStepViewController
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTowerOfHanoiStepViewController.h"
|
||||
#import "ORKActiveStepViewController_Internal.h"
|
||||
#import "ORKTowerOfHanoiTowerView.h"
|
||||
#import "ORKActiveStepView.h"
|
||||
#import "ORKTowerOfHanoiTower.h"
|
||||
#import "ORKTowerOfHanoiStep.h"
|
||||
#import "ORKSkin.h"
|
||||
|
||||
static const NSUInteger kNumberOfTowers = 3;
|
||||
|
||||
@interface ORKTowerOfHanoiViewController () <ORKTowerOfHanoiTowerViewDataSource, ORKTowerOfHanoiTowerViewDelegate>
|
||||
|
||||
@property (nonatomic, strong) NSDateComponentsFormatter *dateComponentsFormatter;
|
||||
@property (nonatomic, strong) NSMutableArray *moves;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ORKTowerOfHanoiViewController {
|
||||
ORKActiveStepCustomView *_towerOfHanoiCustomView;
|
||||
NSNumber *_selectedIndex;
|
||||
NSArray *_currentConstraints;
|
||||
NSMutableArray *_towers;
|
||||
NSArray *_towerViews;
|
||||
NSTimer *_timer;
|
||||
NSInteger _secondsElapsed;
|
||||
NSDate *_firstMoveDate;
|
||||
}
|
||||
|
||||
#pragma mark - UIViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
_towerOfHanoiCustomView = [ORKActiveStepCustomView new];
|
||||
[_towerOfHanoiCustomView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
self.activeStepView.activeCustomView = _towerOfHanoiCustomView;
|
||||
self.activeStepView.minimumStepHeaderHeight = ORKGetMetricForWindow(ORKScreenMetricMinimumStepHeaderHeightForTowerOfHanoiPuzzle, self.view.window);
|
||||
|
||||
[self setupTowers];
|
||||
[self setupTowerViews];
|
||||
[self reloadData];
|
||||
NSString *title = ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_INTRO_TEXT",nil);
|
||||
NSString *text = ORKLocalizedString(@"TOWER_OF_HANOI_TASK_INTRO_TEXT",nil);
|
||||
NSString *skip = ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_SKIP_BUTTON_TITLE", nil);
|
||||
[self.activeStepView updateTitle:title text:text];
|
||||
[self setSkipButtonTitle:skip];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[super viewWillDisappear:animated];
|
||||
[_timer invalidate];
|
||||
}
|
||||
|
||||
- (void)updateViewConstraints {
|
||||
[super updateViewConstraints];
|
||||
if (_currentConstraints) {
|
||||
[NSLayoutConstraint deactivateConstraints:_currentConstraints];
|
||||
_currentConstraints = nil;
|
||||
}
|
||||
BOOL needCompactLayout = self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact &&
|
||||
self.traitCollection.verticalSizeClass != UIUserInterfaceSizeClassCompact;
|
||||
_currentConstraints = needCompactLayout ? [self compactConstraints] : [self regularConstraints];
|
||||
[NSLayoutConstraint activateConstraints:_currentConstraints];
|
||||
}
|
||||
|
||||
#pragma mark - ORKStepViewController
|
||||
|
||||
- (void)skipForward {
|
||||
[self finish];
|
||||
}
|
||||
|
||||
#pragma mark - ORKActiveTaskViewController
|
||||
|
||||
- (ORKResult *)result {
|
||||
ORKStepResult *stepResult = [super result];
|
||||
ORKTowerOfHanoiResult *result = [[ORKTowerOfHanoiResult alloc] initWithIdentifier:self.step.identifier];
|
||||
result.moves = self.moves;
|
||||
result.puzzleWasSolved = [self puzzleIsSolved];
|
||||
if (_firstMoveDate != nil) {
|
||||
result.startDate = _firstMoveDate;
|
||||
}
|
||||
stepResult.results = @[result];
|
||||
return stepResult;
|
||||
}
|
||||
|
||||
#pragma mark - ORKTowerOfHanoiTowerViewDataSource
|
||||
|
||||
- (NSUInteger)numberOfDisksInTowerOfHanoiView:(ORKTowerOfHanoiTowerView *)towerView {
|
||||
NSInteger towerIndex = [_towerViews indexOfObject:towerView];
|
||||
ORKTowerOfHanoiTower *tower = _towers[towerIndex];
|
||||
return tower.disks.count;
|
||||
}
|
||||
|
||||
- (NSNumber *)towerOfHanoiView:(ORKTowerOfHanoiTowerView *)towerView diskAtIndex:(NSUInteger)index {
|
||||
NSInteger towerIndex = [_towerViews indexOfObject:towerView];
|
||||
ORKTowerOfHanoiTower *tower = _towers[towerIndex];
|
||||
return (index >= tower.disks.count) ? nil :tower.disks[index];
|
||||
}
|
||||
|
||||
#pragma mark - ORKTowerOfHanoiTowerViewDelegate
|
||||
|
||||
- (void)towerOfHanoiTowerViewWasSelected:(ORKTowerOfHanoiTowerView *)towerView {
|
||||
NSInteger newSelectedIndex = [_towerViews indexOfObject:towerView];
|
||||
if (_selectedIndex == nil) {
|
||||
_selectedIndex = @(newSelectedIndex);
|
||||
}
|
||||
else if ([_selectedIndex isEqual:@(newSelectedIndex)]) {
|
||||
_selectedIndex = nil;
|
||||
} else {
|
||||
[self transferDiskFromTowerAtIndex:_selectedIndex.integerValue toTowerAtIndex:newSelectedIndex];
|
||||
}
|
||||
[self reloadData];
|
||||
[self evaluatePuzzle];
|
||||
}
|
||||
|
||||
- (ORKTowerOfHanoiTowerView *)towerOfHanoiHighlightedTowerView {
|
||||
return (_selectedIndex != nil ? _towerViews[_selectedIndex.integerValue] : nil);
|
||||
}
|
||||
|
||||
#pragma mark - ORKTowerOfHanoiViewController
|
||||
|
||||
- (NSMutableArray *)moves {
|
||||
if (_moves == nil) {
|
||||
_moves = [NSMutableArray array];
|
||||
}
|
||||
return _moves;
|
||||
}
|
||||
|
||||
- (NSDateComponentsFormatter *)dateComponentsFormatter {
|
||||
if (_dateComponentsFormatter == nil) {
|
||||
_dateComponentsFormatter = [NSDateComponentsFormatter new];
|
||||
_dateComponentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
|
||||
_dateComponentsFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
|
||||
_dateComponentsFormatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
}
|
||||
return _dateComponentsFormatter;
|
||||
}
|
||||
|
||||
- (NSUInteger)numberOfDisks {
|
||||
return ((ORKTowerOfHanoiStep *)self.step).numberOfDisks;
|
||||
}
|
||||
|
||||
- (void)updateTitleText {
|
||||
NSString *moves = ORKLocalizedStringFromNumber(@(self.moves.count));
|
||||
NSString *time = [self.dateComponentsFormatter stringFromTimeInterval:_secondsElapsed];
|
||||
NSString *title = ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_INTRO_TEXT",nil);
|
||||
NSString *text = [NSString stringWithFormat:ORKLocalizedString(@"TOWER_OF_HANOI_TASK_ACTIVE_STEP_PROGRESS_TEXT", nil), moves, time];
|
||||
[self.activeStepView updateTitle:title text:text];
|
||||
}
|
||||
|
||||
- (void)reloadData {
|
||||
for (ORKTowerOfHanoiTowerView *towerView in _towerViews) {
|
||||
towerView.highlighted = _selectedIndex != nil && [_towerViews indexOfObject:towerView] == _selectedIndex.integerValue;
|
||||
[towerView reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)puzzleIsSolved {
|
||||
return ((ORKTowerOfHanoiTower *)_towers.lastObject).disks.count == [self numberOfDisks];
|
||||
}
|
||||
|
||||
- (void)evaluatePuzzle {
|
||||
if ([self puzzleIsSolved]) {
|
||||
[self finish];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupTowers {
|
||||
NSMutableArray *diskStack = [NSMutableArray array];
|
||||
for (NSInteger disk = [self numberOfDisks] ; disk > 0 ; disk--) {
|
||||
[diskStack addObject: @(disk)];
|
||||
}
|
||||
_towers = [@[[[ORKTowerOfHanoiTower alloc] initWithDisks:diskStack], [ORKTowerOfHanoiTower emptyTower], [ORKTowerOfHanoiTower emptyTower]] mutableCopy];
|
||||
}
|
||||
|
||||
- (void)setupTowerViews {
|
||||
NSMutableArray *towerViews = [NSMutableArray array];
|
||||
for (NSInteger index = 0 ; index < 3 ; index++) {
|
||||
ORKTowerOfHanoiTowerView *towerView = [[ORKTowerOfHanoiTowerView alloc] initWithFrame:CGRectZero maximumNumberOfDisks:[self numberOfDisks]];
|
||||
towerView.delegate = self;
|
||||
towerView.dataSource = self;
|
||||
towerView.targeted = (index == kNumberOfTowers - 1);
|
||||
[towerViews addObject:towerView];
|
||||
[towerView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[_towerOfHanoiCustomView addSubview:towerView];
|
||||
}
|
||||
_towerViews = towerViews;
|
||||
}
|
||||
|
||||
- (void)transferDiskFromTowerAtIndex:(NSInteger)donorTowerIndex toTowerAtIndex:(NSInteger)recipientTowerIndex {
|
||||
ORKTowerOfHanoiTower *donorTower = _towers[donorTowerIndex];
|
||||
ORKTowerOfHanoiTower *recipientTower = _towers[recipientTowerIndex];
|
||||
if ([recipientTower recieveDiskFrom:donorTower]) {
|
||||
[self makeMoveFromTowerAtIndex:donorTowerIndex toTowerAtIndex:recipientTowerIndex];
|
||||
}
|
||||
else {
|
||||
NSNumber *donorSize = [self towerOfHanoiView:_towerViews[donorTowerIndex] diskAtIndex:0];
|
||||
NSNumber *recipientSize = [self towerOfHanoiView:_towerViews[recipientTowerIndex] diskAtIndex:0];
|
||||
|
||||
if (donorSize && recipientSize) {
|
||||
// Only announce if the both donor and recipient are valid
|
||||
NSString *invalidMoveAnnouncement = [NSString stringWithFormat:ORKLocalizedString(@"AX_TOWER_OF_HANOI_INVALID_MOVE_FORMAT", nil), donorSize.stringValue, recipientSize.stringValue];
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, invalidMoveAnnouncement);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)makeMoveFromTowerAtIndex:(NSUInteger)donorTowerIndex toTowerAtIndex:(NSUInteger)recipientTowerIndex {
|
||||
ORKTowerOfHanoiMove *move = [[ORKTowerOfHanoiMove alloc] init];
|
||||
move.donorTowerIndex = donorTowerIndex;
|
||||
move.recipientTowerIndex = recipientTowerIndex;
|
||||
move.timestamp = (self.moves.count == 0) ? 0 : fabs([_firstMoveDate timeIntervalSinceNow]);
|
||||
[_moves addObject:move];
|
||||
[self didMakeMove];
|
||||
}
|
||||
|
||||
- (void)didMakeMove {
|
||||
_selectedIndex = nil;
|
||||
if (self.moves.count == 1) {
|
||||
_firstMoveDate = [NSDate date];
|
||||
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerTicked) userInfo:nil repeats:YES];
|
||||
}
|
||||
[self updateTitleText];
|
||||
}
|
||||
|
||||
- (void)timerTicked {
|
||||
_secondsElapsed++;
|
||||
[self updateTitleText];
|
||||
}
|
||||
|
||||
- (NSArray *)compactConstraints {
|
||||
CGFloat compactWidth = ([[UIScreen mainScreen]bounds].size.height - (3 * 8)) / 3;
|
||||
NSDictionary *views = @{ @"A" : _towerViews[0], @"B" : _towerViews[1], @"C" : _towerViews[2]};
|
||||
NSMutableArray *newConstraints = [NSMutableArray new];
|
||||
|
||||
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:|-[A]-[B]-[C]-|"] options:0 metrics:nil views:views]];
|
||||
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:_towerViews[0] attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_towerViews[1] attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];
|
||||
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:_towerViews[2] attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_towerViews[1] attribute:NSLayoutAttributeHeight multiplier:1 constant:0]];
|
||||
|
||||
for (int index = 0 ; index < _towerViews.count ; index++) {
|
||||
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:_towerViews[index] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:compactWidth]];
|
||||
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:_towerViews[index] attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_towerOfHanoiCustomView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
|
||||
}
|
||||
|
||||
return newConstraints;
|
||||
}
|
||||
|
||||
- (NSArray *)regularConstraints {
|
||||
NSDictionary *views = @{ @"A" : _towerViews[0], @"B" : _towerViews[1], @"C" : _towerViews[2]};
|
||||
NSMutableArray *newConstraints = [NSMutableArray new];
|
||||
|
||||
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[A]-|" options:0 metrics:nil views:views]];
|
||||
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[B]-|" options:0 metrics:nil views:views]];
|
||||
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[C]-|" options:0 metrics:nil views:views]];
|
||||
[newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[A]-[B]-[C]-|" options:0 metrics:nil views:views]];
|
||||
|
||||
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:_towerViews[0] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_towerViews[1] attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
|
||||
[newConstraints addObject:[NSLayoutConstraint constraintWithItem:_towerViews[2] attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_towerViews[1] attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
|
||||
|
||||
return newConstraints;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface ORKTowerOfHanoiTower : NSObject
|
||||
|
||||
@property(nonatomic, copy, readonly) NSArray *disks;
|
||||
|
||||
+ (instancetype)emptyTower;
|
||||
|
||||
- (instancetype)initWithDisks:(NSArray *)disks;
|
||||
|
||||
- (BOOL)recieveDiskFrom:(ORKTowerOfHanoiTower *)donorTower;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTowerOfHanoiTower.h"
|
||||
|
||||
@interface ORKTowerOfHanoiTower ()
|
||||
|
||||
@property(nonatomic, copy, readwrite) NSArray *disks;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ORKTowerOfHanoiTower
|
||||
|
||||
+ (instancetype)emptyTower {
|
||||
return [[ORKTowerOfHanoiTower alloc]initWithDisks:@[]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithDisks:(NSArray *)disks {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_disks = disks;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)canRecieveDisk:(NSNumber *)disk {
|
||||
return _disks.count == 0 || [_disks.lastObject integerValue] > disk.integerValue;
|
||||
}
|
||||
|
||||
- (BOOL)recieveDiskFrom:(ORKTowerOfHanoiTower*)donorTower {
|
||||
if (donorTower.disks.count == 0 || ![self canRecieveDisk:donorTower.disks.lastObject]) {
|
||||
return NO;
|
||||
}
|
||||
NSMutableArray *recipientDisks = [self.disks mutableCopy];
|
||||
NSMutableArray *donorDisks = [donorTower.disks mutableCopy];
|
||||
[recipientDisks addObject:donorTower.disks.lastObject];
|
||||
[donorDisks removeLastObject];
|
||||
self.disks = recipientDisks;
|
||||
donorTower.disks = donorDisks;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class ORKTowerOfHanoiTowerView;
|
||||
|
||||
@protocol ORKTowerOfHanoiTowerViewDataSource <NSObject>
|
||||
|
||||
@required
|
||||
- (NSUInteger)numberOfDisksInTowerOfHanoiView:(ORKTowerOfHanoiTowerView *)towerView;
|
||||
- (NSNumber *)towerOfHanoiView:(ORKTowerOfHanoiTowerView *)towerView diskAtIndex:(NSUInteger)index;
|
||||
|
||||
@end
|
||||
|
||||
@protocol ORKTowerOfHanoiTowerViewDelegate <NSObject>
|
||||
|
||||
@required
|
||||
- (void)towerOfHanoiTowerViewWasSelected:(ORKTowerOfHanoiTowerView *)towerView;
|
||||
- (ORKTowerOfHanoiTowerView *)towerOfHanoiHighlightedTowerView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ORKTowerOfHanoiTowerView : UIView
|
||||
|
||||
@property (nonatomic, getter=isHighLighted) BOOL highlighted;
|
||||
@property (nonatomic, getter=isTargeted) BOOL targeted;
|
||||
@property (nonatomic, weak) id <ORKTowerOfHanoiTowerViewDataSource> dataSource;
|
||||
@property (nonatomic, weak) id <ORKTowerOfHanoiTowerViewDelegate> delegate;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame maximumNumberOfDisks:(NSUInteger)maximumNumberOfDisks;
|
||||
|
||||
- (void)reloadData;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKTowerOfHanoiTowerView.h"
|
||||
#import "ORKActiveStepView.h"
|
||||
#import "ORKSkin.h"
|
||||
#import "ORKAccessibility.h"
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
|
||||
static const CGFloat DiskHeight = 10;
|
||||
static const CGFloat DiskSpacing = 8;
|
||||
static const CGFloat BaseSpacing = 10;
|
||||
|
||||
@implementation ORKTowerOfHanoiTowerView {
|
||||
NSInteger _maximumNumberOfDisks;
|
||||
UIView *_base;
|
||||
NSMutableArray *_diskViews;
|
||||
NSMutableArray *_diskSizes;
|
||||
NSMutableArray *_variableConstraints;
|
||||
}
|
||||
|
||||
#pragma mark - Init
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame maximumNumberOfDisks:(NSUInteger)maximumNumberOfDisks {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
_maximumNumberOfDisks = maximumNumberOfDisks;
|
||||
_base = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
_base.backgroundColor = [UIColor ork_midGrayTintColor];
|
||||
[_base setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
_base.layer.cornerRadius = 2.5;
|
||||
_base.layer.masksToBounds = YES;
|
||||
_diskViews = [NSMutableArray new];
|
||||
_diskSizes = [NSMutableArray new];
|
||||
[self addSubview:_base];
|
||||
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userDidTapTower)]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - UIView
|
||||
|
||||
- (void)updateConstraints {
|
||||
[NSLayoutConstraint deactivateConstraints:_variableConstraints];
|
||||
[_variableConstraints removeAllObjects];
|
||||
|
||||
if (!_variableConstraints) {
|
||||
_variableConstraints = [NSMutableArray new];
|
||||
}
|
||||
|
||||
CGFloat height = (DiskHeight * _maximumNumberOfDisks) + (DiskSpacing * _maximumNumberOfDisks);
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:self
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationGreaterThanOrEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1.0
|
||||
constant:height + BaseSpacing]];
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:_base
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self
|
||||
attribute:NSLayoutAttributeWidth
|
||||
multiplier:1.0
|
||||
constant:0.0]];
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:_base
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1.0
|
||||
constant:2]];
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:_base
|
||||
attribute:NSLayoutAttributeCenterX
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self
|
||||
attribute:NSLayoutAttributeCenterX
|
||||
multiplier:1.0
|
||||
constant:0.0]];
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:_base
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self
|
||||
attribute:NSLayoutAttributeCenterY
|
||||
multiplier:1.0
|
||||
constant:(height * 0.5) + BaseSpacing]];
|
||||
|
||||
UIView *topDisk;
|
||||
for (NSInteger index = 0 ; index < _diskSizes.count ; index++) {
|
||||
UIView *disk = _diskViews[index];
|
||||
CGFloat divide = 1.0 / _maximumNumberOfDisks;
|
||||
CGFloat multiply = [(NSNumber *)_diskSizes[index] floatValue] * divide;
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:disk
|
||||
attribute:NSLayoutAttributeCenterX
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self
|
||||
attribute:NSLayoutAttributeCenterX
|
||||
multiplier:1.0
|
||||
constant:0.0]];
|
||||
|
||||
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:disk
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:_base
|
||||
attribute:NSLayoutAttributeWidth
|
||||
multiplier:multiply
|
||||
constant:0.0]];
|
||||
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:disk
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1.0
|
||||
constant:DiskHeight]];
|
||||
|
||||
if (index == 0) {
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:disk
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self
|
||||
attribute:NSLayoutAttributeCenterY
|
||||
multiplier:1.0
|
||||
constant:height * 0.5]];
|
||||
} else {
|
||||
[_variableConstraints addObject:[NSLayoutConstraint constraintWithItem:disk
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:topDisk
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0
|
||||
constant:-DiskSpacing]];
|
||||
}
|
||||
topDisk = disk;
|
||||
}
|
||||
[NSLayoutConstraint activateConstraints:_variableConstraints];
|
||||
[super updateConstraints];
|
||||
}
|
||||
|
||||
- (void)tintColorDidChange {
|
||||
[self reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)reloadData {
|
||||
[self updateDisks];
|
||||
[self highlightIfNeeded];
|
||||
[self indicateTargetIfNeeded];
|
||||
[self setNeedsUpdateConstraints];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)userDidTapTower {
|
||||
[self.delegate towerOfHanoiTowerViewWasSelected:self];
|
||||
}
|
||||
|
||||
- (void)updateDisks {
|
||||
[_diskViews makeObjectsPerformSelector:@selector(removeFromSuperview)];
|
||||
ORKRemoveConstraintsForRemovedViews(_variableConstraints, _diskViews);
|
||||
|
||||
[_diskViews removeAllObjects];
|
||||
[_diskSizes removeAllObjects];
|
||||
|
||||
NSInteger numberOfDisks = [self.dataSource numberOfDisksInTowerOfHanoiView:self];
|
||||
for (NSInteger index = 0 ; index < numberOfDisks ; index++) {
|
||||
NSNumber *diskSize = [self.dataSource towerOfHanoiView:self diskAtIndex:index];
|
||||
[_diskSizes addObject:diskSize];
|
||||
UIView *diskView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
diskView.backgroundColor = [self tintColor];
|
||||
diskView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
diskView.layer.cornerRadius = DiskHeight * 0.5;
|
||||
diskView.clipsToBounds = YES;
|
||||
[self addSubview:diskView];
|
||||
[_diskViews addObject:diskView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)highlightIfNeeded {
|
||||
if (self.isHighLighted) {
|
||||
((UIView *)_diskViews.lastObject).alpha = 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)indicateTargetIfNeeded {
|
||||
if (self.isTargeted) {
|
||||
_base.backgroundColor = [self tintColor];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Accessibility
|
||||
|
||||
- (BOOL)isAccessibilityElement {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel {
|
||||
NSString *targetDisk = (self.isTargeted ? ORKLocalizedString(@"AX_TOWER_OF_HANOI_TARGET_DISK", nil) : nil);
|
||||
return ORKAccessibilityStringForVariables(ORKLocalizedString(@"AX_TOWER_OF_HANOI_TOWER", nil), targetDisk);
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityHint {
|
||||
if (!self.isHighLighted && [self.delegate towerOfHanoiHighlightedTowerView] != nil) {
|
||||
return ORKLocalizedString(@"AX_TOWER_OF_HANOI_PLACE_DISK", nil);
|
||||
}
|
||||
|
||||
BOOL hasDisks = ([self.dataSource numberOfDisksInTowerOfHanoiView:self] > 0);
|
||||
return (self.isHighLighted ? nil : (hasDisks ? ORKLocalizedString(@"AX_TOWER_OF_HANOI_SELECT_DISK", nil) : nil));
|
||||
}
|
||||
|
||||
- (UIAccessibilityTraits)accessibilityTraits {
|
||||
UIAccessibilityTraits traits = [super accessibilityTraits];
|
||||
if (self.isHighLighted) {
|
||||
traits |= UIAccessibilityTraitSelected;
|
||||
}
|
||||
|
||||
// Don't echo if when a disk is placed.
|
||||
if (!self.isHighLighted && UIAccessibilityFocusedElement(UIAccessibilityNotificationVoiceOverIdentifier) == self) {
|
||||
traits |= UIAccessibilityTraitStartsMediaSession;
|
||||
}
|
||||
|
||||
return traits;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityValue {
|
||||
|
||||
NSString *disksString = @"";
|
||||
|
||||
for (NSNumber *diskSize in _diskSizes) {
|
||||
disksString = ORKAccessibilityStringForVariables(disksString, diskSize.stringValue, @", ");
|
||||
}
|
||||
|
||||
NSString *value = (_diskSizes.count > 0 ? [NSString stringWithFormat:ORKLocalizedString(@"AX_TOWER_OF_HANOI_TOWER_CONTAINS", nil), disksString] : ORKLocalizedString(@"AX_TOWER_OF_HANOI_TOWER_EMPTY", nil));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -41,147 +41,7 @@
|
||||
#import "ORKWalkingTaskStep.h"
|
||||
#import "ORKPedometerRecorder.h"
|
||||
#import "ORKActiveStepView.h"
|
||||
|
||||
|
||||
static const CGFloat kProgressCircleDiameter = 10;
|
||||
static const CGFloat kProgressCircleSpacing = 4;
|
||||
|
||||
@interface ORKWalkingProgressCircleView : UIView
|
||||
|
||||
@property (nonatomic, assign) BOOL completed;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKWalkingProgressCircleView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setCompleted:NO];
|
||||
self.backgroundColor = [self tintColor];
|
||||
self.layer.cornerRadius = kProgressCircleDiameter/2;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)tintColorDidChange {
|
||||
[super tintColorDidChange];
|
||||
self.backgroundColor = [self tintColor];
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize {
|
||||
return (CGSize){kProgressCircleDiameter,kProgressCircleDiameter};
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size {
|
||||
return (CGSize){kProgressCircleDiameter,kProgressCircleDiameter};
|
||||
}
|
||||
|
||||
- (void)setCompleted:(BOOL)completed {
|
||||
_completed = completed;
|
||||
self.alpha = (completed ? 1.0 : 0.6);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface ORKWalkingProgressView : UIView
|
||||
|
||||
@property (nonatomic, assign) NSInteger count;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ORKWalkingProgressView {
|
||||
NSArray *_circles;
|
||||
NSInteger _index;
|
||||
NSTimer *_timer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
self.count = 3;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
}
|
||||
|
||||
- (void)setCount:(NSInteger)count {
|
||||
_count = count;
|
||||
if (count != [_circles count]) {
|
||||
for (UIView *v in _circles) {
|
||||
[v removeFromSuperview];
|
||||
}
|
||||
NSMutableArray *newCircles = [NSMutableArray array];
|
||||
for (NSInteger idx = 0; idx < count; idx ++) {
|
||||
ORKWalkingProgressCircleView *circle = [ORKWalkingProgressCircleView new];
|
||||
[newCircles addObject:circle];
|
||||
[self addSubview:circle];
|
||||
}
|
||||
|
||||
_circles = newCircles;
|
||||
[self invalidateIntrinsicContentSize];
|
||||
[self setNeedsLayout];
|
||||
self.index = _index;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setIndex:(NSInteger)index {
|
||||
_index = index;
|
||||
[_circles enumerateObjectsUsingBlock:^(ORKWalkingProgressCircleView *circle, NSUInteger idx, BOOL *stop) {
|
||||
circle.completed = (idx < _index);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow {
|
||||
if (self.window) {
|
||||
[self startAnimating];
|
||||
} else {
|
||||
[self stopAnimating];
|
||||
}
|
||||
}
|
||||
- (void)stopAnimating {
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
}
|
||||
|
||||
- (void)incrementIndex {
|
||||
self.index = (_index + 1) % (_count + 1);
|
||||
}
|
||||
|
||||
- (void)startAnimating {
|
||||
[self stopAnimating];
|
||||
self.index = 0;
|
||||
_timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(incrementIndex) userInfo:nil repeats:YES];
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size {
|
||||
size.height = kProgressCircleDiameter;
|
||||
size.width = (_count * kProgressCircleDiameter) + MAX(_count-1,0) * kProgressCircleSpacing;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize {
|
||||
return [self sizeThatFits:CGSizeZero];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
CGSize sz = (CGSize){kProgressCircleDiameter,kProgressCircleDiameter};
|
||||
CGFloat xStep = kProgressCircleDiameter + kProgressCircleSpacing;
|
||||
CGFloat x0 = 0;
|
||||
for (UIView *v in _circles) {
|
||||
v.frame = (CGRect){{x0,0},sz};
|
||||
x0 += xStep;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
#import "ORKProgressView.h"
|
||||
|
||||
|
||||
@interface ORKWalkingContentView : ORKActiveStepCustomView {
|
||||
@@ -189,7 +49,7 @@ static const CGFloat kProgressCircleSpacing = 4;
|
||||
NSLayoutConstraint *_topConstraint;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong, readonly) ORKWalkingProgressView *progressView;
|
||||
@property (nonatomic, strong, readonly) ORKProgressView *progressView;
|
||||
|
||||
@end
|
||||
|
||||
@@ -198,14 +58,14 @@ static const CGFloat kProgressCircleSpacing = 4;
|
||||
|
||||
- (void)willMoveToWindow:(UIWindow *)newWindow {
|
||||
[super willMoveToWindow:newWindow];
|
||||
_screenType = ORKGetScreenTypeForWindow(newWindow);
|
||||
_screenType = ORKGetVerticalScreenTypeForWindow(newWindow);
|
||||
[self updateConstraintConstants];
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
_progressView = [ORKWalkingProgressView new];
|
||||
_progressView = [ORKProgressView new];
|
||||
_progressView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
_screenType = ORKScreenTypeiPhone4;
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"filename" : "phone-tower-of-hanoi@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"filename" : "phone-tower-of-hanoi@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"filename" : "phone-tower-of-hanoi@2x~ipad.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"filename" : "phonepsat@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"filename" : "phonepsat@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"filename" : "phonepsat@2x~ipad.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"filename" : "timed-walkingman-outbound@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"filename" : "timed-walkingman-outbound@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"filename" : "timed-walkingman-outbound@2x~ipad.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"filename" : "timed-walkingman-return@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"filename" : "timed-walkingman-return@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"filename" : "timed-walkingman-return@2x~ipad.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"filename" : "timer@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"filename" : "timer@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"filename" : "timer@2x~ipad.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"filename" : "tower-of-hanoi-second-screen@2x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"filename" : "tower-of-hanoi-second-screen@3x.png"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"filename" : "tower-of-hanoi-second-screen@2x~ipad.png"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "UIButtonBarArrowRight.pdf"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "UIButtonBarArrowRightLandscape.pdf"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ORKCenteredCollectionViewLayout : UICollectionViewFlowLayout
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import "ORKCenteredCollectionViewLayout.h"
|
||||
|
||||
@implementation ORKCenteredCollectionViewLayout
|
||||
|
||||
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
|
||||
NSArray<UICollectionViewLayoutAttributes *> *attributesArray = [super layoutAttributesForElementsInRect:rect];
|
||||
for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
|
||||
attributes.frame = [self layoutAttributesForItemAtIndexPath:attributes.indexPath].frame;
|
||||
}
|
||||
return attributesArray;
|
||||
}
|
||||
|
||||
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
|
||||
NSInteger count = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:indexPath.section];
|
||||
NSIndexPath *lastItemIndexPath = [NSIndexPath indexPathForItem:count - 1 inSection:indexPath.section];
|
||||
UICollectionViewLayoutAttributes *lastItemAttributes = [super layoutAttributesForItemAtIndexPath:lastItemIndexPath];
|
||||
if (attributes.frame.origin.y == lastItemAttributes.frame.origin.y) {
|
||||
CGFloat trailing = self.collectionView.bounds.size.width - lastItemAttributes.frame.origin.x - attributes.frame.size.width;
|
||||
attributes.frame = CGRectOffset(attributes.frame, trailing * 0.5, 0);
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ORKGraphChartView.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
The `ORKDiscreteGraphChartView` class presents data provided by an object conforming to the
|
||||
`ORKGraphChartViewDataSource` protocol as a discrete graph of ranged points. You can optionally
|
||||
display a line connecting each ranged points pair.
|
||||
*/
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKDiscreteGraphChartView : ORKGraphChartView
|
||||
|
||||
/**
|
||||
A Boolean value indicating whether to draw a line connecting the minimum value and maximum value of
|
||||
each ranged point represented by the graph view.
|
||||
|
||||
The default value for this property is `YES`.
|
||||
*/
|
||||
@property (nonatomic) BOOL drawsConnectedRanges;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKDiscreteGraphChartView.h"
|
||||
#import "ORKGraphChartView_Internal.h"
|
||||
#import "ORKHelpers.h"
|
||||
#import "ORKRangedPoint.h"
|
||||
|
||||
|
||||
@implementation ORKDiscreteGraphChartView
|
||||
|
||||
#pragma mark - Init
|
||||
|
||||
- (void)sharedInit {
|
||||
[super sharedInit];
|
||||
_drawsConnectedRanges = YES;
|
||||
}
|
||||
|
||||
- (void)setDrawsConnectedRanges:(BOOL)drawsConnectedRanges {
|
||||
_drawsConnectedRanges = drawsConnectedRanges;
|
||||
[super updateLineLayers];
|
||||
[super updatePointLayers];
|
||||
[super layoutLineLayers];
|
||||
[super layoutPointLayers];
|
||||
}
|
||||
|
||||
#pragma mark - Draw
|
||||
|
||||
- (BOOL)shouldDrawLinesForPlotIndex:(NSInteger)plotIndex {
|
||||
return [self numberOfValidValuesForPlotIndex:plotIndex] > 0 && _drawsConnectedRanges;
|
||||
}
|
||||
|
||||
- (void)updateLineLayersForPlotIndex:(NSInteger)plotIndex {
|
||||
NSUInteger pointCount = self.dataPoints[plotIndex].count;
|
||||
for (NSUInteger pointIndex = 0; pointIndex < pointCount; pointIndex++) {
|
||||
ORKRangedPoint *dataPointValue = self.dataPoints[plotIndex][pointIndex];
|
||||
if (!dataPointValue.isUnset && !dataPointValue.hasEmptyRange) {
|
||||
CAShapeLayer *lineLayer = graphLineLayer();
|
||||
lineLayer.strokeColor = [self colorForplotIndex:plotIndex].CGColor;
|
||||
lineLayer.lineWidth = ORKGraphChartViewPointAndLineSize;
|
||||
|
||||
[self.plotView.layer addSublayer:lineLayer];
|
||||
[self.lineLayers[plotIndex] addObject:lineLayer];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutLineLayersForPlotIndex:(NSInteger)plotIndex {
|
||||
NSUInteger lineLayerIndex = 0;
|
||||
CGFloat positionOnXAxis = ORKCGFloatInvalidValue;
|
||||
ORKRangedPoint *positionOnYAxis = nil;
|
||||
NSUInteger pointCount = self.yAxisPoints[plotIndex].count;
|
||||
for (NSUInteger pointIndex = 0; pointIndex < pointCount; pointIndex++) {
|
||||
|
||||
ORKRangedPoint *dataPointValue = self.dataPoints[plotIndex][pointIndex];
|
||||
|
||||
if (!dataPointValue.isUnset && !dataPointValue.hasEmptyRange) {
|
||||
|
||||
UIBezierPath *linePath = [UIBezierPath bezierPath];
|
||||
|
||||
positionOnXAxis = xAxisPoint(pointIndex, self.numberOfXAxisPoints, self.plotView.bounds.size.width);
|
||||
positionOnXAxis += [self offsetForPlotIndex:plotIndex];
|
||||
positionOnYAxis = self.yAxisPoints[plotIndex][pointIndex];
|
||||
|
||||
[linePath moveToPoint:CGPointMake(positionOnXAxis, positionOnYAxis.minimumValue)];
|
||||
[linePath addLineToPoint:CGPointMake(positionOnXAxis, positionOnYAxis.maximumValue)];
|
||||
|
||||
CAShapeLayer *lineLayer = self.lineLayers[plotIndex][lineLayerIndex];
|
||||
lineLayer.path = linePath.CGPath;
|
||||
lineLayerIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)offsetForPlotIndex:(NSInteger)plotIndex {
|
||||
CGFloat pointWidth = ORKGraphChartViewPointAndLineSize;
|
||||
|
||||
NSInteger numberOfPlots = [self numberOfPlots];
|
||||
|
||||
CGFloat offset = 0;
|
||||
|
||||
if (numberOfPlots % 2 == 0) {
|
||||
// Even
|
||||
offset = (plotIndex - numberOfPlots / 2 + 0.5) * pointWidth;
|
||||
} else {
|
||||
// Odd
|
||||
offset = (plotIndex - numberOfPlots / 2) * pointWidth;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
#pragma mark - Graph Calculations
|
||||
|
||||
- (CGFloat)canvasYPointForXPosition:(CGFloat)xPosition plotIndex:(NSInteger)plotIndex {
|
||||
BOOL snapped = [self isXPositionSnapped:xPosition];
|
||||
CGFloat canvasYPosition = 0;
|
||||
if (snapped) {
|
||||
NSInteger pointIndex = [self pointIndexForXPosition:xPosition];
|
||||
canvasYPosition = self.yAxisPoints[plotIndex][pointIndex-1].maximumValue;
|
||||
}
|
||||
return canvasYPosition;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ORKDefines.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ORKGraphChartView;
|
||||
@class ORKRangedPoint;
|
||||
|
||||
/**
|
||||
The graph chart view delegate protocol declares methods which forward pan gesture events occuring
|
||||
within the bounds of an `ORKGraphChartView` object.
|
||||
*/
|
||||
ORK_AVAILABLE_DECL
|
||||
@protocol ORKGraphChartViewDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
/**
|
||||
Notifies the delegate that a pan gesture has begun within the bounds of an `ORKGraphChartView`
|
||||
object.
|
||||
|
||||
@param graphChartView The graph chart view in which the gesture occurred.
|
||||
*/
|
||||
- (void)graphChartViewTouchesBegan:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
/**
|
||||
Notifies the delegate of updates in the x-coordinate of an ongoing pan gesture within the bounds
|
||||
of an `ORKGraphChartView` object.
|
||||
|
||||
@param graphChartView The graph chart view object in which the gesture occurred.
|
||||
@param xPosition The updated x-coordinate of the ongoing pan gesture.
|
||||
*/
|
||||
- (void)graphChartView:(ORKGraphChartView *)graphChartView touchesMovedToXPosition:(CGFloat)xPosition;
|
||||
|
||||
/**
|
||||
Notifies the delegate that a pan gesture which began within the bounds of an `ORKGraphChartView`
|
||||
object has ended.
|
||||
|
||||
@param graphChartView The graph chart view object in which the gesture occurred.
|
||||
*/
|
||||
- (void)graphChartViewTouchesEnded:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
An object that adopts the `ORKGraphChartViewDataSource` protocol is responsible for providing the
|
||||
data required to populate an `ORKGraphChartView` object.
|
||||
|
||||
At a minimum, a data source object must implement the `graphChartView:numberOfPointsInPlot:` and
|
||||
`graphChartView:plot:valueForPointAtIndex:` methods. These methods are responsible for returning
|
||||
the number of points in a plot and the points themselves. Each point in a plot is represented by an
|
||||
object of the `ORKRangedPoint` class. A data source object may provide additional information to
|
||||
the graph chart view by implementing the optional methods.
|
||||
|
||||
When configuring an `ORKGraphChartView` object, assign your data source to its `dataSource`
|
||||
property.
|
||||
*/
|
||||
ORK_AVAILABLE_DECL
|
||||
@protocol ORKGraphChartViewDataSource <NSObject>
|
||||
|
||||
@required
|
||||
/**
|
||||
Asks the data source for the number of range points to be plotted by the graph chart view at the
|
||||
specified plot index.
|
||||
|
||||
@param graphChartView The graph chart view asking for the number of range points.
|
||||
@param plotIndex An index number identifying the plot in the graph chart view. This index
|
||||
is 0 in a single-plot graph chart view.
|
||||
|
||||
@return The number of range points in the plot at `plotIndex`.
|
||||
*/
|
||||
- (NSInteger)graphChartView:(ORKGraphChartView *)graphChartView numberOfPointsForPlotIndex:(NSInteger)plotIndex;
|
||||
|
||||
|
||||
/**
|
||||
Asks the data source for the range point to be plotted at the specified point index for the
|
||||
specified plot.
|
||||
|
||||
@param graphChartView The graphChartView asking for the range point.
|
||||
@param pointIndex An index number identifying the range point in the graph chart view.
|
||||
@param plotIndex An index number identifying the plot in the graph chart view. This index
|
||||
is 0 in a single-plot graph chart view.
|
||||
|
||||
@return The range point specified by `pointIndex` in the plot specified by `plotIndex` for the
|
||||
specified graph chart view`.
|
||||
*/
|
||||
- (ORKRangedPoint *)graphChartView:(ORKGraphChartView *)graphChartView pointForPointIndex:(NSInteger)pointIndex plotIndex:(NSInteger)plotIndex;
|
||||
|
||||
@optional
|
||||
/**
|
||||
Asks the data source for the number of plots to be plotted by the graph chart view. If this method
|
||||
is not implemented, the graph chart view will assume it has a single plot.
|
||||
|
||||
@param graphChartView The graph chart view asking for the number of plots.
|
||||
|
||||
@return The number of plots in the graph chart view.
|
||||
*/
|
||||
- (NSInteger)numberOfPlotsInGraphChartView:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
/**
|
||||
Asks the data source for the color of the specified plot.
|
||||
|
||||
If this method is not implemented, the first plot will use the graph chart view `tintColor`, and
|
||||
all subsequent plots will use the current `referenceLineColor`.
|
||||
|
||||
@param graphChartView The graph chart view asking for the color of the segment.
|
||||
@param plotIndex An index number identifying the plot in the graph chart view. This index
|
||||
is always 0 in single-plot graph chart views.
|
||||
|
||||
@return The color of the segment at the specified `index` in `pieChartView`.
|
||||
*/
|
||||
- (UIColor *)graphChartView:(ORKGraphChartView *)graphChartView colorForPlotIndex:(NSInteger)plotIndex;
|
||||
|
||||
/**
|
||||
Asks the data source which plot should the scrubber snap to in multi-graph chart views.
|
||||
|
||||
If this method is not implemented, the scrubber snaps over the first plot.
|
||||
|
||||
@param graphChartView The graph chart view asking for the scrubbing plot index.
|
||||
|
||||
@return The index of the plot the scrubber should snap to.
|
||||
*/
|
||||
- (NSInteger)scrubbingPlotIndexForGraphChartView:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
/**
|
||||
Asks the data source for the upper limit of the y-axis drawn by the graph chart view.
|
||||
|
||||
If this method is not implemented, the greatest `maximumValue` of all `ORKRangedPoint` instances
|
||||
returned in `graphChartView:plot:valueForPointAtIndex:` will be used.
|
||||
|
||||
See also: `graphChartView:plot:valueForPointAtIndex:`.
|
||||
|
||||
@param graphChartView The graph chart view asking for the maximum value.
|
||||
|
||||
@return The maximum value of the y-axis drawn by `graphChartView`.
|
||||
*/
|
||||
- (CGFloat)maximumValueForGraphChartView:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
/**
|
||||
Asks the data source for the lower limit of the y-axis drawn by the graph chart view.
|
||||
|
||||
If this method is not implemented, The smallest `minimumValue` of all ORKRangedPoint instances
|
||||
returned in `graphChartView:plot:valueForPointAtIndex:` will be used.
|
||||
|
||||
See also: `graphChartView:plot:valueForPointAtIndex:`.
|
||||
|
||||
@param graphChartView The graph chart view asking for the minimum value.
|
||||
|
||||
@return The minimum value of the y-axis drawn by `graphChartView`.
|
||||
*/
|
||||
- (CGFloat)minimumValueForGraphChartView:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
/**
|
||||
Asks the data source for the number of divisions in the x-axis. The value is ignored if it is lower
|
||||
than the number of data points. A title appearing adjacent to each
|
||||
division may optionally be returned in `graphChartView:titleForXAxisAtPointIndex:`.
|
||||
|
||||
@param graphChartView The graph chart view asking for the number of divisions in its x-axis.
|
||||
|
||||
@return The number of divisions in the x-axis for `graphChartView`.
|
||||
*/
|
||||
- (NSInteger)numberOfDivisionsInXAxisForGraphChartView:(ORKGraphChartView *)graphChartView;
|
||||
|
||||
/**
|
||||
Asks the data source for the title to be displayed adjacent to each division in the x-axis (the
|
||||
number returned by `numberOfDivisionsInXAxisForGraphChartView:`).
|
||||
|
||||
If this method is not implemented, the x-axis will not have titles.
|
||||
|
||||
See also: `numberOfDivisionsInXAxisForGraphChartView:`.
|
||||
|
||||
@param graphChartView The graph chart view asking for the tile.
|
||||
@param pointIndex The index of the specified x-axis division.
|
||||
|
||||
@return The title string to be displayed adjacent to each division of the x-axis of the graph chart
|
||||
view.
|
||||
*/
|
||||
- (NSString *)graphChartView:(ORKGraphChartView *)graphChartView titleForXAxisAtPointIndex:(NSInteger)pointIndex;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
The `ORKGraphChartView` class is an abstract class. It holds properties and methods common to
|
||||
subclasses like `ORKLineGraphChartView` and `ORKDiscreteGraphChartView`. You should not instantiate
|
||||
this class directly, use one of the subclasses instead.
|
||||
*/
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKGraphChartView : UIView
|
||||
|
||||
/**
|
||||
The minimum value of the y-axis.
|
||||
|
||||
This value can be provided to an instance of `ORKGraphChartView` by implementing the optional
|
||||
`minimumValueForGraphChartView:` method of the `ORKGraphChartViewDataSource` protocol.
|
||||
|
||||
If `minimumValueForGraphChartView:` is not implemented, the minimum value will be assigned to the
|
||||
smallest value of the `minimumValue` property of all `ORKRangedPoint` instances returned by the
|
||||
graph chart view data source.
|
||||
*/
|
||||
@property (nonatomic, readonly) CGFloat minimumValue;
|
||||
|
||||
/**
|
||||
The maximum value of the y-axis.
|
||||
|
||||
This value can be provided to an instance of `ORKGraphChartView` by implementing the
|
||||
optional `maximumValueForGraphChartView:` method of the `ORKGraphChartViewDataSource` protocol.
|
||||
|
||||
If `maximumValueForGraphChartView:` is not implemented, the maximum value will be assigned to the
|
||||
largest value of the `maximumValue` property of all `ORKRangedPoint` instances returned by the
|
||||
graph chart view data source.
|
||||
*/
|
||||
@property (nonatomic, readonly) CGFloat maximumValue;
|
||||
|
||||
/**
|
||||
A Boolean value indicating whether the graph chart view should draw horizontal reference lines.
|
||||
|
||||
The default value of this property is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL showsHorizontalReferenceLines;
|
||||
|
||||
/**
|
||||
A Boolean value indicating whether the graph chart view should draw vertical reference lines.
|
||||
|
||||
The default value of this property is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL showsVerticalReferenceLines;
|
||||
|
||||
/**
|
||||
The delegate will be notified of pan gesture events occuring within the bounds of the graph chart
|
||||
view.
|
||||
|
||||
See the `ORKGraphChartViewDelegate` protocol.
|
||||
*/
|
||||
@property (nonatomic, weak, nullable) id <ORKGraphChartViewDelegate> delegate;
|
||||
|
||||
/**
|
||||
The dataSource responsible for providing the data required to populate the graph chart view.
|
||||
|
||||
See the `ORKGraphChartViewDataSource` protocol.
|
||||
*/
|
||||
@property (nonatomic, weak) id <ORKGraphChartViewDataSource> dataSource;
|
||||
|
||||
/**
|
||||
The color of the axes drawn by the graph chart view.
|
||||
|
||||
The default value for this property is a very light gray color. Setting this property to `nil`
|
||||
resets it to its default value.
|
||||
*/
|
||||
@property (nonatomic, strong, null_resettable) UIColor *axisColor;
|
||||
|
||||
/**
|
||||
The color of the vertical axis titles.
|
||||
|
||||
The default value for this property is a light gray color. Setting this property to `nil` resets it
|
||||
to its default value.
|
||||
|
||||
@note The horizontal axis titles use the current `tintColor`.
|
||||
*/
|
||||
@property (nonatomic, strong, null_resettable) UIColor *verticalAxisTitleColor;
|
||||
|
||||
/**
|
||||
The color of the reference lines.
|
||||
|
||||
The default value for this property is a light gray color. Setting this property to `nil` resets it
|
||||
to its default value.
|
||||
*/
|
||||
@property (nonatomic, strong, null_resettable) UIColor *referenceLineColor;
|
||||
|
||||
/**
|
||||
The background color of the thumb on the scrubber line.
|
||||
|
||||
The default value for this property is a white color. Setting this property to `nil` resets it to
|
||||
its default value.
|
||||
*/
|
||||
@property (nonatomic, strong, null_resettable) UIColor *scrubberThumbColor;
|
||||
|
||||
/**
|
||||
The color of the scrubber line.
|
||||
|
||||
The default value for this property is a gray color. Setting this property to `nil` resets it to
|
||||
its default value.
|
||||
*/
|
||||
@property (nonatomic, strong, null_resettable) UIColor *scrubberLineColor;
|
||||
|
||||
/**
|
||||
The string that will be displayed if no data points are provided by the `dataSource`.
|
||||
|
||||
The default value for this property is an appropriate message string. Setting this property to
|
||||
`nil` resets it to its default value.
|
||||
*/
|
||||
@property (nonatomic, copy, null_resettable) NSString *noDataText;
|
||||
|
||||
/**
|
||||
An image to be optionally displayed in place of the maximum value label on the y-axis.
|
||||
|
||||
The default value for this property is `nil`.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) UIImage *maximumValueImage;
|
||||
|
||||
/**
|
||||
An image to be optionally displayed in place of the minimum value label on the y-axis.
|
||||
|
||||
The default value for this property is `nil`.
|
||||
*/
|
||||
@property (nonatomic, strong, nullable) UIImage *minimumValueImage;
|
||||
|
||||
/**
|
||||
The gesture recognizer that is used for scrubbing by the graph chart view.
|
||||
|
||||
This object is instatiated and added to the view when it is created.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *panGestureRecognizer;
|
||||
|
||||
/**
|
||||
Animates the graph when it first displays on the screen.
|
||||
|
||||
You can optionally call this method from the `viewWillAppear:` implementation of the view
|
||||
controller that owns the graph chart view.
|
||||
|
||||
@param animationDuration The duration of the appearing animation.
|
||||
*/
|
||||
- (void)animateWithDuration:(NSTimeInterval)animationDuration;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKGraphChartView.h"
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
|
||||
@class ORKXAxisView;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ORKGraphAnimationType) {
|
||||
ORkGraphAnimationTypeNone,
|
||||
ORKGraphAnimationTypeFade,
|
||||
ORKGraphAnimationTypeGrow,
|
||||
ORKGraphAnimationTypePop
|
||||
};
|
||||
|
||||
extern const CGFloat ORKGraphChartViewLeftPadding;
|
||||
extern const CGFloat ORKGraphChartViewPointAndLineSize;
|
||||
extern const CGFloat ORKGraphChartViewScrubberMoveAnimationDuration;
|
||||
extern const CGFloat ORKGraphChartViewAxisTickLength;
|
||||
extern const CGFloat ORKGraphChartViewYAxisTickPadding;
|
||||
|
||||
|
||||
inline static CAShapeLayer *graphLineLayer() {
|
||||
CAShapeLayer *lineLayer = [CAShapeLayer layer];
|
||||
lineLayer.fillColor = [UIColor clearColor].CGColor;
|
||||
lineLayer.lineJoin = kCALineJoinRound;
|
||||
lineLayer.lineCap = kCALineCapRound;
|
||||
lineLayer.opacity = 1.0;
|
||||
return lineLayer;
|
||||
}
|
||||
|
||||
static inline CGFloat xAxisPoint(NSInteger pointIndex, NSInteger numberOfXAxisPoints, CGFloat canvasWidth) {
|
||||
return round((canvasWidth / MAX(1, numberOfXAxisPoints - 1)) * pointIndex);
|
||||
}
|
||||
|
||||
|
||||
@interface ORKGraphChartView ()
|
||||
|
||||
@property (nonatomic) NSMutableArray<NSMutableArray<CAShapeLayer *> *> *lineLayers;
|
||||
|
||||
@property (nonatomic) NSInteger numberOfXAxisPoints;
|
||||
|
||||
@property (nonatomic) NSMutableArray<NSMutableArray<ORKRangedPoint *> *> *dataPoints; // Actual data
|
||||
|
||||
@property (nonatomic) NSMutableArray<NSMutableArray<ORKRangedPoint *> *> *yAxisPoints; // Normalized for the plot view height
|
||||
|
||||
@property (nonatomic) UIView *plotView; // Holds the plots
|
||||
|
||||
@property (nonatomic) UIView *scrubberLine;
|
||||
|
||||
@property (nonatomic) BOOL scrubberAccessoryViewsHidden;
|
||||
|
||||
- (void)sharedInit;
|
||||
|
||||
- (NSInteger)numberOfPlots;
|
||||
|
||||
- (CGFloat)offsetForPlotIndex:(NSInteger)plotIndex;
|
||||
|
||||
- (NSInteger)numberOfValidValuesForPlotIndex:(NSInteger)plotIndex;
|
||||
|
||||
- (NSInteger)scrubbingPlotIndex;
|
||||
|
||||
- (CGFloat)valueForCanvasXPosition:(CGFloat)xPosition plotIndex:(NSInteger)plotIndex;
|
||||
|
||||
- (NSInteger)pointIndexForXPosition:(CGFloat)xPosition;
|
||||
|
||||
- (void)updateScrubberViewForXPosition:(CGFloat)xPosition plotIndex:(NSInteger)plotIndex;
|
||||
|
||||
- (void)updateScrubberLineAccessories:(CGFloat)xPosition plotIndex:(NSInteger)plotIndex;
|
||||
|
||||
- (BOOL)isXPositionSnapped:(CGFloat)xPosition;
|
||||
|
||||
- (void)updatePlotColors;
|
||||
|
||||
- (void)updateLineLayers;
|
||||
|
||||
- (void)layoutLineLayers;
|
||||
|
||||
- (void)updatePointLayers;
|
||||
|
||||
- (void)layoutPointLayers;
|
||||
|
||||
- (UIColor *)colorForplotIndex:(NSInteger)plotIndex;
|
||||
|
||||
- (void)animateLayersSequentiallyWithDuration:(NSTimeInterval)duration;
|
||||
|
||||
- (void)animateLayer:(CALayer *)layer
|
||||
keyPath:(NSString *)keyPath
|
||||
duration:(CGFloat)duration
|
||||
startDelay:(CGFloat)startDelay
|
||||
timingFunction:(CAMediaTimingFunction *)timingFunction;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ORKGraphChartView.h"
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
The `ORKLineGraphChartView` class presents the data provided by an object conforming to the
|
||||
`ORKGraphChartViewDataSource` protocol as a line graph.
|
||||
|
||||
The primary plot is colored by the `tintColor`, and any additional plots are colored using the
|
||||
`referenceLineColor`.
|
||||
*/
|
||||
ORK_CLASS_AVAILABLE
|
||||
@interface ORKLineGraphChartView : ORKGraphChartView
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKLineGraphChartView.h"
|
||||
#import "ORKGraphChartView_Internal.h"
|
||||
#import "ORKHelpers.h"
|
||||
#import "ORKRangedPoint.h"
|
||||
|
||||
|
||||
const CGFloat FillColorAlpha = 0.4;
|
||||
|
||||
@implementation ORKLineGraphChartView {
|
||||
NSMutableDictionary *_fillLayers;
|
||||
}
|
||||
|
||||
#pragma mark - Init
|
||||
|
||||
- (void)sharedInit {
|
||||
[super sharedInit];
|
||||
_fillLayers = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
- (BOOL)shouldDrawLinesForPlotIndex:(NSInteger)plotIndex {
|
||||
return [self numberOfValidValuesForPlotIndex:plotIndex] > 1;
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
|
||||
- (void)updatePlotColors {
|
||||
[super updatePlotColors];
|
||||
NSInteger numberOfPlots = [self numberOfPlots];
|
||||
for (NSUInteger plotIndex = 0; plotIndex < numberOfPlots; plotIndex++) {
|
||||
UIColor *fillColor = [[self colorForplotIndex:plotIndex] colorWithAlphaComponent:FillColorAlpha];
|
||||
CAShapeLayer *fillLayer = _fillLayers[@(plotIndex)];
|
||||
fillLayer.fillColor = fillColor.CGColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateLineLayers {
|
||||
[[_fillLayers allValues] makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
|
||||
[_fillLayers removeAllObjects];
|
||||
[super updateLineLayers];
|
||||
}
|
||||
|
||||
- (void)updateLineLayersForPlotIndex:(NSInteger)plotIndex {
|
||||
BOOL previousPointExists = NO;
|
||||
BOOL emptyDataPresent = NO;
|
||||
NSUInteger pointCount = self.dataPoints[plotIndex].count;
|
||||
for (NSUInteger pointIndex = 0; pointIndex < pointCount; pointIndex++) {
|
||||
if (self.dataPoints[plotIndex][pointIndex].isUnset) {
|
||||
emptyDataPresent = YES;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!previousPointExists) {
|
||||
previousPointExists = YES;
|
||||
emptyDataPresent = NO;
|
||||
continue;
|
||||
}
|
||||
|
||||
CAShapeLayer *lineLayer = graphLineLayer();
|
||||
lineLayer.strokeColor = [self colorForplotIndex:plotIndex].CGColor;
|
||||
lineLayer.lineWidth = 2.0;
|
||||
|
||||
if (emptyDataPresent) {
|
||||
lineLayer.lineDashPattern = @[@12, @6];
|
||||
emptyDataPresent = NO;
|
||||
}
|
||||
|
||||
[self.plotView.layer addSublayer:lineLayer];
|
||||
[self.lineLayers[plotIndex] addObject:lineLayer];
|
||||
}
|
||||
|
||||
CAShapeLayer *fillLayer = [CAShapeLayer layer];
|
||||
fillLayer.fillColor = [[self colorForplotIndex:plotIndex] colorWithAlphaComponent:0.4].CGColor;
|
||||
|
||||
[self.plotView.layer addSublayer:fillLayer];
|
||||
_fillLayers[@(plotIndex)] = fillLayer;
|
||||
}
|
||||
|
||||
- (void)layoutLineLayersForPlotIndex:(NSInteger)plotIndex {
|
||||
CAShapeLayer *fillLayer = _fillLayers[@(plotIndex)];
|
||||
|
||||
if (fillLayer == nil) {
|
||||
// Skip for a nil fillLayer
|
||||
return;
|
||||
}
|
||||
|
||||
NSUInteger lineLayerIndex = 0;
|
||||
UIBezierPath *fillPath = [UIBezierPath bezierPath];
|
||||
CGFloat positionOnXAxis = ORKCGFloatInvalidValue;
|
||||
ORKRangedPoint *positionOnYAxis = nil;
|
||||
BOOL previousPointExists = NO;
|
||||
NSUInteger pointCount = self.yAxisPoints[plotIndex].count;
|
||||
for (NSUInteger pointIndex = 0; pointIndex < pointCount; pointIndex++) {
|
||||
if (self.dataPoints[plotIndex][pointIndex].isUnset) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UIBezierPath *linePath = [UIBezierPath bezierPath];
|
||||
|
||||
if (positionOnXAxis != ORKCGFloatInvalidValue) {
|
||||
previousPointExists = YES;
|
||||
[linePath moveToPoint:CGPointMake(positionOnXAxis, positionOnYAxis.minimumValue)];
|
||||
if ([fillPath isEmpty]) {
|
||||
[fillPath moveToPoint:CGPointMake(positionOnXAxis, CGRectGetHeight(self.plotView.frame))];
|
||||
}
|
||||
[fillPath addLineToPoint:CGPointMake(positionOnXAxis, positionOnYAxis.minimumValue)];
|
||||
}
|
||||
|
||||
positionOnXAxis = xAxisPoint(pointIndex, self.numberOfXAxisPoints, self.plotView.bounds.size.width);
|
||||
positionOnYAxis = self.yAxisPoints[plotIndex][pointIndex];
|
||||
|
||||
if (!previousPointExists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
[linePath addLineToPoint:CGPointMake(positionOnXAxis, positionOnYAxis.minimumValue)];
|
||||
[fillPath addLineToPoint:CGPointMake(positionOnXAxis, positionOnYAxis.minimumValue)];
|
||||
|
||||
CAShapeLayer *lineLayer = self.lineLayers[plotIndex][lineLayerIndex];
|
||||
lineLayer.path = linePath.CGPath;
|
||||
lineLayerIndex++;
|
||||
}
|
||||
|
||||
[fillPath addLineToPoint:CGPointMake(positionOnXAxis, CGRectGetHeight(self.plotView.frame))];
|
||||
|
||||
fillLayer.path = fillPath.CGPath;
|
||||
}
|
||||
|
||||
#pragma mark - Graph Calculations
|
||||
|
||||
- (CGFloat)valueForCanvasXPosition:(CGFloat)xPosition plotIndex:(NSInteger)plotIndex {
|
||||
CGFloat value = [super valueForCanvasXPosition:xPosition plotIndex:plotIndex];
|
||||
|
||||
CGFloat viewWidth = self.plotView.bounds.size.width;
|
||||
NSInteger numberOfXAxisPoints = self.numberOfXAxisPoints;
|
||||
|
||||
if (value == ORKCGFloatInvalidValue) {
|
||||
NSInteger pointIndex = 0;
|
||||
for (pointIndex = 0; pointIndex < (numberOfXAxisPoints - 1); pointIndex++) {
|
||||
CGFloat xAxisPointValue = xAxisPoint(pointIndex, numberOfXAxisPoints, viewWidth);
|
||||
if (xAxisPointValue > xPosition) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NSInteger previousValidIndex = [self previousValidPointIndexForPointIndex:pointIndex plotIndex:plotIndex];
|
||||
NSInteger nextValidIndex = [self nextValidPointIndexForPointIndex:pointIndex plotIndex:plotIndex];
|
||||
|
||||
CGFloat x1 = xAxisPoint(previousValidIndex, numberOfXAxisPoints, viewWidth);
|
||||
CGFloat x2 = xAxisPoint(nextValidIndex, numberOfXAxisPoints, viewWidth);
|
||||
|
||||
CGFloat y1 = self.dataPoints[plotIndex][previousValidIndex].minimumValue;
|
||||
CGFloat y2 = self.dataPoints[plotIndex][nextValidIndex].minimumValue;
|
||||
|
||||
if (y1 == ORKCGFloatInvalidValue || y2 == ORKCGFloatInvalidValue) {
|
||||
return ORKCGFloatInvalidValue;
|
||||
}
|
||||
|
||||
CGFloat slope = (y2 - y1)/(x2 - x1);
|
||||
|
||||
// (y2 - y3)/(x2 - x3) = m
|
||||
value = y2 - (slope * (x2 - xPosition));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
- (CGFloat)canvasYPointForXPosition:(CGFloat)xPosition plotIndex:(NSInteger)plotIndex {
|
||||
NSInteger pointIndex = [self pointIndexForXPosition:xPosition];
|
||||
NSInteger nextValidIndex = [self nextValidPointIndexForPointIndex:pointIndex plotIndex:plotIndex];
|
||||
NSInteger previousValidIndex = [self previousValidPointIndexForPointIndex:pointIndex plotIndex:plotIndex];
|
||||
|
||||
CGFloat viewWidth = self.plotView.bounds.size.width;
|
||||
NSInteger numberOfXAxisPoints = self.numberOfXAxisPoints;
|
||||
|
||||
CGFloat x1 = xAxisPoint(previousValidIndex, numberOfXAxisPoints, viewWidth);
|
||||
CGFloat x2 = xAxisPoint(nextValidIndex, numberOfXAxisPoints, viewWidth);
|
||||
|
||||
CGFloat y1 = self.yAxisPoints[plotIndex][previousValidIndex].minimumValue;
|
||||
CGFloat y2 = self.yAxisPoints[plotIndex][nextValidIndex].minimumValue;
|
||||
|
||||
CGFloat slope = (y2 - y1)/(x2 - x1);
|
||||
|
||||
// (y2 - y3)/(x2 - x3) = m
|
||||
CGFloat canvasYPosition = y2 - (slope * (x2 - xPosition));
|
||||
|
||||
return canvasYPosition;
|
||||
}
|
||||
|
||||
- (NSInteger)nextValidPointIndexForPointIndex:(NSInteger)pointIndex plotIndex:(NSInteger)plotIndex {
|
||||
NSUInteger validPosition = pointIndex;
|
||||
|
||||
NSUInteger pointCountMinusOne = (self.dataPoints[plotIndex].count - 1);
|
||||
while (validPosition < pointCountMinusOne) {
|
||||
if (self.dataPoints[plotIndex][validPosition].maximumValue != ORKCGFloatInvalidValue) {
|
||||
break;
|
||||
}
|
||||
validPosition++;
|
||||
}
|
||||
|
||||
return validPosition;
|
||||
}
|
||||
|
||||
- (NSInteger)previousValidPointIndexForPointIndex:(NSInteger)pointIndex plotIndex:(NSInteger)plotIndex {
|
||||
NSInteger validPosition = pointIndex - 1;
|
||||
while (validPosition > 0) {
|
||||
if (self.dataPoints[plotIndex][validPosition].minimumValue != ORKCGFloatInvalidValue) {
|
||||
break;
|
||||
}
|
||||
validPosition--;
|
||||
}
|
||||
return validPosition;
|
||||
}
|
||||
|
||||
#pragma mark - Animations
|
||||
|
||||
- (void)animateWithDuration:(NSTimeInterval)animationDuration {
|
||||
[_fillLayers enumerateKeysAndObjectsUsingBlock:^(id key, CAShapeLayer *fillLayer, BOOL *stop) {
|
||||
[fillLayer removeAllAnimations];
|
||||
fillLayer.opacity = 0;
|
||||
}];
|
||||
|
||||
[super animateWithDuration:animationDuration];
|
||||
}
|
||||
|
||||
- (void)animateLayersSequentiallyWithDuration:(NSTimeInterval)duration {
|
||||
[super animateLayersSequentiallyWithDuration:duration];
|
||||
|
||||
[_fillLayers enumerateKeysAndObjectsUsingBlock:^(id key, CAShapeLayer *layer, BOOL *stop) {
|
||||
[self animateLayer:layer
|
||||
keyPath:@"opacity"
|
||||
duration:duration * (1/3.0)
|
||||
startDelay:duration * (2/3.0)
|
||||
timingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ORKPieChartLegendCell : UICollectionViewCell
|
||||
|
||||
@property (nonatomic, strong) UILabel *titleLabel;
|
||||
|
||||
@property (nonatomic, strong) UIView *dotView;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright (c) 2015, James Cox. All rights reserved.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKPieChartLegendCell.h"
|
||||
#import "ORKSkin.h"
|
||||
|
||||
|
||||
const CGFloat DotViewSize = 10.0;
|
||||
const CGFloat DotToLabelPadding = 6.0;
|
||||
|
||||
@implementation ORKPieChartLegendCell
|
||||
|
||||
#pragma mark - Init
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
if (self = [super initWithCoder:aDecoder]) {
|
||||
[self sharedInit];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[self sharedInit];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sharedInit {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.textColor = ORKColor(ORKChartDefaultTextColorKey);
|
||||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
_titleLabel.isAccessibilityElement = NO;
|
||||
_dotView = [UIView new];
|
||||
_dotView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
_dotView.layer.cornerRadius = DotViewSize * 0.5;
|
||||
_dotView.layer.masksToBounds = YES;
|
||||
[self.contentView addSubview:_titleLabel];
|
||||
[self.contentView addSubview:_dotView];
|
||||
|
||||
[self setUpConstraints];
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (void)setUpConstraints {
|
||||
NSMutableArray<NSLayoutConstraint *> *constraints = [NSMutableArray new];
|
||||
NSDictionary *views = NSDictionaryOfVariableBindings(_titleLabel, _dotView);
|
||||
|
||||
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=0)-[_titleLabel]-(>=0)-|"
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil
|
||||
views:views]];
|
||||
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=0)-[_dotView]-(>=0)-|"
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:nil
|
||||
views:views]];
|
||||
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_dotView]-DotToLabelPadding-[_titleLabel]|"
|
||||
options:(NSLayoutFormatOptions)0
|
||||
metrics:@{@"DotToLabelPadding": @(DotToLabelPadding)}
|
||||
views:views]];
|
||||
|
||||
[constraints addObject:[NSLayoutConstraint constraintWithItem:_dotView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:0
|
||||
multiplier:1.0
|
||||
constant:DotViewSize]];
|
||||
[constraints addObject:[NSLayoutConstraint constraintWithItem:_dotView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:_dotView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
multiplier:1.0
|
||||
constant:0.0]];
|
||||
[constraints addObject:[NSLayoutConstraint constraintWithItem:_dotView
|
||||
attribute:NSLayoutAttributeCenterY
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:_titleLabel
|
||||
attribute:NSLayoutAttributeCenterY
|
||||
multiplier:1.0
|
||||
constant:0.0]];
|
||||
|
||||
[NSLayoutConstraint activateConstraints:constraints];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresConstraintBasedLayout {
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Accessibility
|
||||
|
||||
- (BOOL)isAccessibilityElement {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)accessibilityLabel {
|
||||
return _titleLabel.accessibilityLabel;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@class ORKPieChartView;
|
||||
|
||||
@interface ORKPieChartLegendView : UICollectionView <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||
|
||||
@property (nonatomic) UIFont *labelFont;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
collectionViewLayout:(UICollectionViewLayout *)collectionViewLayout NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithParentPieChartView:(ORKPieChartView *)parentPieChartView NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)animateWithDuration:(NSTimeInterval)animationDuration;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import "ORKPieChartLegendView.h"
|
||||
#import "ORKPieChartView_Internal.h"
|
||||
#import "ORKPieChartLegendCell.h"
|
||||
#import "ORKCenteredCollectionViewLayout.h"
|
||||
#import "ORKHelpers.h"
|
||||
|
||||
|
||||
@implementation ORKPieChartLegendView {
|
||||
__weak ORKPieChartView *_parentPieChartView;
|
||||
ORKPieChartLegendCell *_sizingCell;
|
||||
CGFloat _sumOfValues;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
collectionViewLayout:(UICollectionViewLayout *)collectionViewLayout {
|
||||
ORKThrowMethodUnavailableException();
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
self = [self initWithParentPieChartView:nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithParentPieChartView:(ORKPieChartView *)parentPieChartView {
|
||||
ORKCenteredCollectionViewLayout *centeredCollectionViewLayout = [[ORKCenteredCollectionViewLayout alloc] init];
|
||||
centeredCollectionViewLayout.estimatedItemSize = CGSizeMake(100.0, 30.0);
|
||||
self = [super initWithFrame:CGRectZero collectionViewLayout:centeredCollectionViewLayout];
|
||||
if (self) {
|
||||
_parentPieChartView = parentPieChartView;
|
||||
_sumOfValues = 0;
|
||||
NSInteger numberOfSegments = [_parentPieChartView.dataSource numberOfSegmentsInPieChartView:_parentPieChartView];
|
||||
for (NSInteger idx = 0; idx < numberOfSegments; idx++) {
|
||||
CGFloat value = [_parentPieChartView.dataSource pieChartView:_parentPieChartView valueForSegmentAtIndex:idx];
|
||||
_sumOfValues += value;
|
||||
}
|
||||
|
||||
[self registerClass:[ORKPieChartLegendCell class] forCellWithReuseIdentifier:@"cell"];
|
||||
|
||||
_sizingCell = [[ORKPieChartLegendCell alloc] initWithFrame:CGRectZero];
|
||||
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
self.dataSource = self;
|
||||
self.delegate = self;
|
||||
|
||||
[self setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
|
||||
[self setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setLabelFont:(UIFont *)labelFont {
|
||||
_labelFont = labelFont;
|
||||
_sizingCell.titleLabel.font = _labelFont;
|
||||
[self reloadData];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize {
|
||||
CGSize size = CGSizeMake(UIViewNoIntrinsicMetric, [self.collectionViewLayout collectionViewContentSize].height);
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void)animateWithDuration:(NSTimeInterval)animationDuration {
|
||||
NSArray<UICollectionViewCell *> *sortedCells = [self.visibleCells sortedArrayUsingComparator:^NSComparisonResult(UICollectionViewCell *cell1, UICollectionViewCell *cell2) {
|
||||
return cell1.tag > cell2.tag;
|
||||
}];
|
||||
NSUInteger cellCount = sortedCells.count;
|
||||
NSTimeInterval interAnimationDelay = 0.05;
|
||||
NSTimeInterval singleAnimationDuration = animationDuration - (interAnimationDelay * (cellCount-1));
|
||||
if (singleAnimationDuration < 0) {
|
||||
interAnimationDelay = 0;
|
||||
singleAnimationDuration = animationDuration;
|
||||
}
|
||||
for (NSUInteger idx = 0; idx < cellCount; idx++) {
|
||||
UICollectionViewCell *cell = sortedCells[idx];
|
||||
cell.transform = CGAffineTransformMakeScale(0, 0);
|
||||
[UIView animateWithDuration:singleAnimationDuration
|
||||
delay:interAnimationDelay * idx
|
||||
options:(UIViewAnimationOptions)0
|
||||
animations:^{
|
||||
cell.transform = CGAffineTransformIdentity;
|
||||
} completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionViewDataSource / UICollectionViewDelegate
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
CGFloat value = [_parentPieChartView.dataSource pieChartView:_parentPieChartView valueForSegmentAtIndex:indexPath.item];
|
||||
NSString *title = [_parentPieChartView.dataSource pieChartView:_parentPieChartView titleForSegmentAtIndex:indexPath.item];
|
||||
|
||||
ORKPieChartLegendCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
|
||||
cell.tag = indexPath.item;
|
||||
cell.titleLabel.text = title;
|
||||
cell.titleLabel.font = _labelFont;
|
||||
cell.dotView.backgroundColor = [_parentPieChartView colorForSegmentAtIndex:indexPath.item];
|
||||
|
||||
cell.accessibilityLabel = title;
|
||||
cell.accessibilityValue = [NSString stringWithFormat:@"%0.0f%%", (value < .01) ? 1 : value / _sumOfValues * 100];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
return [_parentPieChartView.dataSource numberOfSegmentsInPieChartView:_parentPieChartView];
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView
|
||||
layout:(UICollectionViewLayout *)collectionViewLayout
|
||||
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
_sizingCell.titleLabel.text = [_parentPieChartView.dataSource pieChartView:_parentPieChartView titleForSegmentAtIndex:indexPath.item];
|
||||
CGSize size = [_sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
|
||||
return size;
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
|
||||
return 10.0;
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
|
||||
return 6.0;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright (c) 2015, Apple Inc. All rights reserved.
|
||||
Copyright (c) 2015, James Cox.
|
||||
Copyright (c) 2015, Ricardo Sánchez-Sáez.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission. No license is granted to the trademarks of
|
||||
the copyright holders even if such marks are included in this software.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@class ORKPieChartView;
|
||||
|
||||
@interface ORKPieChartPieView : UIView
|
||||
|
||||
@property (nonatomic) UIFont *percentageLabelFont;
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithParentPieChartView:(ORKPieChartView *)parentPieChartView NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (CGFloat)normalizeValues;
|
||||
|
||||
- (void)updatePieLayers;
|
||||
|
||||
- (void)updatePercentageLabels;
|
||||
|
||||
- (void)updateColors;
|
||||
|
||||
- (void)animateWithDuration:(NSTimeInterval)animationDuration;
|
||||
|
||||
@end
|
||||