storyboardlint 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +10 -0
- data/README.md +1 -0
- data/Rakefile +7 -1
- data/VERSION +1 -1
- data/lib/storyboardlint.rb +96 -52
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/Base.lproj/Main_iPad.storyboard +138 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/Base.lproj/Main_iPhone.storyboard +125 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/Images.xcassets/LaunchImage.launchimage/Contents.json +51 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/SPWKAppDelegate.h +15 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/SPWKAppDelegate.m +51 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/SPWKDetailViewController.h +16 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/SPWKDetailViewController.m +80 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/SPWKMasterViewController.h +17 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/SPWKMasterViewController.m +131 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/StoryboardLintTest-Info.plist +59 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/StoryboardLintTest-Prefix.pch +16 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/TestView.xib +25 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/en.lproj/InfoPlist.strings +2 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest/main.m +18 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest.xcodeproj/project.pbxproj +466 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/fixtures/StoryboardLintTest/StoryboardLintTest.xcodeproj/project.xcworkspace/xcshareddata/StoryboardLintTest.xccheckout +41 -0
- data/spec/linter_spec.rb +26 -0
- data/spec/matcher_spec.rb +156 -0
- data/spec/source_scanner_spec.rb +139 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/storyboard_scanner_spec.rb +56 -0
- data/storyboardlint.gemspec +31 -2
- metadata +42 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cff590128484b450950874dc541b476c2dfdc69e
|
|
4
|
+
data.tar.gz: a27efee054708381b70b433c31ebb7ef5b68bd7e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e9d1b1fc5c6716ad240c41ba662617146cbe1d1efa661125e2dfbfb131a126240d7e13584e1a6f5151358ded9f0a288a273dfb62e56e159dd2f6ae7acdbb4e7c
|
|
7
|
+
data.tar.gz: 9ca7b267a26383ca59d050716737227de9a567ae3e651137d83bf4f70622079dbd7c205ff9c10dc1467e86830db7fae2dcefdb1a8da518c3258d5f21ef002c24
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
- XIB files are now also scanned for reuse identifiers
|
|
6
|
+
- Added tests
|
|
7
|
+
|
|
8
|
+
## 0.1.2
|
|
9
|
+
|
|
10
|
+
- UTF-8 support
|
|
11
|
+
|
|
12
|
+
## 0.1.1
|
|
13
|
+
|
|
14
|
+
- Support for custom pre- and suffixes for Storyboard IDs, Segue IDs and reuse IDs
|
|
15
|
+
|
|
16
|
+
## 0.1.0
|
|
17
|
+
|
|
18
|
+
- First release
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -3,6 +3,7 @@ GEM
|
|
|
3
3
|
specs:
|
|
4
4
|
addressable (2.3.5)
|
|
5
5
|
builder (3.2.2)
|
|
6
|
+
diff-lcs (1.2.5)
|
|
6
7
|
faraday (0.8.9)
|
|
7
8
|
multipart-post (~> 1.2.0)
|
|
8
9
|
git (1.2.6)
|
|
@@ -41,6 +42,14 @@ GEM
|
|
|
41
42
|
rake (10.1.1)
|
|
42
43
|
rdoc (4.1.1)
|
|
43
44
|
json (~> 1.4)
|
|
45
|
+
rspec (2.14.1)
|
|
46
|
+
rspec-core (~> 2.14.0)
|
|
47
|
+
rspec-expectations (~> 2.14.0)
|
|
48
|
+
rspec-mocks (~> 2.14.0)
|
|
49
|
+
rspec-core (2.14.7)
|
|
50
|
+
rspec-expectations (2.14.5)
|
|
51
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
|
52
|
+
rspec-mocks (2.14.6)
|
|
44
53
|
|
|
45
54
|
PLATFORMS
|
|
46
55
|
ruby
|
|
@@ -49,3 +58,4 @@ DEPENDENCIES
|
|
|
49
58
|
bundler (~> 1.3.5)
|
|
50
59
|
jeweler (~> 1.8.0)
|
|
51
60
|
nokogiri (~> 1.5.0)
|
|
61
|
+
rspec (~> 2.14.0)
|
data/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
StoryboardLint
|
|
2
2
|
==============
|
|
3
|
+
[](https://travis-ci.org/jfahrenkrug/StoryboardLint)
|
|
3
4
|
|
|
4
5
|
A lint tool for UIStoryboard to find wrong classes and wrong storyboard/segue/reuse identifiers.
|
|
5
6
|
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
2
|
require 'bundler'
|
|
3
|
+
require "rspec/core/rake_task"
|
|
3
4
|
begin
|
|
4
5
|
Bundler.setup(:default, :development)
|
|
5
6
|
rescue Bundler::BundlerError => e
|
|
@@ -22,4 +23,9 @@ Jeweler::Tasks.new do |gem|
|
|
|
22
23
|
|
|
23
24
|
# dependencies defined in Gemfile
|
|
24
25
|
end
|
|
25
|
-
Jeweler::RubygemsDotOrgTasks.new
|
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
|
27
|
+
|
|
28
|
+
RSpec::Core::RakeTask.new
|
|
29
|
+
|
|
30
|
+
task :test => :spec
|
|
31
|
+
task :default => :spec
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.2.0
|
data/lib/storyboardlint.rb
CHANGED
|
@@ -9,6 +9,10 @@ require 'optparse'
|
|
|
9
9
|
module StoryboardLint
|
|
10
10
|
class StoryboardScanner
|
|
11
11
|
def initialize(src_root)
|
|
12
|
+
if !File.directory?(src_root)
|
|
13
|
+
raise ArgumentError, "The directory '#{src_root}' does not exist."
|
|
14
|
+
end
|
|
15
|
+
|
|
12
16
|
@src_root = src_root
|
|
13
17
|
@scan_performed = false
|
|
14
18
|
end
|
|
@@ -20,6 +24,35 @@ module StoryboardLint
|
|
|
20
24
|
@sb_files = Dir.glob(File.join(@src_root, "**/*.storyboard"))
|
|
21
25
|
end
|
|
22
26
|
|
|
27
|
+
def xib_files
|
|
28
|
+
return @xib_files if @xib_files
|
|
29
|
+
|
|
30
|
+
# find all XIB files...
|
|
31
|
+
@xib_files = Dir.glob(File.join(@src_root, "**/*.xib"))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def segue_ids
|
|
35
|
+
scan_files
|
|
36
|
+
@segue_ids
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def storyboard_ids
|
|
40
|
+
scan_files
|
|
41
|
+
@storyboard_ids
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def reuse_ids
|
|
45
|
+
scan_files
|
|
46
|
+
@reuse_ids
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def custom_class_names
|
|
50
|
+
scan_files
|
|
51
|
+
@custom_class_names
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
23
56
|
def scan_files
|
|
24
57
|
if !@scan_performed
|
|
25
58
|
@segue_ids ||= []
|
|
@@ -40,9 +73,39 @@ module StoryboardLint
|
|
|
40
73
|
@custom_class_names += doc.xpath("//@customClass").to_a.map {|match| {:file => sb_file, :class_name => match.to_s}}
|
|
41
74
|
end
|
|
42
75
|
|
|
76
|
+
xib_files.each do |xib_file|
|
|
77
|
+
xib_source = File.open(xib_file)
|
|
78
|
+
doc = Nokogiri::XML(xib_source)
|
|
79
|
+
|
|
80
|
+
@reuse_ids += doc.xpath("//@reuseIdentifier").to_a.map {|match| {:file => xib_file, :id => match.to_s}}
|
|
81
|
+
end
|
|
82
|
+
|
|
43
83
|
@scan_performed = true
|
|
44
84
|
end
|
|
45
85
|
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class SourceScanner
|
|
89
|
+
def initialize(src_root, matcher)
|
|
90
|
+
if !File.directory?(src_root)
|
|
91
|
+
raise ArgumentError, "The directory '#{src_root}' does not exist."
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if !matcher
|
|
95
|
+
raise ArgumentError, "The matcher cannot be nil."
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
@matcher = matcher
|
|
99
|
+
@src_root = src_root
|
|
100
|
+
@scan_performed = false
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def source_files
|
|
104
|
+
return @source_files if @source_files
|
|
105
|
+
|
|
106
|
+
# find all *.h, *.c, *.m and *.mm files
|
|
107
|
+
@source_files = Dir.glob(File.join(@src_root, "**/*.{h,c,m,mm}"))
|
|
108
|
+
end
|
|
46
109
|
|
|
47
110
|
def segue_ids
|
|
48
111
|
scan_files
|
|
@@ -59,25 +122,12 @@ module StoryboardLint
|
|
|
59
122
|
@reuse_ids
|
|
60
123
|
end
|
|
61
124
|
|
|
62
|
-
def
|
|
125
|
+
def class_names
|
|
63
126
|
scan_files
|
|
64
|
-
@
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
class SourceScanner
|
|
69
|
-
def initialize(src_root, matcher)
|
|
70
|
-
@matcher = matcher
|
|
71
|
-
@src_root = src_root
|
|
72
|
-
@scan_performed = false
|
|
127
|
+
@class_names
|
|
73
128
|
end
|
|
74
129
|
|
|
75
|
-
|
|
76
|
-
return @source_files if @source_files
|
|
77
|
-
|
|
78
|
-
# find all *.h, *.c, *.m and *.mm files
|
|
79
|
-
@source_files = Dir.glob(File.join(@src_root, "**/*.{h,c,m,mm}"))
|
|
80
|
-
end
|
|
130
|
+
private
|
|
81
131
|
|
|
82
132
|
def scan_files
|
|
83
133
|
if !@scan_performed
|
|
@@ -113,26 +163,6 @@ module StoryboardLint
|
|
|
113
163
|
@scan_performed = true
|
|
114
164
|
end
|
|
115
165
|
end
|
|
116
|
-
|
|
117
|
-
def class_names
|
|
118
|
-
scan_files
|
|
119
|
-
@class_names
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def segue_ids
|
|
123
|
-
scan_files
|
|
124
|
-
@segue_ids
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def storyboard_ids
|
|
128
|
-
scan_files
|
|
129
|
-
@storyboard_ids
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def reuse_ids
|
|
133
|
-
scan_files
|
|
134
|
-
@reuse_ids
|
|
135
|
-
end
|
|
136
166
|
end
|
|
137
167
|
|
|
138
168
|
class Matcher
|
|
@@ -152,6 +182,19 @@ module StoryboardLint
|
|
|
152
182
|
@reuse_id_regex_source = create_source_regex(DEFAULT_REUSE_ID_PREFIX, options.reuse_prefix, options.reuse_suffix)
|
|
153
183
|
@reuse_id_regex_sb = create_storyboard_regex(DEFAULT_REUSE_ID_PREFIX, options.reuse_prefix, options.reuse_suffix)
|
|
154
184
|
end
|
|
185
|
+
|
|
186
|
+
def class_regex
|
|
187
|
+
/@interface\s+([a-zA-Z_]+\w*)/
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
[:storyboard, :segue, :reuse].each do |name|
|
|
191
|
+
[:sb, :source].each do |kind|
|
|
192
|
+
method_name = "#{name}_id_regex_#{kind}"
|
|
193
|
+
define_method(method_name) { instance_variable_get("@#{method_name}") }
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
private
|
|
155
198
|
|
|
156
199
|
def create_source_regex(default_prefix, prefix, suffix)
|
|
157
200
|
inner_regex_part = %{(?:\\"|[^"])+}
|
|
@@ -180,21 +223,22 @@ module StoryboardLint
|
|
|
180
223
|
|
|
181
224
|
sb
|
|
182
225
|
end
|
|
183
|
-
|
|
184
|
-
def class_regex
|
|
185
|
-
/@interface\s+([a-zA-Z_]+\w*)/
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
[:storyboard, :segue, :reuse].each do |name|
|
|
189
|
-
[:sb, :source].each do |kind|
|
|
190
|
-
method_name = "#{name}_id_regex_#{kind}"
|
|
191
|
-
define_method(method_name) { instance_variable_get("@#{method_name}") }
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
226
|
end
|
|
195
227
|
|
|
196
228
|
class Linter
|
|
197
229
|
def initialize(sb_scanner, source_scanner, matcher)
|
|
230
|
+
if !sb_scanner
|
|
231
|
+
raise ArgumentError, "The sb_scanner cannot be nil."
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
if !source_scanner
|
|
235
|
+
raise ArgumentError, "The source_scanner cannot be nil."
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
if !matcher
|
|
239
|
+
raise ArgumentError, "The matcher cannot be nil."
|
|
240
|
+
end
|
|
241
|
+
|
|
198
242
|
@matcher = matcher
|
|
199
243
|
@sb_scanner = sb_scanner
|
|
200
244
|
@source_scanner = source_scanner
|
|
@@ -227,12 +271,12 @@ module StoryboardLint
|
|
|
227
271
|
end
|
|
228
272
|
|
|
229
273
|
def check_ids
|
|
230
|
-
[{:method_name => :segue_ids, :name => 'Segue ID'},
|
|
231
|
-
{:method_name => :storyboard_ids, :name => 'Storyboard ID'},
|
|
232
|
-
{:method_name => :reuse_ids, :name => 'Reuse ID'}].each do |data|
|
|
274
|
+
[{:method_name => :segue_ids, :name => 'Segue ID', :target => 'Storyboard'},
|
|
275
|
+
{:method_name => :storyboard_ids, :name => 'Storyboard ID', :target => 'Storyboard'},
|
|
276
|
+
{:method_name => :reuse_ids, :name => 'Reuse ID', :target => 'Storyboard or XIB'}].each do |data|
|
|
233
277
|
@source_scanner.send(data[:method_name]).each do |source_item|
|
|
234
278
|
if !@sb_scanner.send(data[:method_name]).map {|sb_item| sb_item[:id]}.include?(source_item[:id])
|
|
235
|
-
puts "#{source_item[:file]}:#{source_item[:line]}: warning: #{data[:name]} '#{source_item[:id]}' could not be found in any
|
|
279
|
+
puts "#{source_item[:file]}:#{source_item[:line]}: warning: #{data[:name]} '#{source_item[:id]}' could not be found in any #{data[:target]}."
|
|
236
280
|
end
|
|
237
281
|
end
|
|
238
282
|
end
|
|
@@ -279,7 +323,7 @@ module StoryboardLint
|
|
|
279
323
|
|
|
280
324
|
# Another typical switch to print the version.
|
|
281
325
|
opts.on_tail("--version", "Show version") do
|
|
282
|
-
puts "StoryboardLint v0.
|
|
326
|
+
puts "StoryboardLint v0.2.0"
|
|
283
327
|
exit
|
|
284
328
|
end
|
|
285
329
|
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13A598" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" initialViewController="H1p-Uh-vWS">
|
|
3
|
+
<dependencies>
|
|
4
|
+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
|
5
|
+
</dependencies>
|
|
6
|
+
<scenes>
|
|
7
|
+
<!--Navigation Controller-->
|
|
8
|
+
<scene sceneID="pY4-Hu-kfo">
|
|
9
|
+
<objects>
|
|
10
|
+
<navigationController id="RMx-3f-FxP" sceneMemberID="viewController">
|
|
11
|
+
<navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="Pmd-2v-anx">
|
|
12
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
13
|
+
</navigationBar>
|
|
14
|
+
<connections>
|
|
15
|
+
<segue destination="7bK-jq-Zjz" kind="relationship" relationship="rootViewController" id="tsl-Nk-0bq"/>
|
|
16
|
+
</connections>
|
|
17
|
+
</navigationController>
|
|
18
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="8fS-aE-onr" sceneMemberID="firstResponder"/>
|
|
19
|
+
</objects>
|
|
20
|
+
<point key="canvasLocation" x="448" y="-630"/>
|
|
21
|
+
</scene>
|
|
22
|
+
<!--Detail View Controller - Detail-->
|
|
23
|
+
<scene sceneID="yUG-lL-AsK">
|
|
24
|
+
<objects>
|
|
25
|
+
<viewController title="Detail" id="JEX-9P-axG" customClass="SPWKDetailViewController" sceneMemberID="viewController">
|
|
26
|
+
<layoutGuides>
|
|
27
|
+
<viewControllerLayoutGuide type="top" id="E9l-JE-Xxa"/>
|
|
28
|
+
<viewControllerLayoutGuide type="bottom" id="NXR-7p-zaA"/>
|
|
29
|
+
</layoutGuides>
|
|
30
|
+
<view key="view" contentMode="scaleToFill" id="svH-Pt-448">
|
|
31
|
+
<rect key="frame" x="0.0" y="0.0" width="703" height="768"/>
|
|
32
|
+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
33
|
+
<subviews>
|
|
34
|
+
<label clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Detail view content goes here" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="0XM-y9-sOw">
|
|
35
|
+
<rect key="frame" x="20" y="376" width="663" height="17"/>
|
|
36
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
37
|
+
<fontDescription key="fontDescription" type="system" size="system"/>
|
|
38
|
+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
39
|
+
<nil key="highlightedColor"/>
|
|
40
|
+
</label>
|
|
41
|
+
</subviews>
|
|
42
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
|
43
|
+
<constraints>
|
|
44
|
+
<constraint firstItem="0XM-y9-sOw" firstAttribute="leading" secondItem="svH-Pt-448" secondAttribute="leading" constant="20" symbolic="YES" id="Tsc-yG-G1q"/>
|
|
45
|
+
<constraint firstItem="0XM-y9-sOw" firstAttribute="centerY" secondItem="svH-Pt-448" secondAttribute="centerY" id="jWN-iV-94e"/>
|
|
46
|
+
<constraint firstAttribute="trailing" secondItem="0XM-y9-sOw" secondAttribute="trailing" constant="20" symbolic="YES" id="tHV-ZD-HQj"/>
|
|
47
|
+
</constraints>
|
|
48
|
+
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
49
|
+
</view>
|
|
50
|
+
<toolbarItems/>
|
|
51
|
+
<navigationItem key="navigationItem" title="Detail" id="mOI-FS-AaM"/>
|
|
52
|
+
<connections>
|
|
53
|
+
<outlet property="detailDescriptionLabel" destination="0XM-y9-sOw" id="deQ-Na-JPF"/>
|
|
54
|
+
</connections>
|
|
55
|
+
</viewController>
|
|
56
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="FJe-Yq-33r" sceneMemberID="firstResponder"/>
|
|
57
|
+
</objects>
|
|
58
|
+
<point key="canvasLocation" x="448" y="248"/>
|
|
59
|
+
</scene>
|
|
60
|
+
<!--Split View Controller-->
|
|
61
|
+
<scene sceneID="Nki-YV-4Qg">
|
|
62
|
+
<objects>
|
|
63
|
+
<splitViewController id="H1p-Uh-vWS" sceneMemberID="viewController">
|
|
64
|
+
<toolbarItems/>
|
|
65
|
+
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="blackOpaque"/>
|
|
66
|
+
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
67
|
+
<connections>
|
|
68
|
+
<segue destination="RMx-3f-FxP" kind="relationship" relationship="masterViewController" id="BlO-5A-QYV"/>
|
|
69
|
+
<segue destination="vC3-pB-5Vb" kind="relationship" relationship="detailViewController" id="Tll-UG-LXB"/>
|
|
70
|
+
</connections>
|
|
71
|
+
</splitViewController>
|
|
72
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="cZU-Oi-B1e" sceneMemberID="firstResponder"/>
|
|
73
|
+
</objects>
|
|
74
|
+
<point key="canvasLocation" x="-687" y="-630"/>
|
|
75
|
+
</scene>
|
|
76
|
+
<!--Master View Controller - Master-->
|
|
77
|
+
<scene sceneID="smW-Zh-WAh">
|
|
78
|
+
<objects>
|
|
79
|
+
<tableViewController title="Master" clearsSelectionOnViewWillAppear="NO" id="7bK-jq-Zjz" customClass="SPWKMasterViewController" sceneMemberID="viewController">
|
|
80
|
+
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="r7i-6Z-zg0">
|
|
81
|
+
<rect key="frame" x="0.0" y="0.0" width="320" height="768"/>
|
|
82
|
+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
83
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
84
|
+
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
85
|
+
<prototypes>
|
|
86
|
+
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="Arm-wq-HPj" style="IBUITableViewCellStyleDefault" id="WCw-Qf-5nD">
|
|
87
|
+
<rect key="frame" x="0.0" y="86" width="320" height="44"/>
|
|
88
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
89
|
+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WCw-Qf-5nD" id="j8x-TT-mEF">
|
|
90
|
+
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
|
|
91
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
92
|
+
<subviews>
|
|
93
|
+
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Arm-wq-HPj">
|
|
94
|
+
<rect key="frame" x="15" y="0.0" width="290" height="43"/>
|
|
95
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
96
|
+
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
|
|
97
|
+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
98
|
+
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
|
99
|
+
</label>
|
|
100
|
+
</subviews>
|
|
101
|
+
</tableViewCellContentView>
|
|
102
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
103
|
+
</tableViewCell>
|
|
104
|
+
</prototypes>
|
|
105
|
+
<sections/>
|
|
106
|
+
<connections>
|
|
107
|
+
<outlet property="dataSource" destination="7bK-jq-Zjz" id="Gho-Na-rnu"/>
|
|
108
|
+
<outlet property="delegate" destination="7bK-jq-Zjz" id="RA6-mI-bju"/>
|
|
109
|
+
</connections>
|
|
110
|
+
</tableView>
|
|
111
|
+
<navigationItem key="navigationItem" title="Master" id="Zdf-7t-Un8"/>
|
|
112
|
+
</tableViewController>
|
|
113
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="Rux-fX-hf1" sceneMemberID="firstResponder"/>
|
|
114
|
+
</objects>
|
|
115
|
+
<point key="canvasLocation" x="859" y="-631"/>
|
|
116
|
+
</scene>
|
|
117
|
+
<!--Navigation Controller-->
|
|
118
|
+
<scene sceneID="r7l-gg-dq7">
|
|
119
|
+
<objects>
|
|
120
|
+
<navigationController id="vC3-pB-5Vb" sceneMemberID="viewController">
|
|
121
|
+
<navigationBar key="navigationBar" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="DjV-YW-jjY">
|
|
122
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
123
|
+
</navigationBar>
|
|
124
|
+
<connections>
|
|
125
|
+
<segue destination="JEX-9P-axG" kind="relationship" relationship="rootViewController" id="GKi-kA-LjT"/>
|
|
126
|
+
</connections>
|
|
127
|
+
</navigationController>
|
|
128
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="SLD-UC-DBI" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
129
|
+
</objects>
|
|
130
|
+
<point key="canvasLocation" x="-366" y="248"/>
|
|
131
|
+
</scene>
|
|
132
|
+
</scenes>
|
|
133
|
+
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
|
134
|
+
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="blackOpaque"/>
|
|
135
|
+
<simulatedOrientationMetrics key="orientation"/>
|
|
136
|
+
<simulatedScreenMetrics key="destination"/>
|
|
137
|
+
</simulatedMetricsContainer>
|
|
138
|
+
</document>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13A598" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="rS3-R9-Ivy">
|
|
3
|
+
<dependencies>
|
|
4
|
+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
|
|
5
|
+
</dependencies>
|
|
6
|
+
<scenes>
|
|
7
|
+
<!--Nonexistent View Controller-->
|
|
8
|
+
<scene sceneID="sqY-Eh-LZl">
|
|
9
|
+
<objects>
|
|
10
|
+
<viewController id="ggl-FL-rMO" customClass="NonexistentViewController" sceneMemberID="viewController">
|
|
11
|
+
<layoutGuides>
|
|
12
|
+
<viewControllerLayoutGuide type="top" id="DHG-f8-iSv"/>
|
|
13
|
+
<viewControllerLayoutGuide type="bottom" id="Pcc-sg-8SB"/>
|
|
14
|
+
</layoutGuides>
|
|
15
|
+
<view key="view" contentMode="scaleToFill" id="P5D-RH-Ckg">
|
|
16
|
+
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
17
|
+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
18
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
|
19
|
+
</view>
|
|
20
|
+
</viewController>
|
|
21
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="mRF-bn-7H8" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
22
|
+
</objects>
|
|
23
|
+
<point key="canvasLocation" x="-224" y="-244"/>
|
|
24
|
+
</scene>
|
|
25
|
+
<!--Navigation Controller-->
|
|
26
|
+
<scene sceneID="cUi-kZ-frf">
|
|
27
|
+
<objects>
|
|
28
|
+
<navigationController storyboardIdentifier="sb_navigationControllerStoryboard" id="rS3-R9-Ivy" sceneMemberID="viewController">
|
|
29
|
+
<navigationBar key="navigationBar" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="yXu-0R-QUA">
|
|
30
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
31
|
+
</navigationBar>
|
|
32
|
+
<connections>
|
|
33
|
+
<segue destination="pGg-6v-bdr" kind="relationship" relationship="rootViewController" id="RxB-wf-QIq"/>
|
|
34
|
+
</connections>
|
|
35
|
+
</navigationController>
|
|
36
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="eq9-QA-ai8" sceneMemberID="firstResponder"/>
|
|
37
|
+
</objects>
|
|
38
|
+
<point key="canvasLocation" x="-1" y="64"/>
|
|
39
|
+
</scene>
|
|
40
|
+
<!--Master View Controller - Master-->
|
|
41
|
+
<scene sceneID="VgW-fR-Quf">
|
|
42
|
+
<objects>
|
|
43
|
+
<tableViewController storyboardIdentifier="sb_masterControllerStoryboard" title="Master" id="pGg-6v-bdr" customClass="SPWKMasterViewController" sceneMemberID="viewController">
|
|
44
|
+
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="mLL-gJ-YKr">
|
|
45
|
+
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
46
|
+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
47
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
48
|
+
<prototypes>
|
|
49
|
+
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="ruid_TableCell" textLabel="2pz-XF-uhl" style="IBUITableViewCellStyleDefault" id="m0d-ak-lc9">
|
|
50
|
+
<rect key="frame" x="0.0" y="86" width="320" height="44"/>
|
|
51
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
52
|
+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="m0d-ak-lc9" id="1Yu-d4-OdB">
|
|
53
|
+
<rect key="frame" x="0.0" y="0.0" width="287" height="43"/>
|
|
54
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
55
|
+
<subviews>
|
|
56
|
+
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2pz-XF-uhl">
|
|
57
|
+
<rect key="frame" x="15" y="0.0" width="270" height="43"/>
|
|
58
|
+
<autoresizingMask key="autoresizingMask"/>
|
|
59
|
+
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
|
|
60
|
+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
61
|
+
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
|
62
|
+
</label>
|
|
63
|
+
</subviews>
|
|
64
|
+
</tableViewCellContentView>
|
|
65
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
66
|
+
<connections>
|
|
67
|
+
<segue destination="Ah7-4n-0Wa" kind="push" identifier="seg_showDetailSegue" id="jUr-3t-vfg"/>
|
|
68
|
+
</connections>
|
|
69
|
+
</tableViewCell>
|
|
70
|
+
</prototypes>
|
|
71
|
+
<sections/>
|
|
72
|
+
<connections>
|
|
73
|
+
<outlet property="dataSource" destination="pGg-6v-bdr" id="P41-gY-KXY"/>
|
|
74
|
+
<outlet property="delegate" destination="pGg-6v-bdr" id="Y6K-Cp-Qkv"/>
|
|
75
|
+
</connections>
|
|
76
|
+
</tableView>
|
|
77
|
+
<navigationItem key="navigationItem" title="Master" id="tQt-TN-PWz"/>
|
|
78
|
+
</tableViewController>
|
|
79
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="6Cn-md-YlS" sceneMemberID="firstResponder"/>
|
|
80
|
+
</objects>
|
|
81
|
+
<point key="canvasLocation" x="459" y="64"/>
|
|
82
|
+
</scene>
|
|
83
|
+
<!--Detail View Controller - Detail-->
|
|
84
|
+
<scene sceneID="Cn3-H9-jdl">
|
|
85
|
+
<objects>
|
|
86
|
+
<viewController storyboardIdentifier="sb_detailControllerStoryboard" title="Detail" id="Ah7-4n-0Wa" customClass="SPWKDetailViewController" sceneMemberID="viewController">
|
|
87
|
+
<layoutGuides>
|
|
88
|
+
<viewControllerLayoutGuide type="top" id="gPs-rF-5IM"/>
|
|
89
|
+
<viewControllerLayoutGuide type="bottom" id="cfK-9t-i1J"/>
|
|
90
|
+
</layoutGuides>
|
|
91
|
+
<view key="view" contentMode="scaleToFill" id="MMQ-IT-qOo">
|
|
92
|
+
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
|
|
93
|
+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
94
|
+
<subviews>
|
|
95
|
+
<label clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Detail view content goes here" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Lei-5M-9Gs">
|
|
96
|
+
<rect key="frame" x="20" y="276" width="280" height="17"/>
|
|
97
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
98
|
+
<fontDescription key="fontDescription" type="system" size="system"/>
|
|
99
|
+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
|
100
|
+
<nil key="highlightedColor"/>
|
|
101
|
+
</label>
|
|
102
|
+
</subviews>
|
|
103
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
|
104
|
+
<constraints>
|
|
105
|
+
<constraint firstItem="Lei-5M-9Gs" firstAttribute="leading" secondItem="MMQ-IT-qOo" secondAttribute="leading" constant="20" symbolic="YES" id="62x-JV-TTJ"/>
|
|
106
|
+
<constraint firstItem="Lei-5M-9Gs" firstAttribute="centerY" secondItem="MMQ-IT-qOo" secondAttribute="centerY" id="JzS-HC-Rnl"/>
|
|
107
|
+
<constraint firstAttribute="trailing" secondItem="Lei-5M-9Gs" secondAttribute="trailing" constant="20" symbolic="YES" id="pXB-RP-Zz6"/>
|
|
108
|
+
</constraints>
|
|
109
|
+
</view>
|
|
110
|
+
<navigationItem key="navigationItem" title="Detail" id="cra-N8-TIN"/>
|
|
111
|
+
<connections>
|
|
112
|
+
<outlet property="detailDescriptionLabel" destination="Lei-5M-9Gs" id="sCT-F7-F6f"/>
|
|
113
|
+
</connections>
|
|
114
|
+
</viewController>
|
|
115
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="lrm-kH-fPn" sceneMemberID="firstResponder"/>
|
|
116
|
+
</objects>
|
|
117
|
+
<point key="canvasLocation" x="902" y="64"/>
|
|
118
|
+
</scene>
|
|
119
|
+
</scenes>
|
|
120
|
+
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
|
121
|
+
<simulatedStatusBarMetrics key="statusBar"/>
|
|
122
|
+
<simulatedOrientationMetrics key="orientation"/>
|
|
123
|
+
<simulatedScreenMetrics key="destination" type="retina4"/>
|
|
124
|
+
</simulatedMetricsContainer>
|
|
125
|
+
</document>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"images" : [
|
|
3
|
+
{
|
|
4
|
+
"idiom" : "iphone",
|
|
5
|
+
"size" : "29x29",
|
|
6
|
+
"scale" : "2x"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"idiom" : "iphone",
|
|
10
|
+
"size" : "40x40",
|
|
11
|
+
"scale" : "2x"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"idiom" : "iphone",
|
|
15
|
+
"size" : "60x60",
|
|
16
|
+
"scale" : "2x"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"idiom" : "ipad",
|
|
20
|
+
"size" : "29x29",
|
|
21
|
+
"scale" : "1x"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"idiom" : "ipad",
|
|
25
|
+
"size" : "29x29",
|
|
26
|
+
"scale" : "2x"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"idiom" : "ipad",
|
|
30
|
+
"size" : "40x40",
|
|
31
|
+
"scale" : "1x"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"idiom" : "ipad",
|
|
35
|
+
"size" : "40x40",
|
|
36
|
+
"scale" : "2x"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"idiom" : "ipad",
|
|
40
|
+
"size" : "76x76",
|
|
41
|
+
"scale" : "1x"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"idiom" : "ipad",
|
|
45
|
+
"size" : "76x76",
|
|
46
|
+
"scale" : "2x"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"info" : {
|
|
50
|
+
"version" : 1,
|
|
51
|
+
"author" : "xcode"
|
|
52
|
+
}
|
|
53
|
+
}
|