diff --git a/.codecov.yml b/.codecov.yml index 8874afe9..826ae53a 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,6 +1,8 @@ coverage: - ignore: - - "Carthage/**/*" - - "Example*/**/*" - - "*Tests/**/*" - - "Pods/**/*" + status: + patch: off +ignore: + - "Carthage/**/*" + - "Example*/**/*" + - "*Tests/**/*" + - "Pods/**/*" diff --git a/.jazzy.yml b/.jazzy.yml index 3a1e95c4..1db54e3c 100644 --- a/.jazzy.yml +++ b/.jazzy.yml @@ -5,7 +5,7 @@ github_url: https://github.com/bcylin/QuickTableViewController github_file_prefix: https://github.com/bcylin/QuickTableViewController/blob/develop xcodebuild_arguments: [-project, QuickTableViewController.xcodeproj, -scheme, QuickTableViewController-iOS] module: QuickTableViewController -module_version: 0.9.0 +module_version: 0.9.1 output: docs/output theme: fullwidth skip_undocumented: true diff --git a/.slather.yml b/.slather.yml deleted file mode 100644 index 310d06b9..00000000 --- a/.slather.yml +++ /dev/null @@ -1,12 +0,0 @@ -coverage_service: cobertura_xml -workspace: QuickTableViewController.xcworkspace -xcodeproj: QuickTableViewController.xcodeproj -scheme: QuickTableViewController-iOS -source_directory: Source -output_directory: test_output/xml_report -ignore: - - Carthage/* - - Example/* - - ExampleUITests/* - - QuickTableViewControllerTests/* - - Pods/* diff --git a/.swift-version b/.swift-version index c4e41f94..7d5c902e 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -4.0.3 +4.1 diff --git a/.swiftlint.yml b/.swiftlint.yml index 6818291c..5cad63dc 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -2,10 +2,9 @@ disabled_rules: - cyclomatic_complexity - force_cast - function_body_length - - valid_docs + - identifier_name - vertical_whitespace opt_in_rules: - - attributes - closure_end_indentation - closure_spacing - conditional_returns_on_newline @@ -29,10 +28,11 @@ opt_in_rules: - unneeded_parentheses_in_closure_argument - vertical_parameter_alignment_on_call included: - - Example - - ExampleUITests - - QuickTableViewControllerTests - - Source + - "Example-iOS" + - "Example-iOSUITests" + - "QuickTableViewController-iOS" + - "QuickTableViewController-iOSTests" + - "Source" excluded: - Carthage - Pods diff --git a/.travis.yml b/.travis.yml index 7cd637dc..67605cea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.2 +osx_image: xcode9.3beta matrix: include: - env: VERSION=latest @@ -16,9 +16,10 @@ install: before_script: - if [ -n "$DANGER_GITHUB_API_TOKEN" ]; then bundle exec danger; fi script: - - bundle exec rake ci:test[QuickTableViewController-iOS] + - bundle exec rake "ci:build[QuickTableViewController-iOS, 3.0]" + - bundle exec rake "ci:test[QuickTableViewController-iOS]" - bash <(curl -s https://codecov.io/bash) -cF ios -J "QuickTableViewController" - - bundle exec rake ci:test[Example-iOS] + - bundle exec rake "ci:test[Example-iOS]" - make -B carthage - make -B docs after_success: diff --git a/Brewfile b/Brewfile deleted file mode 100644 index 1e054346..00000000 --- a/Brewfile +++ /dev/null @@ -1,2 +0,0 @@ -brew "carthage" -brew "xcproj" diff --git a/CHANGELOG.md b/CHANGELOG.md index d1de2736..65f4081d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v0.9.1 + +#### Fixes + +* Fix the property setter in `RadioSection` and change `Row` to a class protocol, [#14](https://github.com/bcylin/QuickTableViewController/pull/14) by [@z3bi](https://github.com/z3bi) + ## v0.9.0 #### Breaking diff --git a/Example-iOS/Info.plist b/Example-iOS/Info.plist index 9b882036..f012d687 100644 --- a/Example-iOS/Info.plist +++ b/Example-iOS/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.9.0 + 0.9.1 CFBundleVersion 101 LSRequiresIPhoneOS diff --git a/Example-iOS/ViewControllers/CustomizationViewController.swift b/Example-iOS/ViewControllers/CustomizationViewController.swift index ba6d21d0..b6b23c44 100644 --- a/Example-iOS/ViewControllers/CustomizationViewController.swift +++ b/Example-iOS/ViewControllers/CustomizationViewController.swift @@ -56,30 +56,83 @@ internal final class CustomizationViewController: QuickTableViewController { debugging, Section(title: "Switch", rows: [ - SwitchRow(title: "SwitchRow\n", switchValue: true, action: weakify(self, type(of: self).log)), - CustomSwitchRow(title: "CustomSwitchRow\n", switchValue: false, action: weakify(self, type(of: self).log)) + SwitchRow( + title: "SwitchRow\n", + switchValue: true, + customization: set(label: "0-0"), + action: weakify(self, type(of: self).log) + ), + CustomSwitchRow( + title: "CustomSwitchRow\n", + switchValue: false, + customization: set(label: "0-1"), + action: weakify(self, type(of: self).log) + ) ]), Section(title: "Tap Action", rows: [ - TapActionRow(title: "TapActionRow\n", action: weakify(self, type(of: self).log)), - CustomTapActionRow(title: "CustomTapActionRow\n", action: weakify(self, type(of: self).log)) + TapActionRow( + title: "TapActionRow\n", + customization: set(label: "1-0"), + action: weakify(self, type(of: self).log) + ), + CustomTapActionRow( + title: "CustomTapActionRow\n", + customization: set(label: "1-1"), + action: weakify(self, type(of: self).log) + ) ]), Section(title: "Navigation", rows: [ - NavigationRow(title: "NavigationRow", subtitle: .none, action: weakify(self, type(of: self).log)), - NavigationRow(title: "NavigationRow", subtitle: .belowTitle(".subtitle"), action: weakify(self, type(of: self).log)), - CustomNavigationRow(title: "CustomNavigationRow", subtitle: .rightAligned(".value1"), action: weakify(self, type(of: self).log)), - CustomNavigationRow(title: "CustomNavigationRow", subtitle: .leftAligned(".value2"), action: weakify(self, type(of: self).log)) + NavigationRow( + title: "NavigationRow", + subtitle: .none, + customization: set(label: "2-0"), + action: weakify(self, type(of: self).log)), + NavigationRow( + title: "NavigationRow", + subtitle: .belowTitle(".subtitle"), + customization: set(label: "2-1"), + action: weakify(self, type(of: self).log) + ), + CustomNavigationRow( + title: "CustomNavigationRow", + subtitle: .rightAligned(".value1"), + customization: set(label: "2-2"), + action: weakify(self, type(of: self).log) + ), + CustomNavigationRow( + title: "CustomNavigationRow", + subtitle: .leftAligned(".value2"), + customization: set(label: "2-3"), + action: weakify(self, type(of: self).log) + ) ]), RadioSection(title: "Radio Buttons", options: [ - OptionRow(title: "OptionRow", isSelected: false, action: weakify(self, type(of: self).log)), - CustomOptionRow(title: "CustomOptionRow", isSelected: false, action: weakify(self, type(of: self).log)), - CustomOptionRow(title: "CustomOptionRow", isSelected: false, action: weakify(self, type(of: self).log)) + OptionRow( + title: "OptionRow", + isSelected: false, + customization: set(label: "3-0"), + action: weakify(self, type(of: self).log) + ), + CustomOptionRow( + title: "CustomOptionRow", + isSelected: false, + customization: set(label: "3-1"), + action: weakify(self, type(of: self).log) + ), + CustomOptionRow( + title: "CustomOptionRow", + isSelected: false, + customization: set(label: "3-2"), + action: weakify(self, type(of: self).log) + ) ]), Section(title: nil, rows: [ NavigationRow(title: "Customization closure", subtitle: .none, customization: { cell, _ in + cell.accessibilityLabel = "4-0" cell.accessoryView = UIImageView(image: #imageLiteral(resourceName: "iconmonstr-x-mark")) }) ]) @@ -96,6 +149,12 @@ internal final class CustomizationViewController: QuickTableViewController { // MARK: - Private + private func set(label: String) -> ((UITableViewCell, Row & RowStyle) -> Void) { + return { cell, _ in + cell.accessibilityLabel = label + } + } + private func log(_ sender: Row) { if let option = sender as? OptionRowCompatible, !option.isSelected { return diff --git a/Example-iOSUITests/ExampleUITests.swift b/Example-iOSUITests/ExampleUITests.swift index 6b971577..74a17b02 100644 --- a/Example-iOSUITests/ExampleUITests.swift +++ b/Example-iOSUITests/ExampleUITests.swift @@ -90,47 +90,47 @@ internal final class ExampleUITests: XCTestCase { let tables = XCUIApplication().tables let existance = NSPredicate(format: "exists == true") - tables.switches["SwitchRow "].tap() + tables.switches["0-0"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["CustomSwitchCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.switches["CustomSwitchRow "].tap() + tables.switches["0-1"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["SwitchCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["TapActionRow "].tap() + tables.cells["1-0"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["CustomTapActionCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["CustomTapActionRow "].tap() + tables.cells["1-1"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["TapActionCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["NavigationRow"].tap() + tables.cells["2-0"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["UITableViewCell.default"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["NavigationRow"].tap() + tables.cells["2-1"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["CustomCell.subtitle"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["CustomNavigationRow"].tap() + tables.cells["2-2"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["UITableViewCell.value1"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["CustomNavigationRow"].tap() + tables.cells["2-3"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["CustomCell.value2"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["OptionRow"].tap() + tables.cells["3-0"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["UITableViewCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["CustomOptionRow"].tap() + tables.cells["3-1"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["UITableViewCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) - tables.staticTexts["CustomOptionRow"].tap() + tables.cells["3-2"].tap() expectation(for: existance, evaluatedWith: tables.staticTexts["CustomOptionCell"], handler: nil) waitForExpectations(timeout: 5, handler: nil) } diff --git a/Example-iOSUITests/Info.plist b/Example-iOSUITests/Info.plist index bbe19c41..7206a5fa 100644 --- a/Example-iOSUITests/Info.plist +++ b/Example-iOSUITests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.9.0 + 0.9.1 CFBundleVersion 1 diff --git a/Makefile b/Makefile index 6bc78c9c..3feee46a 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ default: test test: - bundle exec rake 'ci:test[QuickTableViewController-iOS]' - bundle exec rake 'ci:test[Example-iOS]' + bundle exec rake "ci:test[QuickTableViewController-iOS]" + bundle exec rake "ci:test[Example-iOS]" ci-test: test make -B carthage @@ -21,7 +21,7 @@ carthage: set -o pipefail && carthage build --no-skip-current --verbose | bundle exec xcpretty -c coverage: - bundle exec slather coverage -s --input-format profdata --workspace QuickTableViewController.xcworkspace --scheme QuickTableViewController-iOS QuickTableViewController.xcodeproj + slather coverage -s --input-format profdata --workspace QuickTableViewController.xcworkspace --scheme QuickTableViewController-iOS QuickTableViewController.xcodeproj docs: test -d docs || git clone -b gh-pages --single-branch https://github.com/bcylin/QuickTableViewController.git docs @@ -31,8 +31,9 @@ docs: for file in "html" "css" "js" "json"; do \ echo "Cleaning whitespace in *."$$file ; \ - find docs/output -name "*."$$file -exec sed -E -i '' -e 's/[[:blank:]]*$///' {} \; ; \ + find docs/output -name "*."$$file -exec sed -E -i "" -e "s/[[:blank:]]*$$//" {} \; ; \ done + find docs -type f -execdir chmod 644 {} \; cp -rfv docs/output/* docs cd docs && \ diff --git a/QuickTableViewController-iOS/Info.plist b/QuickTableViewController-iOS/Info.plist index 76d3d186..70b8293c 100644 --- a/QuickTableViewController-iOS/Info.plist +++ b/QuickTableViewController-iOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.9.0 + 0.9.1 CFBundleSignature ???? CFBundleVersion diff --git a/QuickTableViewController-iOSTests/Info.plist b/QuickTableViewController-iOSTests/Info.plist index 0c4fbf23..a4d76f18 100644 --- a/QuickTableViewController-iOSTests/Info.plist +++ b/QuickTableViewController-iOSTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 0.9.0 + 0.9.1 CFBundleSignature ???? CFBundleVersion diff --git a/QuickTableViewController-iOSTests/Model/RadioSectionSpec.swift b/QuickTableViewController-iOSTests/Model/RadioSectionSpec.swift index 653abf8f..2a7e51ad 100644 --- a/QuickTableViewController-iOSTests/Model/RadioSectionSpec.swift +++ b/QuickTableViewController-iOSTests/Model/RadioSectionSpec.swift @@ -45,7 +45,66 @@ internal final class RadioSectionSpec: QuickSpec { } } - describe("always select one") { + describe("rows") { + context("getter") { + let options = [ + OptionRow(title: "0", isSelected: false, action: nil), + OptionRow(title: "1", isSelected: true, action: nil) + ] + let section = RadioSection(title: "", options: options) + + it("should return options as rows") { + expect(section.rows).to(beAKindOf([OptionRowCompatible].self)) + expect(section.rows as? [OptionRow]) == options + } + } + + context("setter") { + context("given empty array") { + let section = RadioSection(title: "", options: [ + OptionRow(title: "", isSelected: true, action: nil) + ]) + + it("should change rows") { + expect(section.rows).to(haveCount(1)) + section.rows = [] + expect(section.rows).to(beEmpty()) + } + } + + context("given incompatible type") { + let options = [OptionRow(title: "0", isSelected: false, action: nil)] + let section = RadioSection(title: "", options: options) + + it("should not change rows") { + expect(section.rows).to(haveCount(1)) + section.rows = [ + NavigationRow(title: "", subtitle: .none), + NavigationRow(title: "", subtitle: .none) + ] + expect(section.rows).to(haveCount(1)) + expect(section.rows as? [OptionRow]) == options + } + } + + context("given compatible type") { + let options = [ + OptionRow(title: "0", isSelected: false, action: nil), + OptionRow(title: "1", isSelected: true, action: nil) + ] + let section = RadioSection(title: "", options: []) + + it("should change rows") { + expect(section.rows).to(beEmpty()) + section.rows = options + expect(section.rows).to(haveCount(2)) + expect(section.rows as? [OptionRow]) == options + } + } + } + } + + describe("always selects one option") { context("when set to false") { let section = RadioSection(title: "title", options: [ OptionRow(title: "Option 1", isSelected: false, action: nil) diff --git a/QuickTableViewController-iOSTests/Row/NavigationRowSpec.swift b/QuickTableViewController-iOSTests/Row/NavigationRowSpec.swift index 8c0bcab2..63ead340 100644 --- a/QuickTableViewController-iOSTests/Row/NavigationRowSpec.swift +++ b/QuickTableViewController-iOSTests/Row/NavigationRowSpec.swift @@ -101,7 +101,7 @@ internal final class NavigationRowSpec: QuickSpec { context("different actions") { let f = NavigationRow(title: "Same", subtitle: .belowTitle("Same"), icon: .image(image), action: { _ in }) - it("should be equal regardless the actions attached") { + it("should be equal regardless of the actions attached") { expect(a) == f } } diff --git a/QuickTableViewController-iOSTests/Row/OptionRowSpec.swift b/QuickTableViewController-iOSTests/Row/OptionRowSpec.swift index a9b23517..1bc917f2 100644 --- a/QuickTableViewController-iOSTests/Row/OptionRowSpec.swift +++ b/QuickTableViewController-iOSTests/Row/OptionRowSpec.swift @@ -93,7 +93,7 @@ internal final class OptionRowSpec: QuickSpec { context("different actions") { let f = OptionRow(title: "Same", isSelected: true, action: { _ in }) - it("should be equal regardless the actions attached") { + it("should be equal regardless of the actions attached") { expect(a) == f } } diff --git a/QuickTableViewController-iOSTests/Row/SwitchRowSpec.swift b/QuickTableViewController-iOSTests/Row/SwitchRowSpec.swift index 40ece34c..de084785 100644 --- a/QuickTableViewController-iOSTests/Row/SwitchRowSpec.swift +++ b/QuickTableViewController-iOSTests/Row/SwitchRowSpec.swift @@ -82,7 +82,7 @@ internal final class SwitchRowSpec: QuickSpec { context("different actions") { let f = SwitchRow(title: "Same", switchValue: true, action: { _ in }) - it("should be equal regardless the actions attached") { + it("should be equal regardless of the actions attached") { expect(a) == f } } diff --git a/QuickTableViewController-iOSTests/Row/TapActionRowSpec.swift b/QuickTableViewController-iOSTests/Row/TapActionRowSpec.swift index 88f66d0b..f6678e30 100644 --- a/QuickTableViewController-iOSTests/Row/TapActionRowSpec.swift +++ b/QuickTableViewController-iOSTests/Row/TapActionRowSpec.swift @@ -67,7 +67,7 @@ internal final class TapActionRowSpec: QuickSpec { context("different actions") { let d = TapActionRow(title: "Same", action: { _ in }) - it("should be equal regardless the actions attached") { + it("should be equal regardless of the actions attached") { expect(a) == d } } diff --git a/QuickTableViewController-iOSTests/ViewController/QuickTableViewControllerSpec.swift b/QuickTableViewController-iOSTests/ViewController/QuickTableViewControllerSpec.swift index 8da654ad..1c1bde67 100644 --- a/QuickTableViewController-iOSTests/ViewController/QuickTableViewControllerSpec.swift +++ b/QuickTableViewController-iOSTests/ViewController/QuickTableViewControllerSpec.swift @@ -44,7 +44,7 @@ internal final class QuickTableViewControllerSpec: QuickSpec { // MARK: - UIViewController describe("lifecycle") { - var tableView: UITableView! + var tableView: UITableView! // swiftlint:disable:this implicitly_unwrapped_optional it("should set up table view") { let controller = QuickTableViewController(style: .grouped) diff --git a/QuickTableViewController.podspec b/QuickTableViewController.podspec index 6f99d539..90ae284d 100644 --- a/QuickTableViewController.podspec +++ b/QuickTableViewController.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "QuickTableViewController" - s.version = "0.9.0" + s.version = "0.9.1" s.summary = "A simple way to create a UITableView for settings." s.screenshots = "https://bcylin.github.io/QuickTableViewController/img/screenshot-1.png", "https://bcylin.github.io/QuickTableViewController/img/screenshot-2.png" diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index e8b88c66..24f6185c 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -671,7 +671,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "${PODS_ROOT}/SwiftLint/swiftlint"; + shellScript = "${PODS_ROOT}/SwiftLint/swiftlint --config .swiftlint.yml"; }; C57ED08E45623928E1F82168 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; diff --git a/README.md b/README.md index dde583c2..1585e46a 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,6 @@ NavigationRow(title: "UITableViewCellStyle", subtitle: .leftAligned(".value2")) #### Images * Images in table view cells can be set by specifying the `icon` of each row. -* The `Icon` carries info about images for both normal and highlighted states. * Table view cells in `UITableViewCellStyle.value2` will not show the image view. ```swift @@ -91,8 +90,8 @@ NavigationRow(title: "Cell with image", subtitle: .none, icon: icon) #### Disclosure Indicator -* A `NavigationRow` with an `action` will be displayed in a table view cell whose `accessoryType` is `.disclosureIndicator`. -* The `action` will be invoked when the related table view cell is selected. +* A `NavigationRow` with an `action` will be displayed in a table view cell with `.disclosureIndicator`. +* The `action` will be invoked when the table view cell is selected. ```swift NavigationRow(title: "Navigation cell", subtitle: .none, action: { (sender: Row) in }) @@ -111,8 +110,8 @@ SwitchRow(title: "Switch", switchValue: true, action: { (sender: Row) in }), ### TapActionRow * A `TapActionRow` is representing a button-like table view cell. -* The `action` will be invoked when the related table view cell is selected. -* `Icon` is disabled in `TapActionRow`. +* The `action` will be invoked when the table view cell is selected. +* The icon and subtitle are disabled in `TapActionRow`. ```swift TapActionRow(title: "Tap action", action: { (sender: Row) in }) @@ -120,17 +119,16 @@ TapActionRow(title: "Tap action", action: { (sender: Row) in }) ### OptionRow & RadioSection -* An `OptionRow` is representing a selectable table view cell. -* When the row `isSelected`, the table view cell shows `.checkmark` as its `accessoryType`. -* The `action` will be invoked when the selection is toggled. +* An `OptionRow` is representing a table view cell with `.checkmark`. +* The `action` will be invoked when the selected state is toggled. * The subtitle is disabled in `OptionRow`. ```swift OptionRow(title: "Option", isSelected: true, action: { (sender: Row) in }) ``` -* `OptionRow` can be used with or without `RadioSection`, which allows only one selection. -* `RadioSection` allows all options unselected by default. Set `alwaysSelectsOneOption` to true to keep one option selected. +* `OptionRow` can be used with or without `RadioSection`, which allows only one selected option. +* All options can be unselected in `RadioSection` by default. Setting `alwaysSelectsOneOption` to true will keep one of the options selected. ## Customization @@ -196,17 +194,17 @@ protocol RowStyle { } ``` -The `customize` closure overwrites the `Configurable` changes. +The `customize` closure overwrites the `Configurable` setup. ### UIAppearance -As discussed in issue [#12](https://github.com/bcylin/QuickTableViewController/issues/12), UIAppearance customization works when the cell is dequeued from the storyboard. One way to work around this is to register nib objects to the table view. Check out [AppearanceViewController](https://github.com/bcylin/QuickTableViewController/blob/develop/Example/ViewControllers/AppearanceViewController.swift) for the setups. +As discussed in issue [#12](https://github.com/bcylin/QuickTableViewController/issues/12), UIAppearance customization works when the cell is dequeued from the storyboard. One way to work around this is to register nib objects to the table view. Check out [AppearanceViewController](https://github.com/bcylin/QuickTableViewController/blob/develop/Example/ViewControllers/AppearanceViewController.swift) for the setup. ## Limitation > When to use **QuickTableViewController**? -QuickTableViewController is good for presenting static table contents, where the sections and rows don't need to change dynamically after `viewDidLoad`. +QuickTableViewController is good for presenting static table contents, where the sections and rows don't change dynamically after `viewDidLoad`. It's possible to update the table contents by replacing a specific section or row. Using different styles on each row requires additional configuration as described in the [Customization](#customization) section. diff --git a/Rakefile b/Rakefile index c901aac4..3512587f 100644 --- a/Rakefile +++ b/Rakefile @@ -8,29 +8,30 @@ namespace :ci do %(-scheme #{params[:scheme]}), %(-sdk iphonesimulator), %(-destination "name=iPhone 7,OS=latest"), + params[:swift_version] ? %(SWIFT_VERSION=#{params[:swift_version]}) : nil, %(#{params[:action]} | xcpretty -c && exit ${PIPESTATUS[0]}) - ].join " " + ].reject(&:nil?).join " " end - desc "Build a target of specified scheme" - task :build, [:scheme] do |t, args| + desc "Build a target with a specified scheme and Swift version" + task :build, [:scheme, :swift_version] do |t, args| unless args[:scheme] - puts "usage: rake ci:build[scheme]" + puts "Usage: rake 'ci:build[scheme, swift_version]'" next end - sh xcodebuild(scheme: args[:scheme], action: "clean build") + sh xcodebuild(args.to_hash.merge(action: "clean build")) exit $?.exitstatus if not $?.success? end - desc "Run tests with a specified scheme" - task :test, [:scheme] do |t, args| + desc "Run tests with a specified scheme and Swift version" + task :test, [:scheme, :swift_version] do |t, args| unless args[:scheme] - puts "Usage: rake ci:test[scheme]" + puts "Usage: rake 'ci:test[scheme, swift_version]'" next end - sh xcodebuild(scheme: args[:scheme], action: "-enableCodeCoverage YES clean test") + sh xcodebuild(args.to_hash.merge(action: "-enableCodeCoverage YES clean test")) exit $?.exitstatus if not $?.success? end end diff --git a/Source/Model/RadioSection.swift b/Source/Model/RadioSection.swift index d09228f5..f8a76de5 100644 --- a/Source/Model/RadioSection.swift +++ b/Source/Model/RadioSection.swift @@ -49,7 +49,7 @@ open class RadioSection: Section { return options } set { - options = rows as? [OptionRowCompatible] ?? options + options = newValue as? [OptionRowCompatible] ?? options } } diff --git a/Source/Protocol/Row.swift b/Source/Protocol/Row.swift index 236b9d2f..1a018f58 100644 --- a/Source/Protocol/Row.swift +++ b/Source/Protocol/Row.swift @@ -27,7 +27,7 @@ import Foundation /// Any type that conforms to this protocol is capable of representing a row in a table view. -public protocol Row { +public protocol Row: class { /// The title text of the row. var title: String { get } @@ -39,13 +39,3 @@ public protocol Row { var action: ((Row) -> Void)? { get } } - - -extension Row { - - /// Returns true iff `lhs` and `rhs` have equal titles and subtitles. - public static func == (lhs: Self, rhs: Self) -> Bool { - return lhs.title == rhs.title && lhs.subtitle == rhs.subtitle - } - -} diff --git a/Source/Protocol/RowCompatible.swift b/Source/Protocol/RowCompatible.swift index 6a28c504..95826f5c 100644 --- a/Source/Protocol/RowCompatible.swift +++ b/Source/Protocol/RowCompatible.swift @@ -35,14 +35,14 @@ public protocol TapActionRowCompatible: Row, RowStyle {} /// This protocol defines the compatible interface of an `OptionRow` regardless of its associated cell type. -public protocol OptionRowCompatible: class, Row, RowStyle { +public protocol OptionRowCompatible: Row, RowStyle { /// The state of selection. var isSelected: Bool { get set } } /// This protocol defines the compatible interface of a `SwitchRow` regardless of its associated cell type. -public protocol SwitchRowCompatible: class, Row, RowStyle { +public protocol SwitchRowCompatible: Row, RowStyle { /// The state of the switch. var switchValue: Bool { get set } } diff --git a/Source/Rows/TapActionRow.swift b/Source/Rows/TapActionRow.swift index 50a5bf2d..e8aaaf01 100644 --- a/Source/Rows/TapActionRow.swift +++ b/Source/Rows/TapActionRow.swift @@ -79,4 +79,11 @@ open class TapActionRow: TapActionRowCompatible, Equatable { /// The additional customization during cell configuration. public let customize: ((UITableViewCell, Row & RowStyle) -> Void)? + // MARK: - Equatable + + /// Returns true iff `lhs` and `rhs` have equal titles and subtitles. + public static func == (lhs: TapActionRow, rhs: TapActionRow) -> Bool { + return lhs.title == rhs.title && lhs.subtitle == rhs.subtitle + } + }