diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..c929601 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,20 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Project** +This repo contains many projects, please state which project this issue is for. + +**Environment** +Please include at least the following details: +- Xcode version +- iOS version +- Device or simulator used to reproduce the bug + +**Describe the bug** +A clear and concise description of what the bug is. diff --git a/AdaptType/AdaptType.xcodeproj/project.pbxproj b/AdaptType/AdaptType.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5390100 --- /dev/null +++ b/AdaptType/AdaptType.xcodeproj/project.pbxproj @@ -0,0 +1,344 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 53ED33A52165588D005E895D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ED33A42165588D005E895D /* AppDelegate.swift */; }; + 53ED33A72165588D005E895D /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ED33A62165588D005E895D /* SettingsViewController.swift */; }; + 53ED33AA2165588D005E895D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53ED33A82165588D005E895D /* Main.storyboard */; }; + 53ED33AC2165588E005E895D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53ED33AB2165588E005E895D /* Assets.xcassets */; }; + 53ED33AF2165588E005E895D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53ED33AD2165588E005E895D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 5379191D216B8B1F007E5997 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53ED33A12165588D005E895D /* AdaptType.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdaptType.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53ED33A42165588D005E895D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53ED33A62165588D005E895D /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; + 53ED33A92165588D005E895D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53ED33AB2165588E005E895D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53ED33AE2165588E005E895D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53ED33B02165588E005E895D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53ED339E2165588D005E895D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53ED33982165588D005E895D = { + isa = PBXGroup; + children = ( + 5379191D216B8B1F007E5997 /* README.md */, + 53ED33A32165588D005E895D /* AdaptType */, + 53ED33A22165588D005E895D /* Products */, + ); + sourceTree = ""; + }; + 53ED33A22165588D005E895D /* Products */ = { + isa = PBXGroup; + children = ( + 53ED33A12165588D005E895D /* AdaptType.app */, + ); + name = Products; + sourceTree = ""; + }; + 53ED33A32165588D005E895D /* AdaptType */ = { + isa = PBXGroup; + children = ( + 53ED33A42165588D005E895D /* AppDelegate.swift */, + 53ED33A62165588D005E895D /* SettingsViewController.swift */, + 53ED33A82165588D005E895D /* Main.storyboard */, + 53ED33AB2165588E005E895D /* Assets.xcassets */, + 53ED33AD2165588E005E895D /* LaunchScreen.storyboard */, + 53ED33B02165588E005E895D /* Info.plist */, + ); + path = AdaptType; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53ED33A02165588D005E895D /* AdaptType */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53ED33B32165588E005E895D /* Build configuration list for PBXNativeTarget "AdaptType" */; + buildPhases = ( + 53ED339D2165588D005E895D /* Sources */, + 53ED339E2165588D005E895D /* Frameworks */, + 53ED339F2165588D005E895D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = AdaptType; + productName = AdaptType; + productReference = 53ED33A12165588D005E895D /* AdaptType.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53ED33992165588D005E895D /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1000; + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53ED33A02165588D005E895D = { + CreatedOnToolsVersion = 10.0; + LastSwiftMigration = 1120; + }; + }; + }; + buildConfigurationList = 53ED339C2165588D005E895D /* Build configuration list for PBXProject "AdaptType" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53ED33982165588D005E895D; + productRefGroup = 53ED33A22165588D005E895D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53ED33A02165588D005E895D /* AdaptType */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53ED339F2165588D005E895D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53ED33AF2165588E005E895D /* LaunchScreen.storyboard in Resources */, + 53ED33AC2165588E005E895D /* Assets.xcassets in Resources */, + 53ED33AA2165588D005E895D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53ED339D2165588D005E895D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53ED33A72165588D005E895D /* SettingsViewController.swift in Sources */, + 53ED33A52165588D005E895D /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53ED33A82165588D005E895D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53ED33A92165588D005E895D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53ED33AD2165588E005E895D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53ED33AE2165588E005E895D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53ED33B12165588E005E895D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53ED33B22165588E005E895D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53ED33B42165588E005E895D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = AdaptType/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AdaptType; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53ED33B52165588E005E895D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = AdaptType/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AdaptType; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53ED339C2165588D005E895D /* Build configuration list for PBXProject "AdaptType" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53ED33B12165588E005E895D /* Debug */, + 53ED33B22165588E005E895D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53ED33B32165588E005E895D /* Build configuration list for PBXNativeTarget "AdaptType" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53ED33B42165588E005E895D /* Debug */, + 53ED33B52165588E005E895D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53ED33992165588D005E895D /* Project object */; +} diff --git a/AdaptType/AdaptType/AppDelegate.swift b/AdaptType/AdaptType/AppDelegate.swift new file mode 100644 index 0000000..85205c0 --- /dev/null +++ b/AdaptType/AdaptType/AppDelegate.swift @@ -0,0 +1,34 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/AdaptType/AdaptType/Assets.xcassets/AppIcon.appiconset/Contents.json b/AdaptType/AdaptType/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/AdaptType/AdaptType/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RemindMe/RemindMe/Images.xcassets/Contents.json b/AdaptType/AdaptType/Assets.xcassets/Contents.json similarity index 100% rename from RemindMe/RemindMe/Images.xcassets/Contents.json rename to AdaptType/AdaptType/Assets.xcassets/Contents.json diff --git a/AdaptType/AdaptType/Base.lproj/LaunchScreen.storyboard b/AdaptType/AdaptType/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/AdaptType/AdaptType/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AdaptType/AdaptType/Base.lproj/Main.storyboard b/AdaptType/AdaptType/Base.lproj/Main.storyboard new file mode 100644 index 0000000..8303d01 --- /dev/null +++ b/AdaptType/AdaptType/Base.lproj/Main.storyboard @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AdaptType/AdaptType/Info.plist b/AdaptType/AdaptType/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/AdaptType/AdaptType/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/AdaptType/AdaptType/SettingsViewController.swift b/AdaptType/AdaptType/SettingsViewController.swift new file mode 100644 index 0000000..c2a4310 --- /dev/null +++ b/AdaptType/AdaptType/SettingsViewController.swift @@ -0,0 +1,76 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class SettingsViewController: UIViewController { + @IBOutlet var stackView: UIStackView! + + let backgroundView: UIView = { + let view = UIView() + view.backgroundColor = .white + view.translatesAutoresizingMaskIntoConstraints = false + return view + }() + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + configureView(for: traitCollection) + } + + private func setupView() { + stackView.insertSubview(backgroundView, at: 0) + NSLayoutConstraint.activate([ + backgroundView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor), + backgroundView.topAnchor.constraint(equalTo: stackView.topAnchor), + backgroundView.trailingAnchor.constraint(equalTo: stackView.trailingAnchor), + backgroundView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor) + ]) + } +} + +extension SettingsViewController { + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory { + configureView(for: traitCollection) + } + } + + private func configureView(for traitCollection: UITraitCollection) { + let contentSize = traitCollection.preferredContentSizeCategory + if contentSize.isAccessibilityCategory { + stackView.axis = .vertical + stackView.alignment = .leading + } else { + stackView.axis = .horizontal + stackView.alignment = .center + } + } +} diff --git a/AdaptType/README.md b/AdaptType/README.md new file mode 100644 index 0000000..f9c4b69 --- /dev/null +++ b/AdaptType/README.md @@ -0,0 +1,5 @@ +# Making Space For Dynamic Type + +A case study that looks at how to implement the Larger Text screen from the Apple Settings App. See the following post for details: + ++ [Making Space For Dynamic Type](https://useyourloaf.com/blog/making-space-for-dynamic-type/) diff --git a/AdaptivePopover/AdaptivePopover.xcodeproj/project.pbxproj b/AdaptivePopover/AdaptivePopover.xcodeproj/project.pbxproj index e6de0ae..e582a0a 100644 --- a/AdaptivePopover/AdaptivePopover.xcodeproj/project.pbxproj +++ b/AdaptivePopover/AdaptivePopover.xcodeproj/project.pbxproj @@ -18,17 +18,17 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 53A8BF831C0CE6F3003C9B46 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; 53BC63AA1C0A57E4009BFDDF /* AdaptivePopover.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdaptivePopover.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53BC63AD1C0A57E4009BFDDF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 53BC63B21C0A57E4009BFDDF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 53BC63B41C0A57E4009BFDDF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 53BC63B71C0A57E4009BFDDF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53BC63B91C0A57E4009BFDDF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53BC63BF1C0A591A009BFDDF /* RootViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = ""; }; 53BC63C11C0A596C009BFDDF /* SimpleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleViewController.swift; sourceTree = ""; }; 53BC63C31C0A5F59009BFDDF /* SimpleTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleTableViewController.swift; sourceTree = ""; }; 53BC63C51C0A5F72009BFDDF /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; + 53FFA91A23C768C000EAFE01 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53FFA91D23C76E7D00EAFE01 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53FFA91E23C76E7D00EAFE01 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -45,7 +45,7 @@ 53BC63A11C0A57E4009BFDDF = { isa = PBXGroup; children = ( - 53A8BF831C0CE6F3003C9B46 /* README */, + 53FFA91A23C768C000EAFE01 /* README.md */, 53BC63AC1C0A57E4009BFDDF /* AdaptivePopover */, 53BC63AB1C0A57E4009BFDDF /* Products */, ); @@ -102,17 +102,18 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 0710; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53BC63A91C0A57E4009BFDDF = { CreatedOnToolsVersion = 7.1.1; + DevelopmentTeam = LCC2J94N44; }; }; }; buildConfigurationList = 53BC63A51C0A57E4009BFDDF /* Build configuration list for PBXProject "AdaptivePopover" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -160,7 +161,7 @@ 53BC63B11C0A57E4009BFDDF /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - 53BC63B21C0A57E4009BFDDF /* Base */, + 53FFA91D23C76E7D00EAFE01 /* Base */, ); name = Main.storyboard; sourceTree = ""; @@ -168,7 +169,7 @@ 53BC63B61C0A57E4009BFDDF /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - 53BC63B71C0A57E4009BFDDF /* Base */, + 53FFA91E23C76E7D00EAFE01 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; @@ -180,17 +181,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -217,6 +229,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -225,17 +238,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -254,6 +278,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -263,8 +289,11 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AdaptivePopover/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MARKETING_VERSION = 2.0; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AdaptivePopover; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -274,8 +303,11 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AdaptivePopover/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MARKETING_VERSION = 2.0; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AdaptivePopover; PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/AdaptivePopover/AdaptivePopover/Base.lproj/LaunchScreen.storyboard b/AdaptivePopover/AdaptivePopover/Base.lproj/LaunchScreen.storyboard index f9b6409..bfec1a2 100644 --- a/AdaptivePopover/AdaptivePopover/Base.lproj/LaunchScreen.storyboard +++ b/AdaptivePopover/AdaptivePopover/Base.lproj/LaunchScreen.storyboard @@ -1,45 +1,41 @@ - - + + + - + + + - - - - - + - + - - - + - + + @@ -53,9 +49,8 @@ - + - diff --git a/AdaptivePopover/AdaptivePopover/Base.lproj/Main.storyboard b/AdaptivePopover/AdaptivePopover/Base.lproj/Main.storyboard index b02fbee..e1d5a06 100644 --- a/AdaptivePopover/AdaptivePopover/Base.lproj/Main.storyboard +++ b/AdaptivePopover/AdaptivePopover/Base.lproj/Main.storyboard @@ -1,28 +1,27 @@ - - + + + - + + + - - - - - + - + - - - + - + + @@ -65,64 +63,55 @@ - - - - - + - - + - + + - + - + - - + - + - + - - @@ -146,28 +135,23 @@ - - - - - + - - + - + + @@ -183,9 +167,8 @@ - + - @@ -194,7 +177,7 @@ - + @@ -202,9 +185,8 @@ - + - diff --git a/AdaptivePopover/AdaptivePopover/Info.plist b/AdaptivePopover/AdaptivePopover/Info.plist index 40c6215..26e2b70 100644 --- a/AdaptivePopover/AdaptivePopover/Info.plist +++ b/AdaptivePopover/AdaptivePopover/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/AdaptivePopover/AdaptivePopover/RootViewController.swift b/AdaptivePopover/AdaptivePopover/RootViewController.swift index e73020f..3afb47c 100644 --- a/AdaptivePopover/AdaptivePopover/RootViewController.swift +++ b/AdaptivePopover/AdaptivePopover/RootViewController.swift @@ -33,75 +33,72 @@ import UIKit -class RootViewController: UIViewController { +final class RootViewController: UIViewController { + @IBOutlet var simpleButton: UIButton! + @IBOutlet var embeddedButton: UIButton! - @IBOutlet weak var simpleButton: UIButton! - @IBOutlet weak var embeddedButton: UIButton! - - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { switch segue.identifier { case "SimpleSegue"?: - let simplePPC = segue.destinationViewController.popoverPresentationController + let simplePPC = segue.destination.popoverPresentationController simplePPC?.delegate = self simplePPC?.sourceView = simpleButton simplePPC?.sourceRect = simpleButton.bounds case "EmbeddedSegue"?: - let embeddedPPC = segue.destinationViewController.popoverPresentationController + let embeddedPPC = segue.destination.popoverPresentationController embeddedPPC?.delegate = self embeddedPPC?.sourceView = embeddedButton embeddedPPC?.sourceRect = embeddedButton.bounds default: - fatalError("Unknown segue: \(segue.identifier)") + fatalError("Unknown segue: \(segue.identifier ?? "Unknown")") } } } - // MARK: UIPopoverPresentationControllerDelegate + extension RootViewController: UIPopoverPresentationControllerDelegate { - // In modal presentation we need to add a button to our popover // to allow it to be dismissed. Handle the situation where // our popover may be embedded in a navigation controller - - func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? { - guard style != .None else { + + func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? { + if style == .none { return controller.presentedViewController } - - if let navController = controller.presentedViewController as? UINavigationController { - addDismissButton(navController) - return navController - } else { - let navController = UINavigationController.init(rootViewController: controller.presentedViewController) - addDismissButton(navController) - return navController - } + + let navigationController: UINavigationController = { + guard let navigationController = controller.presentedViewController as? UINavigationController else { + return UINavigationController(rootViewController: controller.presentedViewController) + } + return navigationController + }() + + addDismissButton(navigationController) + return navigationController } - + // Check for when we present in a non modal style and remove the // the dismiss button from the navigation bar. - - func presentationController(presentationController: UIPresentationController, willPresentWithAdaptiveStyle style: UIModalPresentationStyle, transitionCoordinator: UIViewControllerTransitionCoordinator?) { - if style == .None { - if let navController = presentationController.presentedViewController as? UINavigationController { - removeDismissButton(navController) - } + + func presentationController(_ presentationController: UIPresentationController, willPresentWithAdaptiveStyle style: UIModalPresentationStyle, transitionCoordinator: UIViewControllerTransitionCoordinator?) { + if style == .none, + let navController = presentationController.presentedViewController as? UINavigationController { + removeDismissButton(navController) } } - - func didDismissPresentedView() { - presentedViewController?.dismissViewControllerAnimated(true, completion: nil) + + @objc private func didDismissPresentedView() { + presentedViewController?.dismiss(animated: true, completion: nil) } - - private func addDismissButton(navigationController: UINavigationController) { + + private func addDismissButton(_ navigationController: UINavigationController) { let rootViewController = navigationController.viewControllers[0] - rootViewController.navigationItem.leftBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Done, - target: self, action: "didDismissPresentedView") + rootViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(didDismissPresentedView)) } - - private func removeDismissButton(navigationController: UINavigationController) { + + private func removeDismissButton(_ navigationController: UINavigationController) { let rootViewController = navigationController.viewControllers[0] - rootViewController.navigationItem.leftBarButtonItem = nil; + rootViewController.navigationItem.leftBarButtonItem = nil } } diff --git a/AdaptivePopover/AdaptivePopover/SimpleTableViewController.swift b/AdaptivePopover/AdaptivePopover/SimpleTableViewController.swift index 68f8ac9..a41c123 100644 --- a/AdaptivePopover/AdaptivePopover/SimpleTableViewController.swift +++ b/AdaptivePopover/AdaptivePopover/SimpleTableViewController.swift @@ -33,32 +33,30 @@ import UIKit -class SimpleTableViewController: UIViewController { - +final class SimpleTableViewController: UIViewController { @IBOutlet var tableView: UITableView! - - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { - if segue.identifier == "ShowDetailSegue" { - if let indexPath = tableView.indexPathForCell(sender as! UITableViewCell) { - if let detailViewController = segue.destinationViewController as? DetailViewController { - detailViewController.detailText = "Item \(indexPath.row)" - } - } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "ShowDetailSegue", + let sender = sender as? UITableViewCell, + let indexPath = tableView.indexPath(for: sender), + let detailViewController = segue.destination as? DetailViewController { + detailViewController.detailText = "Item \(indexPath.row)" } } } extension SimpleTableViewController: UITableViewDataSource { - func numberOfSectionsInTableView(tableView: UITableView) -> Int { + func numberOfSections(in tableView: UITableView) -> Int { return 1 } - - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } - - func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCellWithIdentifier("SimpleCell", forIndexPath: indexPath) + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "SimpleCell", for: indexPath) cell.textLabel?.text = "Item \(indexPath.row)" return cell } diff --git a/AdaptivePopover/README b/AdaptivePopover/README deleted file mode 100644 index c60fb7d..0000000 --- a/AdaptivePopover/README +++ /dev/null @@ -1,11 +0,0 @@ -======================================================================= -AdaptivePopover - Adapting popovers to size classes - -Version 1.0 30 Nov 2015 Initial version. -======================================================================= - -Example of how to use the UIPopoverPresentationController delegate -protocol to adapt a popover to compact size classes. See the following -post for further details: - -http://useyourloaf.com/blog/making-popovers-adapt-to-size-classes.html diff --git a/AdaptivePopover/README.md b/AdaptivePopover/README.md new file mode 100644 index 0000000..2f2a4be --- /dev/null +++ b/AdaptivePopover/README.md @@ -0,0 +1,10 @@ +# AdaptivePopover - Adapting popovers to size classes + ++ Version 2.0 09 Jan 2020 Updated for Xcode 11, Swift 5 and iOS 13 ++ Version 1.0 30 Nov 2015 Initial version. + +Example of how to use the `UIPopoverPresentationController` delegate +protocol to adapt a popover to compact size classes. See the following +post for further details: + ++ [Making Popovers Adapt to Size Classes](https://useyourloaf.com/blog/making-popovers-adapt-to-size-classes/) diff --git a/AirPrinter/AirPrinter/WebViewController.xib b/AirPrinter/AirPrinter/WebViewController.xib deleted file mode 100644 index b28d757..0000000 --- a/AirPrinter/AirPrinter/WebViewController.xib +++ /dev/null @@ -1,177 +0,0 @@ - - - - 1056 - 11A511 - 1617 - 1138 - 566.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 534 - - - YES - IBProxyObject - IBUIWebView - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - - - YES - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 292 - {240, 128} - - - _NS:667 - - 1 - MSAxIDEAA - - IBCocoaTouchFramework - YES - - - - - YES - - - webView - - - - 5 - - - - delegate - - - - 6 - - - - view - - - - 7 - - - - - YES - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - Web View - - - - - YES - - YES - -1.CustomClassName - -1.IBPluginDependency - -2.CustomClassName - -2.IBPluginDependency - 4.IBPluginDependency - - - YES - WebViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - - - - YES - - - - - 7 - - - - YES - - WebViewController - UIViewController - - webView - UIWebView - - - webView - - webView - UIWebView - - - - IBProjectSource - ./Classes/WebViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - 3 - 534 - - diff --git a/AirPrinter/AirPrinter/en.lproj/MainWindow.xib b/AirPrinter/AirPrinter/en.lproj/MainWindow.xib deleted file mode 100644 index ba438d9..0000000 --- a/AirPrinter/AirPrinter/en.lproj/MainWindow.xib +++ /dev/null @@ -1,331 +0,0 @@ - - - - 1024 - 11A511 - 1617 - 1138 - 566.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 534 - - - YES - IBProxyObject - IBUINavigationController - IBUIViewController - IBUICustomObject - IBUIBarButtonItem - IBUIWindow - IBUINavigationBar - IBUINavigationItem - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - - - YES - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - IBCocoaTouchFramework - - - - 1316 - - {320, 480} - - - - 1 - MSAxIDEAA - - NO - NO - - IBCocoaTouchFramework - YES - - - - - 1 - 1 - - IBCocoaTouchFramework - NO - - - 256 - {0, 0} - NO - YES - YES - IBCocoaTouchFramework - - - YES - - - - AirPrinter - - Home - IBCocoaTouchFramework - 1 - - IBCocoaTouchFramework - - - RootViewController - - - 1 - 1 - - IBCocoaTouchFramework - NO - - - - - - - YES - - - delegate - - - - 4 - - - - window - - - - 5 - - - - navigationController - - - - 15 - - - - - YES - - 0 - - - - - - 2 - - - YES - - - - - -1 - - - File's Owner - - - 3 - - - - - -2 - - - - - 9 - - - YES - - - - - - - 11 - - - - - 13 - - - YES - - - - - - 14 - - - YES - - - - - - 17 - - - - - - - YES - - YES - -1.CustomClassName - -1.IBPluginDependency - -2.CustomClassName - -2.IBPluginDependency - 11.IBPluginDependency - 13.CustomClassName - 13.IBPluginDependency - 14.IBPluginDependency - 17.IBPluginDependency - 2.IBAttributePlaceholdersKey - 2.IBPluginDependency - 3.CustomClassName - 3.IBPluginDependency - 9.IBPluginDependency - - - YES - UIApplication - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - RootViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - YES - - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - AirPrinterAppDelegate - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - - - - YES - - - - - 17 - - - - YES - - AirPrinterAppDelegate - NSObject - - YES - - YES - navigationController - window - - - YES - UINavigationController - UIWindow - - - - YES - - YES - navigationController - window - - - YES - - navigationController - UINavigationController - - - window - UIWindow - - - - - IBProjectSource - ./Classes/AirPrinterAppDelegate.h - - - - RootViewController - UIViewController - - IBProjectSource - ./Classes/RootViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - 3 - 534 - - diff --git a/AirPrinter/AirPrinter/en.lproj/RootViewController.xib b/AirPrinter/AirPrinter/en.lproj/RootViewController.xib deleted file mode 100644 index 6768cbf..0000000 --- a/AirPrinter/AirPrinter/en.lproj/RootViewController.xib +++ /dev/null @@ -1,170 +0,0 @@ - - - - 784 - 11A511 - 1617 - 1138 - 566.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 534 - - - IBProxyObject - IBUIView - IBUITextField - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 292 - - - - 290 - {{20, 71}, {280, 31}} - - - - _NS:294 - NO - YES - IBCocoaTouchFramework - 0 - http://apple.com - 3 - Enter a web site URL - - 3 - MAA - - 2 - - - YES - 17 - - 1 - 3 - 1 - YES - IBCocoaTouchFramework - - 1 - - - {320, 460} - - - - _NS:180 - - 1 - MC41IDAgMC41AA - - IBCocoaTouchFramework - - - - - - - view - - - - 10 - - - - delegate - - - - 11 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 6 - - - - - - - - 8 - - - - - - - RootViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 11 - - - - - RootViewController - UIViewController - - IBProjectSource - ./Classes/RootViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 534 - - diff --git a/AirPrinter/AirPrinter/iPad/en.lproj/MainWindow-iPad.xib b/AirPrinter/AirPrinter/iPad/en.lproj/MainWindow-iPad.xib deleted file mode 100644 index c56e8f8..0000000 --- a/AirPrinter/AirPrinter/iPad/en.lproj/MainWindow-iPad.xib +++ /dev/null @@ -1,349 +0,0 @@ - - - - 1056 - 11A511 - 1617 - 1138 - 566.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 534 - - - YES - IBProxyObject - IBUINavigationController - IBUIViewController - IBUICustomObject - IBUIBarButtonItem - IBUIWindow - IBUINavigationBar - IBUINavigationItem - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - - - YES - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - IBIPadFramework - - - - 1316 - - {768, 1024} - - - - - 1 - MSAxIDEAA - - NO - NO - - 2 - - IBIPadFramework - YES - - - - - 1 - 1 - - IBIPadFramework - NO - - - 256 - {0, 0} - NO - YES - YES - IBIPadFramework - - - YES - - - - AirPrinter - - Home - IBIPadFramework - 1 - - IBIPadFramework - - - RootViewController - - - 1 - 1 - - IBIPadFramework - NO - - - - - - - YES - - - delegate - - - - 4 - - - - window - - - - 5 - - - - navigationController - - - - 15 - - - - - YES - - 0 - - - - - - 2 - - - YES - - - - - -1 - - - File's Owner - - - 3 - - - - - -2 - - - - - 9 - - - YES - - - - - - - 11 - - - - - 13 - - - YES - - - - - - 14 - - - YES - - - - - - 17 - - - - - - - YES - - YES - -1.CustomClassName - -1.IBPluginDependency - -2.CustomClassName - -2.IBPluginDependency - 11.IBPluginDependency - 13.CustomClassName - 13.IBLastUsedUIStatusBarStylesToTargetRuntimesMap - 13.IBPluginDependency - 14.IBPluginDependency - 17.IBPluginDependency - 2.IBAttributePlaceholdersKey - 2.IBLastUsedUIStatusBarStylesToTargetRuntimesMap - 2.IBPluginDependency - 3.CustomClassName - 3.IBPluginDependency - 9.IBLastUsedUIStatusBarStylesToTargetRuntimesMap - 9.IBPluginDependency - - - YES - UIApplication - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - RootViewController - - IBCocoaTouchFramework - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - YES - - - - - IBCocoaTouchFramework - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - AirPrinterAppDelegate - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - IBCocoaTouchFramework - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - - - - YES - - - - - 17 - - - - YES - - AirPrinterAppDelegate - NSObject - - YES - - YES - navigationController - window - - - YES - UINavigationController - UIWindow - - - - YES - - YES - navigationController - window - - - YES - - navigationController - UINavigationController - - - window - UIWindow - - - - - IBProjectSource - ./Classes/AirPrinterAppDelegate.h - - - - RootViewController - UIViewController - - IBProjectSource - ./Classes/RootViewController.h - - - - - 0 - IBIPadFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - 3 - 534 - - diff --git a/AlertController/AlertController.xcodeproj/project.pbxproj b/AlertController/AlertController.xcodeproj/project.pbxproj index be08d10..5ac5e6a 100644 --- a/AlertController/AlertController.xcodeproj/project.pbxproj +++ b/AlertController/AlertController.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -13,6 +13,7 @@ 5307C7DE19B6245B00CFD37F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5307C7DC19B6245B00CFD37F /* Main.storyboard */; }; 5307C7E019B6245B00CFD37F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5307C7DF19B6245B00CFD37F /* Images.xcassets */; }; 53AF7FFA1AECFD9C00683F34 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 53AF7FF91AECFD9C00683F34 /* README */; }; + 53B2CD6023C8E61A007FF91F /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53B2CD6223C8E61A007FF91F /* Launch Screen.storyboard */; }; 53D5575019B66F5D005EAFDF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53D5574E19B66F5D005EAFDF /* Localizable.strings */; }; /* End PBXBuildFile section */ @@ -27,6 +28,7 @@ 5307C7DD19B6245B00CFD37F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 5307C7DF19B6245B00CFD37F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 53AF7FF91AECFD9C00683F34 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 53B2CD6123C8E61A007FF91F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = "Base.lproj/Launch Screen.storyboard"; sourceTree = ""; }; 53D5574F19B66F5D005EAFDF /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; /* End PBXFileReference section */ @@ -66,6 +68,7 @@ 5307C7D919B6245B00CFD37F /* ViewController.h */, 5307C7DA19B6245B00CFD37F /* ViewController.m */, 5307C7DC19B6245B00CFD37F /* Main.storyboard */, + 53B2CD6223C8E61A007FF91F /* Launch Screen.storyboard */, 5307C7DF19B6245B00CFD37F /* Images.xcassets */, 5307C7D219B6245B00CFD37F /* Supporting Files */, ); @@ -108,7 +111,7 @@ 5307C7C719B6245B00CFD37F /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 5307C7CE19B6245B00CFD37F = { @@ -117,8 +120,8 @@ }; }; buildConfigurationList = 5307C7CA19B6245B00CFD37F /* Build configuration list for PBXProject "AlertController" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -142,6 +145,7 @@ 53AF7FFA1AECFD9C00683F34 /* README in Resources */, 5307C7DE19B6245B00CFD37F /* Main.storyboard in Resources */, 53D5575019B66F5D005EAFDF /* Localizable.strings in Resources */, + 53B2CD6023C8E61A007FF91F /* Launch Screen.storyboard in Resources */, 5307C7E019B6245B00CFD37F /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -170,6 +174,14 @@ name = Main.storyboard; sourceTree = ""; }; + 53B2CD6223C8E61A007FF91F /* Launch Screen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53B2CD6123C8E61A007FF91F /* Base */, + ); + name = "Launch Screen.storyboard"; + sourceTree = ""; + }; 53D5574E19B66F5D005EAFDF /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( @@ -185,24 +197,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -227,17 +252,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -245,6 +281,7 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -263,9 +300,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AlertController/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -274,9 +315,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AlertController/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/AlertController/AlertController/Base.lproj/Launch Screen.storyboard b/AlertController/AlertController/Base.lproj/Launch Screen.storyboard new file mode 100644 index 0000000..02419c6 --- /dev/null +++ b/AlertController/AlertController/Base.lproj/Launch Screen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AlertController/AlertController/Base.lproj/Main.storyboard b/AlertController/AlertController/Base.lproj/Main.storyboard index c45897b..13541af 100644 --- a/AlertController/AlertController/Base.lproj/Main.storyboard +++ b/AlertController/AlertController/Base.lproj/Main.storyboard @@ -1,7 +1,10 @@ - - + + + - + + + @@ -13,59 +16,59 @@ - + - + diff --git a/AlertController/AlertController/Images.xcassets/AppIcon.appiconset/Contents.json b/AlertController/AlertController/Images.xcassets/AppIcon.appiconset/Contents.json index 91bf9c1..d8db8d6 100644 --- a/AlertController/AlertController/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/AlertController/AlertController/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,18 +1,53 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, { "idiom" : "iphone", "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", "scale" : "2x" }, { @@ -44,6 +79,16 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/Contents.json b/AlertController/AlertController/Images.xcassets/Contents.json similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/Contents.json rename to AlertController/AlertController/Images.xcassets/Contents.json diff --git a/AlertController/AlertController/Images.xcassets/LaunchImage.launchimage/Contents.json b/AlertController/AlertController/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index 6f870a4..0000000 --- a/AlertController/AlertController/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/AlertController/AlertController/Info.plist b/AlertController/AlertController/Info.plist index 984f066..3af6cd7 100644 --- a/AlertController/AlertController/Info.plist +++ b/AlertController/AlertController/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,6 +22,8 @@ 1 LSRequiresIPhoneOS + UILaunchStoryboardName + Launch Screen UIMainStoryboardFile Main UIRequiredDeviceCapabilities diff --git a/AlertController/README b/AlertController/README index 72a408d..3b9896a 100644 --- a/AlertController/README +++ b/AlertController/README @@ -10,4 +10,4 @@ action sheet views. The UIAlertController class was introduced in iOS 8 as a replacement for UIAlertView and UIActionSheet. Full details in the following post: -http://useyourloaf.com/blog/2014/09/05/uialertcontroller-changes-in-ios-8.html +https://useyourloaf.com/blog/uialertcontroller-changes-in-ios-8/ diff --git a/AlertView/AlertView/en.lproj/UYLViewController.xib b/AlertView/AlertView/en.lproj/UYLViewController.xib deleted file mode 100644 index 7de4aa1..0000000 --- a/AlertView/AlertView/en.lproj/UYLViewController.xib +++ /dev/null @@ -1,326 +0,0 @@ - - - - 1280 - 11C74 - 1938 - 1138.23 - 567.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 - - - IBUIButton - IBUIView - IBUILabel - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{20, 118}, {280, 37}} - - - _NS:225 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Default Style - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - - - - 292 - {{20, 190}, {280, 37}} - - - _NS:225 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Secure Text Input - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - - - - - - 292 - {{20, 262}, {280, 37}} - - - _NS:225 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Plain Text Input - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - - - - - - 292 - {{20, 336}, {280, 37}} - - - _NS:225 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Login and Password - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - - - - - - 292 - {{20, 20}, {280, 46}} - - - _NS:328 - NO - YES - 7 - NO - IBCocoaTouchFramework - UIAlertViewStyle - - 1 - MSAxIDAAA - - - 1 - 10 - 1 - - 1 - 20 - - - Helvetica - 20 - 16 - - - - {{0, 20}, {320, 460}} - - - - - 1 - MC41IDAgMC41AA - - NO - - IBCocoaTouchFramework - - - - - - - view - - - - 7 - - - - showDefaultAlertView: - - - 7 - - 13 - - - - showSecureTextAlertView: - - - 7 - - 14 - - - - showPlainTextAlertView: - - - 7 - - 15 - - - - showLoginPassAlertView: - - - 7 - - 16 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 6 - - - - - - - - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 11 - - - - - 12 - - - - - - - UYLViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 16 - - - - - UYLViewController - UIViewController - - IBProjectSource - ./Classes/UYLViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 933 - - diff --git a/AllVisible/AllVisible.xcodeproj/project.pbxproj b/AllVisible/AllVisible.xcodeproj/project.pbxproj index 65cd580..6c1007d 100644 --- a/AllVisible/AllVisible.xcodeproj/project.pbxproj +++ b/AllVisible/AllVisible.xcodeproj/project.pbxproj @@ -167,12 +167,13 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53AA2EB11DA2A957008EBF84 = { CreatedOnToolsVersion = 8.0; DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1120; ProvisioningStyle = Automatic; }; 53AA2ECC1DA2AE09008EBF84 = { @@ -184,7 +185,7 @@ }; buildConfigurationList = 53AA2EAD1DA2A957008EBF84 /* Build configuration list for PBXProject "AllVisible" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -288,20 +289,30 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -338,20 +349,30 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -386,7 +407,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AllVisible; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -399,7 +421,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AllVisible; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/AllVisible/AllVisible/AppDelegate.swift b/AllVisible/AllVisible/AppDelegate.swift index 36e6e17..c56dd48 100644 --- a/AllVisible/AllVisible/AppDelegate.swift +++ b/AllVisible/AllVisible/AppDelegate.swift @@ -3,7 +3,7 @@ // AllVisible // // Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2016 Keith Harrison. All rights reserved. +// Copyright (c) 2016-2018 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -35,23 +35,35 @@ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + guard let splitViewController = self.window?.rootViewController as? UISplitViewController else { + fatalError("Missing SplitViewController") + } + + guard let masterNavController = splitViewController.viewControllers.first as? UINavigationController, + let masterViewController = masterNavController.topViewController as? MasterViewController else { + fatalError("Missing MasterViewController") + } + + guard let navigationController = splitViewController.viewControllers.last as? UINavigationController, + let detailViewController = navigationController.topViewController else { + fatalError("Missing detail view controller") + } // Configure the SplitViewController to prefer to always - // show both master and detail views and add the display - // mode button to the navigation bar of the secondary - // view controller. + // show both master and detail views. + splitViewController.preferredDisplayMode = .allVisible - if let splitViewController = self.window?.rootViewController as? UISplitViewController { - splitViewController.preferredDisplayMode = .allVisible + // Make the master view controller the delegate. + splitViewController.delegate = masterViewController + + // Add the display mode button to the navigation bar + // of the secondary view controller. + detailViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem + detailViewController.navigationItem.leftItemsSupplementBackButton = true - if let navigationController = splitViewController.viewControllers.last as? UINavigationController { - navigationController.topViewController?.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem - } - } return true } } diff --git a/AllVisible/AllVisible/Base.lproj/Main.storyboard b/AllVisible/AllVisible/Base.lproj/Main.storyboard index d3b70bb..2723212 100644 --- a/AllVisible/AllVisible/Base.lproj/Main.storyboard +++ b/AllVisible/AllVisible/Base.lproj/Main.storyboard @@ -1,8 +1,10 @@ - + + - + + @@ -11,7 +13,7 @@ - + @@ -26,27 +28,27 @@ - - - - - + - + + @@ -58,27 +60,25 @@ - - - - - + - + - + + @@ -109,7 +109,7 @@ - + @@ -122,6 +122,6 @@ - + diff --git a/AllVisible/AllVisible/DetailViewController.swift b/AllVisible/AllVisible/DetailViewController.swift index 046b0cf..2bdf1ae 100644 --- a/AllVisible/AllVisible/DetailViewController.swift +++ b/AllVisible/AllVisible/DetailViewController.swift @@ -3,7 +3,7 @@ // AllVisible // // Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2016 Keith Harrison. All rights reserved. +// Copyright (c) 2016-2018 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -33,9 +33,8 @@ import UIKit -class DetailViewController: UIViewController { - - @IBOutlet private weak var detailLabel: UILabel! +final class DetailViewController: UIViewController { + @IBOutlet private var detailLabel: UILabel! private func configureView() { if let label = detailLabel { diff --git a/AllVisible/AllVisible/MasterViewController.swift b/AllVisible/AllVisible/MasterViewController.swift index 10105d1..6d1e170 100644 --- a/AllVisible/AllVisible/MasterViewController.swift +++ b/AllVisible/AllVisible/MasterViewController.swift @@ -3,7 +3,7 @@ // AllVisible // // Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2016 Keith Harrison. All rights reserved. +// Copyright (c) 2016-2018 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -33,29 +33,14 @@ import UIKit -class MasterViewController: UIViewController { - - fileprivate var collapseDetailViewController = true - - override func viewDidLoad() { - super.viewDidLoad() - splitViewController?.delegate = self - } - +final class MasterViewController: UIViewController { override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - guard let navController = segue.destination as? UINavigationController, - let viewController = navController.topViewController as? DetailViewController + let viewController = navController.topViewController as? DetailViewController else { fatalError("Expected DetailViewController") } - // Once we have something to show in the detail - // view allow the default which is to show the - // secondary in a collapsed split view - - collapseDetailViewController = false - viewController.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem viewController.navigationItem.leftItemsSupplementBackButton = true viewController.detailItem = Date() @@ -63,11 +48,18 @@ class MasterViewController: UIViewController { } extension MasterViewController: UISplitViewControllerDelegate { - func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool { + // Returning true prevents the default of showing + // the secondary view controller. + guard let navigationController = secondaryViewController as? UINavigationController, + let detailViewController = navigationController.topViewController as? DetailViewController else { + // Fallback to the default + return false + } - // Returning true prevents the default of showing the secondary - // view controller. - return collapseDetailViewController + // Once we have something to show in the detail + // view return false to show the secondary in a + // collapsed split view + return detailViewController.detailItem == nil } } diff --git a/AllVisible/AllVisibleObjC/AppDelegate.m b/AllVisible/AllVisibleObjC/AppDelegate.m index d69a89e..a169974 100644 --- a/AllVisible/AllVisibleObjC/AppDelegate.m +++ b/AllVisible/AllVisibleObjC/AppDelegate.m @@ -33,14 +33,21 @@ #import "AppDelegate.h" +#import "MasterViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController; splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; + + UINavigationController *masterNavigationController = [splitViewController.viewControllers firstObject]; + MasterViewController *masterViewController = (MasterViewController *)masterNavigationController.topViewController; + splitViewController.delegate = masterViewController; + UINavigationController *navigationController = [splitViewController.viewControllers lastObject]; navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem; + navigationController.topViewController.navigationItem.leftItemsSupplementBackButton = YES; return YES; } diff --git a/AllVisible/AllVisibleObjC/DetailViewController.h b/AllVisible/AllVisibleObjC/DetailViewController.h index 40d451f..7d2ab80 100644 --- a/AllVisible/AllVisibleObjC/DetailViewController.h +++ b/AllVisible/AllVisibleObjC/DetailViewController.h @@ -35,5 +35,5 @@ #import @interface DetailViewController : UIViewController -@property (copy, nonatomic) NSDate *detailItem; +@property (copy, nonatomic, nullable) NSDate *detailItem; @end diff --git a/AllVisible/AllVisibleObjC/MasterViewController.h b/AllVisible/AllVisibleObjC/MasterViewController.h index b2e3a60..0ed7dc7 100644 --- a/AllVisible/AllVisibleObjC/MasterViewController.h +++ b/AllVisible/AllVisibleObjC/MasterViewController.h @@ -34,5 +34,5 @@ #import -@interface MasterViewController : UIViewController +@interface MasterViewController : UIViewController @end diff --git a/AllVisible/AllVisibleObjC/MasterViewController.m b/AllVisible/AllVisibleObjC/MasterViewController.m index 3f6d0d0..f570cf8 100644 --- a/AllVisible/AllVisibleObjC/MasterViewController.m +++ b/AllVisible/AllVisibleObjC/MasterViewController.m @@ -35,30 +35,24 @@ #import "MasterViewController.h" #import "DetailViewController.h" -@interface MasterViewController () -@property (nonatomic, assign) BOOL collapseDetailViewController; -@end - @implementation MasterViewController -- (void)viewDidLoad { - [super viewDidLoad]; - self.collapseDetailViewController = YES; - self.splitViewController.delegate = self; -} - - (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController { - return self.collapseDetailViewController; + if ([secondaryViewController isKindOfClass:[UINavigationController class]]) { + UINavigationController *navigationController = (UINavigationController *)secondaryViewController; + if ([navigationController.topViewController isKindOfClass:[DetailViewController class]]) { + DetailViewController *detailViewController = (DetailViewController *)navigationController.topViewController; + return detailViewController.detailItem == NULL; + } + } + return NO; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - - self.collapseDetailViewController = NO; - if ([segue.destinationViewController isKindOfClass:[UINavigationController class]]) { - UINavigationController *navController = segue.destinationViewController; - if ([navController.topViewController isKindOfClass:[DetailViewController class]]) { - DetailViewController *viewController = (DetailViewController *)navController.topViewController; + UINavigationController *navigationController = segue.destinationViewController; + if ([navigationController.topViewController isKindOfClass:[DetailViewController class]]) { + DetailViewController *viewController = (DetailViewController *)navigationController.topViewController; viewController.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; viewController.navigationItem.leftItemsSupplementBackButton = YES; viewController.detailItem = [NSDate date]; diff --git a/AllVisible/README.md b/AllVisible/README.md index df93f0b..c5ee204 100644 --- a/AllVisible/README.md +++ b/AllVisible/README.md @@ -2,4 +2,4 @@ A simple Xcode project template showing how to configure a split view controller to prefer to show both the primary and secondary view controllers. Both Swift and Objective-C versions are included. -For a more detailed explanation see [Split View Controller Display Modes](http://useyourloaf.com/blog/split-view-controller-display-modes/) +For a more detailed explanation see [Split View Controller Display Modes](https://useyourloaf.com/blog/split-view-controller-display-modes/) diff --git a/AnimatedConstraints/AnimatedConstraints.xcodeproj/project.pbxproj b/AnimatedConstraints/AnimatedConstraints.xcodeproj/project.pbxproj index ff20624..a579b76 100644 --- a/AnimatedConstraints/AnimatedConstraints.xcodeproj/project.pbxproj +++ b/AnimatedConstraints/AnimatedConstraints.xcodeproj/project.pbxproj @@ -16,7 +16,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 5326FC411B0A8FF5003FF69D /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; + 5326FC411B0A8FF5003FF69D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 53D8FD641B08B9E100265E63 /* AnimatedConstraints.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnimatedConstraints.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53D8FD681B08B9E100265E63 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53D8FD691B08B9E100265E63 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -43,7 +43,7 @@ 53D8FD5B1B08B9E100265E63 = { isa = PBXGroup; children = ( - 5326FC411B0A8FF5003FF69D /* README */, + 5326FC411B0A8FF5003FF69D /* README.md */, 53D8FD661B08B9E100265E63 /* AnimatedConstraints */, 53D8FD651B08B9E100265E63 /* Products */, ); @@ -107,17 +107,18 @@ 53D8FD5C1B08B9E100265E63 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0630; + LastUpgradeCheck = 1110; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53D8FD631B08B9E100265E63 = { CreatedOnToolsVersion = 6.3.1; + DevelopmentTeam = LCC2J94N44; }; }; }; buildConfigurationList = 53D8FD5F1B08B9E100265E63 /* Build configuration list for PBXProject "AnimatedConstraints" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -175,23 +176,35 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -207,7 +220,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -219,17 +232,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -245,7 +269,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.3; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -257,8 +281,11 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AnimatedConstraints/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -267,8 +294,11 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AnimatedConstraints/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/AnimatedConstraints/AnimatedConstraints/Base.lproj/Main.storyboard b/AnimatedConstraints/AnimatedConstraints/Base.lproj/Main.storyboard index b93b4fa..ce347f7 100644 --- a/AnimatedConstraints/AnimatedConstraints/Base.lproj/Main.storyboard +++ b/AnimatedConstraints/AnimatedConstraints/Base.lproj/Main.storyboard @@ -1,8 +1,10 @@ - - + + + - - + + + @@ -14,31 +16,31 @@ - + - + - - + + - - + + - + @@ -75,7 +77,7 @@ - + diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/Contents.json b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/Contents.json index 27575b9..6fe8d1f 100644 --- a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,17 @@ { "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon-41.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon-60.png", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", @@ -36,6 +48,18 @@ "filename" : "icon-180.png", "scale" : "3x" }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon-20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon-42.png", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", @@ -71,6 +95,18 @@ "idiom" : "ipad", "filename" : "icon-76@2x.png", "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "icon-167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "icon-1024.png", + "scale" : "1x" } ], "info" : { diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-1024.png b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000..4a1a9de Binary files /dev/null and b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-1024.png differ diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-167.png b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-167.png new file mode 100644 index 0000000..0a5ec66 Binary files /dev/null and b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-167.png differ diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-20.png b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-20.png new file mode 100644 index 0000000..3c16adf Binary files /dev/null and b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-20.png differ diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-41.png b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-41.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-41.png differ diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-42.png b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-42.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-42.png differ diff --git a/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-60.png b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-60.png new file mode 100644 index 0000000..fd2eff6 Binary files /dev/null and b/AnimatedConstraints/AnimatedConstraints/Images.xcassets/AppIcon.appiconset/icon-60.png differ diff --git a/AnimatedConstraints/AnimatedConstraints/Info.plist b/AnimatedConstraints/AnimatedConstraints/Info.plist index 8d07b46..bd1ead3 100644 --- a/AnimatedConstraints/AnimatedConstraints/Info.plist +++ b/AnimatedConstraints/AnimatedConstraints/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -19,7 +19,7 @@ CFBundleSignature ???? CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/AnimatedConstraints/AnimatedConstraints/LaunchScreen.storyboard b/AnimatedConstraints/AnimatedConstraints/LaunchScreen.storyboard index 76ed3d1..8d412a2 100644 --- a/AnimatedConstraints/AnimatedConstraints/LaunchScreen.storyboard +++ b/AnimatedConstraints/AnimatedConstraints/LaunchScreen.storyboard @@ -1,7 +1,10 @@ - - + + + - + + + @@ -13,17 +16,17 @@ - + - + @@ -41,7 +44,7 @@ - + diff --git a/AnimatedConstraints/README b/AnimatedConstraints/README deleted file mode 100644 index f23d42c..0000000 --- a/AnimatedConstraints/README +++ /dev/null @@ -1,12 +0,0 @@ -======================================================================= -AnimatedConstraints - -Version 1.1 21 May 2015 Switch to changing priorities rather than - adding/removing constraints. -Version 1.0 18 May 2015 Initial Version -======================================================================= - -An example on how to animate changes made to autolayout constraints. -For further details see the post: - -useyourloaf.com/blog/2015/05/18/animating-autolayout-constraints.html \ No newline at end of file diff --git a/AnimatedConstraints/README.md b/AnimatedConstraints/README.md new file mode 100644 index 0000000..cdbb29f --- /dev/null +++ b/AnimatedConstraints/README.md @@ -0,0 +1,16 @@ +# AnimatedConstraints + + +An example on how to animate changes made to autolayout constraints. +For further details see the post: + ++ [Animating Autolayout Constraints](https://useyourloaf.com/blog/animating-autolayout-constraints/) + +## Version History + ++ Version 1.2 - 04 Oct 2019 + Minor refresh for Xcode 11. ++ Version 1.1 - 21 May 2015 + Switch to changing priorities rather than adding/removing constraints. ++ Version 1.0 - 18 May 2015 + Initial Version diff --git a/AirPrinter/AirPrinter.xcodeproj/project.pbxproj b/Archive/AirPrinter/AirPrinter.xcodeproj/project.pbxproj similarity index 90% rename from AirPrinter/AirPrinter.xcodeproj/project.pbxproj rename to Archive/AirPrinter/AirPrinter.xcodeproj/project.pbxproj index 687d0f6..d1e10dd 100644 --- a/AirPrinter/AirPrinter.xcodeproj/project.pbxproj +++ b/Archive/AirPrinter/AirPrinter.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -29,6 +29,9 @@ 5310096E13E73E49008FC50D /* WebViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WebViewController.xib; sourceTree = ""; }; 5310097613E74913008FC50D /* UYLGenericPrintPageRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLGenericPrintPageRenderer.h; sourceTree = ""; }; 5310097713E74913008FC50D /* UYLGenericPrintPageRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLGenericPrintPageRenderer.m; sourceTree = ""; }; + 5334609623CA6FC800BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainWindow.xib; sourceTree = ""; }; + 5334609723CA6FC900BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/RootViewController.xib; sourceTree = ""; }; + 5334609823CA6FC900BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "iPad/Base.lproj/MainWindow-iPad.xib"; sourceTree = ""; }; 5336C32213E46620007FB510 /* AirPrinter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AirPrinter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5336C32613E46620007FB510 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 5336C32813E46620007FB510 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -39,11 +42,8 @@ 5336C33413E46620007FB510 /* AirPrinter-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AirPrinter-Prefix.pch"; sourceTree = ""; }; 5336C33513E46620007FB510 /* AirPrinterAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AirPrinterAppDelegate.h; sourceTree = ""; }; 5336C33613E46620007FB510 /* AirPrinterAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AirPrinterAppDelegate.m; sourceTree = ""; }; - 5336C33913E46620007FB510 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; 5336C33B13E46620007FB510 /* RootViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; 5336C33C13E46620007FB510 /* RootViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; - 5336C33F13E46620007FB510 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/RootViewController.xib; sourceTree = ""; }; - 5336C34813E4663E007FB510 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = "iPad/en.lproj/MainWindow-iPad.xib"; sourceTree = ""; }; 53B8321B14069CB300E052A4 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -186,12 +186,16 @@ /* Begin PBXProject section */ 5336C31913E46620007FB510 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 1120; + }; buildConfigurationList = 5336C31C13E46620007FB510 /* Build configuration list for PBXProject "AirPrinter" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 5336C31713E46620007FB510; productRefGroup = 5336C32313E46620007FB510 /* Products */; @@ -245,7 +249,7 @@ 5336C33813E46620007FB510 /* MainWindow.xib */ = { isa = PBXVariantGroup; children = ( - 5336C33913E46620007FB510 /* en */, + 5334609623CA6FC800BE943E /* Base */, ); name = MainWindow.xib; sourceTree = ""; @@ -253,7 +257,7 @@ 5336C33E13E46620007FB510 /* RootViewController.xib */ = { isa = PBXVariantGroup; children = ( - 5336C33F13E46620007FB510 /* en */, + 5334609723CA6FC900BE943E /* Base */, ); name = RootViewController.xib; sourceTree = ""; @@ -261,7 +265,7 @@ 5336C34713E4663E007FB510 /* MainWindow-iPad.xib */ = { isa = PBXVariantGroup; children = ( - 5336C34813E4663E007FB510 /* en */, + 5334609823CA6FC900BE943E /* Base */, ); name = "MainWindow-iPad.xib"; sourceTree = ""; @@ -273,9 +277,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -288,7 +293,8 @@ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-DUYL_DEBUG"; SDKROOT = iphoneos; }; @@ -298,7 +304,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -306,7 +312,7 @@ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -316,10 +322,14 @@ 5336C34413E46620007FB510 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AirPrinter/AirPrinter-Prefix.pch"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "AirPrinter/AirPrinter-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; @@ -329,10 +339,14 @@ 5336C34513E46620007FB510 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AirPrinter/AirPrinter-Prefix.pch"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_FILE = "AirPrinter/AirPrinter-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; diff --git a/AirPrinter/AirPrinter/AirPrinter-Info.plist b/Archive/AirPrinter/AirPrinter/AirPrinter-Info.plist similarity index 94% rename from AirPrinter/AirPrinter/AirPrinter-Info.plist rename to Archive/AirPrinter/AirPrinter/AirPrinter-Info.plist index 3070946..cd79178 100644 --- a/AirPrinter/AirPrinter/AirPrinter-Info.plist +++ b/Archive/AirPrinter/AirPrinter/AirPrinter-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/AirPrinter/AirPrinter/AirPrinter-Prefix.pch b/Archive/AirPrinter/AirPrinter/AirPrinter-Prefix.pch similarity index 100% rename from AirPrinter/AirPrinter/AirPrinter-Prefix.pch rename to Archive/AirPrinter/AirPrinter/AirPrinter-Prefix.pch diff --git a/AirPrinter/AirPrinter/AirPrinterAppDelegate.h b/Archive/AirPrinter/AirPrinter/AirPrinterAppDelegate.h similarity index 100% rename from AirPrinter/AirPrinter/AirPrinterAppDelegate.h rename to Archive/AirPrinter/AirPrinter/AirPrinterAppDelegate.h diff --git a/AirPrinter/AirPrinter/AirPrinterAppDelegate.m b/Archive/AirPrinter/AirPrinter/AirPrinterAppDelegate.m similarity index 100% rename from AirPrinter/AirPrinter/AirPrinterAppDelegate.m rename to Archive/AirPrinter/AirPrinter/AirPrinterAppDelegate.m diff --git a/Archive/AirPrinter/AirPrinter/Base.lproj/MainWindow.xib b/Archive/AirPrinter/AirPrinter/Base.lproj/MainWindow.xib new file mode 100644 index 0000000..a6f7cfc --- /dev/null +++ b/Archive/AirPrinter/AirPrinter/Base.lproj/MainWindow.xib @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/AirPrinter/AirPrinter/Base.lproj/RootViewController.xib b/Archive/AirPrinter/AirPrinter/Base.lproj/RootViewController.xib new file mode 100644 index 0000000..ea17a5e --- /dev/null +++ b/Archive/AirPrinter/AirPrinter/Base.lproj/RootViewController.xib @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AirPrinter/AirPrinter/RootViewController.h b/Archive/AirPrinter/AirPrinter/RootViewController.h similarity index 100% rename from AirPrinter/AirPrinter/RootViewController.h rename to Archive/AirPrinter/AirPrinter/RootViewController.h diff --git a/AirPrinter/AirPrinter/RootViewController.m b/Archive/AirPrinter/AirPrinter/RootViewController.m similarity index 100% rename from AirPrinter/AirPrinter/RootViewController.m rename to Archive/AirPrinter/AirPrinter/RootViewController.m diff --git a/AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.h b/Archive/AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.h similarity index 100% rename from AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.h rename to Archive/AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.h diff --git a/AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.m b/Archive/AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.m similarity index 100% rename from AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.m rename to Archive/AirPrinter/AirPrinter/UYLGenericPrintPageRenderer.m diff --git a/AirPrinter/AirPrinter/WebViewController.h b/Archive/AirPrinter/AirPrinter/WebViewController.h similarity index 100% rename from AirPrinter/AirPrinter/WebViewController.h rename to Archive/AirPrinter/AirPrinter/WebViewController.h diff --git a/AirPrinter/AirPrinter/WebViewController.m b/Archive/AirPrinter/AirPrinter/WebViewController.m similarity index 100% rename from AirPrinter/AirPrinter/WebViewController.m rename to Archive/AirPrinter/AirPrinter/WebViewController.m diff --git a/Archive/AirPrinter/AirPrinter/WebViewController.xib b/Archive/AirPrinter/AirPrinter/WebViewController.xib new file mode 100644 index 0000000..58e917e --- /dev/null +++ b/Archive/AirPrinter/AirPrinter/WebViewController.xib @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AirPrinter/AirPrinter/en.lproj/InfoPlist.strings b/Archive/AirPrinter/AirPrinter/en.lproj/InfoPlist.strings similarity index 100% rename from AirPrinter/AirPrinter/en.lproj/InfoPlist.strings rename to Archive/AirPrinter/AirPrinter/en.lproj/InfoPlist.strings diff --git a/Archive/AirPrinter/AirPrinter/iPad/Base.lproj/MainWindow-iPad.xib b/Archive/AirPrinter/AirPrinter/iPad/Base.lproj/MainWindow-iPad.xib new file mode 100644 index 0000000..52816fd --- /dev/null +++ b/Archive/AirPrinter/AirPrinter/iPad/Base.lproj/MainWindow-iPad.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AirPrinter/AirPrinter/main.m b/Archive/AirPrinter/AirPrinter/main.m similarity index 100% rename from AirPrinter/AirPrinter/main.m rename to Archive/AirPrinter/AirPrinter/main.m diff --git a/AlertView/AlertView.xcodeproj/project.pbxproj b/Archive/AlertView/AlertView.xcodeproj/project.pbxproj similarity index 80% rename from AlertView/AlertView.xcodeproj/project.pbxproj rename to Archive/AlertView/AlertView.xcodeproj/project.pbxproj index 3bef398..0af1f42 100644 --- a/AlertView/AlertView.xcodeproj/project.pbxproj +++ b/Archive/AlertView/AlertView.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5334609223CA652200BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLViewController.xib; sourceTree = ""; }; 534028B91497F89D002DB13A /* AlertView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AlertView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 534028BD1497F89D002DB13A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 534028BF1497F89D002DB13A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -30,7 +31,6 @@ 534028CD1497F89D002DB13A /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 534028CF1497F89D002DB13A /* UYLViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLViewController.h; sourceTree = ""; }; 534028D01497F89D002DB13A /* UYLViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLViewController.m; sourceTree = ""; }; - 534028D31497F89D002DB13A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLViewController.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -124,14 +124,15 @@ 534028B01497F89D002DB13A /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 1120; }; buildConfigurationList = 534028B31497F89D002DB13A /* Build configuration list for PBXProject "AlertView" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 534028AE1497F89D002DB13A; productRefGroup = 534028BA1497F89D002DB13A /* Products */; @@ -180,7 +181,7 @@ 534028D21497F89D002DB13A /* UYLViewController.xib */ = { isa = PBXVariantGroup; children = ( - 534028D31497F89D002DB13A /* en */, + 5334609223CA652200BE943E /* Base */, ); name = UYLViewController.xib; sourceTree = ""; @@ -192,11 +193,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -204,10 +225,15 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -216,15 +242,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -234,9 +283,11 @@ 534028D81497F89D002DB13A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AlertView/AlertView-Prefix.pch"; INFOPLIST_FILE = "AlertView/AlertView-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -245,9 +296,11 @@ 534028D91497F89D002DB13A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AlertView/AlertView-Prefix.pch"; INFOPLIST_FILE = "AlertView/AlertView-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -272,6 +325,7 @@ 534028D91497F89D002DB13A /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/AlertView/AlertView/AlertView-Info.plist b/Archive/AlertView/AlertView/AlertView-Info.plist similarity index 94% rename from AlertView/AlertView/AlertView-Info.plist rename to Archive/AlertView/AlertView/AlertView-Info.plist index f5d7a12..5da589d 100644 --- a/AlertView/AlertView/AlertView-Info.plist +++ b/Archive/AlertView/AlertView/AlertView-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFiles CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/AlertView/AlertView/AlertView-Prefix.pch b/Archive/AlertView/AlertView/AlertView-Prefix.pch similarity index 100% rename from AlertView/AlertView/AlertView-Prefix.pch rename to Archive/AlertView/AlertView/AlertView-Prefix.pch diff --git a/Archive/AlertView/AlertView/Base.lproj/UYLViewController.xib b/Archive/AlertView/AlertView/Base.lproj/UYLViewController.xib new file mode 100644 index 0000000..154769b --- /dev/null +++ b/Archive/AlertView/AlertView/Base.lproj/UYLViewController.xib @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AlertView/AlertView/UYLAppDelegate.h b/Archive/AlertView/AlertView/UYLAppDelegate.h similarity index 100% rename from AlertView/AlertView/UYLAppDelegate.h rename to Archive/AlertView/AlertView/UYLAppDelegate.h diff --git a/AlertView/AlertView/UYLAppDelegate.m b/Archive/AlertView/AlertView/UYLAppDelegate.m similarity index 100% rename from AlertView/AlertView/UYLAppDelegate.m rename to Archive/AlertView/AlertView/UYLAppDelegate.m diff --git a/AlertView/AlertView/UYLViewController.h b/Archive/AlertView/AlertView/UYLViewController.h similarity index 100% rename from AlertView/AlertView/UYLViewController.h rename to Archive/AlertView/AlertView/UYLViewController.h diff --git a/AlertView/AlertView/UYLViewController.m b/Archive/AlertView/AlertView/UYLViewController.m similarity index 100% rename from AlertView/AlertView/UYLViewController.m rename to Archive/AlertView/AlertView/UYLViewController.m diff --git a/AlertView/AlertView/en.lproj/InfoPlist.strings b/Archive/AlertView/AlertView/en.lproj/InfoPlist.strings similarity index 100% rename from AlertView/AlertView/en.lproj/InfoPlist.strings rename to Archive/AlertView/AlertView/en.lproj/InfoPlist.strings diff --git a/AlertView/AlertView/main.m b/Archive/AlertView/AlertView/main.m similarity index 100% rename from AlertView/AlertView/main.m rename to Archive/AlertView/AlertView/main.m diff --git a/BUG TableView State Restore/README b/Archive/BUG TableView State Restore/README similarity index 91% rename from BUG TableView State Restore/README rename to Archive/BUG TableView State Restore/README index 7a1ba94..e463f6e 100644 --- a/BUG TableView State Restore/README +++ b/Archive/BUG TableView State Restore/README @@ -22,7 +22,7 @@ as expected. For further details see the following blog post: -http://useyourloaf.com/blog/2013/04/07/bug-table-view-state-not-restored-when-embedded-in-navigation-controller.html +https://useyourloaf.com/blog/bug-table-view-state-not-restored-when-embedded-in-navigation-controller/ ************************************************************************** *** This bug has been tested and reproduced for iOS 6.0 and iOS 6.1.3. *** diff --git a/BUG TableView State Restore/UYLTableViewController.h b/Archive/BUG TableView State Restore/UYLTableViewController.h similarity index 100% rename from BUG TableView State Restore/UYLTableViewController.h rename to Archive/BUG TableView State Restore/UYLTableViewController.h diff --git a/BUG TableView State Restore/UYLTableViewController.m b/Archive/BUG TableView State Restore/UYLTableViewController.m similarity index 100% rename from BUG TableView State Restore/UYLTableViewController.m rename to Archive/BUG TableView State Restore/UYLTableViewController.m diff --git a/BUG TableView State Restore/restore.xcodeproj/project.pbxproj b/Archive/BUG TableView State Restore/restore.xcodeproj/project.pbxproj similarity index 86% rename from BUG TableView State Restore/restore.xcodeproj/project.pbxproj rename to Archive/BUG TableView State Restore/restore.xcodeproj/project.pbxproj index a3364b9..f3bb7b1 100644 --- a/BUG TableView State Restore/restore.xcodeproj/project.pbxproj +++ b/Archive/BUG TableView State Restore/restore.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5334608723CA275700BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainStoryboard.storyboard; sourceTree = ""; }; 53370CBD16F62D8D0090DFC5 /* restore.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = restore.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53370CC016F62D8D0090DFC5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53370CC216F62D8D0090DFC5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -36,7 +37,6 @@ 53370CD216F62D8D0090DFC5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 53370CD416F62D8D0090DFC5 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 53370CD616F62D8D0090DFC5 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - 53370CD916F62D8D0090DFC5 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = ""; }; 53370CE316F62FF70090DFC5 /* UYLTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UYLTableViewController.h; path = ../UYLTableViewController.h; sourceTree = ""; }; 53370CE416F62FF70090DFC5 /* UYLTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UYLTableViewController.m; path = ../UYLTableViewController.m; sourceTree = ""; }; 537C3B7517121F9100FA27ED /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; @@ -140,15 +140,16 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0460; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; }; buildConfigurationList = 53370CB816F62D8D0090DFC5 /* Build configuration list for PBXProject "restore" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 53370CB416F62D8D0090DFC5; productRefGroup = 53370CBE16F62D8D0090DFC5 /* Products */; @@ -202,7 +203,7 @@ 53370CD816F62D8D0090DFC5 /* MainStoryboard.storyboard */ = { isa = PBXVariantGroup; children = ( - 53370CD916F62D8D0090DFC5 /* en */, + 5334608723CA275700BE943E /* Base */, ); name = MainStoryboard.storyboard; sourceTree = ""; @@ -214,28 +215,47 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -245,21 +265,39 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -272,6 +310,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "restore/restore-Prefix.pch"; INFOPLIST_FILE = "restore/restore-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -283,6 +322,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "restore/restore-Prefix.pch"; INFOPLIST_FILE = "restore/restore-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/BUG TableView State Restore/restore/en.lproj/MainStoryboard.storyboard b/Archive/BUG TableView State Restore/restore/Base.lproj/MainStoryboard.storyboard similarity index 60% rename from BUG TableView State Restore/restore/en.lproj/MainStoryboard.storyboard rename to Archive/BUG TableView State Restore/restore/Base.lproj/MainStoryboard.storyboard index e233416..39f83d9 100644 --- a/BUG TableView State Restore/restore/en.lproj/MainStoryboard.storyboard +++ b/Archive/BUG TableView State Restore/restore/Base.lproj/MainStoryboard.storyboard @@ -1,33 +1,37 @@ - - + + + - + + + - - + + - + - + - - + + - - - + @@ -39,17 +43,7 @@ - + - - - - - - - - - - - \ No newline at end of file + diff --git a/BUG TableView State Restore/restore/Default-568h@2x.png b/Archive/BUG TableView State Restore/restore/Default-568h@2x.png similarity index 100% rename from BUG TableView State Restore/restore/Default-568h@2x.png rename to Archive/BUG TableView State Restore/restore/Default-568h@2x.png diff --git a/BUG TableView State Restore/restore/Default.png b/Archive/BUG TableView State Restore/restore/Default.png similarity index 100% rename from BUG TableView State Restore/restore/Default.png rename to Archive/BUG TableView State Restore/restore/Default.png diff --git a/BUG TableView State Restore/restore/Default@2x.png b/Archive/BUG TableView State Restore/restore/Default@2x.png similarity index 100% rename from BUG TableView State Restore/restore/Default@2x.png rename to Archive/BUG TableView State Restore/restore/Default@2x.png diff --git a/BUG TableView State Restore/restore/NavStoryboard.storyboard b/Archive/BUG TableView State Restore/restore/NavStoryboard.storyboard similarity index 100% rename from BUG TableView State Restore/restore/NavStoryboard.storyboard rename to Archive/BUG TableView State Restore/restore/NavStoryboard.storyboard diff --git a/BUG TableView State Restore/restore/UYLAppDelegate.h b/Archive/BUG TableView State Restore/restore/UYLAppDelegate.h similarity index 100% rename from BUG TableView State Restore/restore/UYLAppDelegate.h rename to Archive/BUG TableView State Restore/restore/UYLAppDelegate.h diff --git a/BUG TableView State Restore/restore/UYLAppDelegate.m b/Archive/BUG TableView State Restore/restore/UYLAppDelegate.m similarity index 100% rename from BUG TableView State Restore/restore/UYLAppDelegate.m rename to Archive/BUG TableView State Restore/restore/UYLAppDelegate.m diff --git a/BUG TableView State Restore/restore/en.lproj/InfoPlist.strings b/Archive/BUG TableView State Restore/restore/en.lproj/InfoPlist.strings similarity index 100% rename from BUG TableView State Restore/restore/en.lproj/InfoPlist.strings rename to Archive/BUG TableView State Restore/restore/en.lproj/InfoPlist.strings diff --git a/BUG TableView State Restore/restore/main.m b/Archive/BUG TableView State Restore/restore/main.m similarity index 100% rename from BUG TableView State Restore/restore/main.m rename to Archive/BUG TableView State Restore/restore/main.m diff --git a/BUG TableView State Restore/restore/restore-Info.plist b/Archive/BUG TableView State Restore/restore/restore-Info.plist similarity index 94% rename from BUG TableView State Restore/restore/restore-Info.plist rename to Archive/BUG TableView State Restore/restore/restore-Info.plist index e20c6df..36d8600 100644 --- a/BUG TableView State Restore/restore/restore-Info.plist +++ b/Archive/BUG TableView State Restore/restore/restore-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/BUG TableView State Restore/restore/restore-Prefix.pch b/Archive/BUG TableView State Restore/restore/restore-Prefix.pch similarity index 100% rename from BUG TableView State Restore/restore/restore-Prefix.pch rename to Archive/BUG TableView State Restore/restore/restore-Prefix.pch diff --git a/Collection/Collection.xcodeproj/project.pbxproj b/Archive/Collection/Collection.xcodeproj/project.pbxproj similarity index 92% rename from Collection/Collection.xcodeproj/project.pbxproj rename to Archive/Collection/Collection.xcodeproj/project.pbxproj index 83cd935..84347c5 100644 --- a/Collection/Collection.xcodeproj/project.pbxproj +++ b/Archive/Collection/Collection.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -209,7 +209,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0500; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53A5F89017E3BA57000DB6B5 = { @@ -221,8 +221,8 @@ }; }; buildConfigurationList = 53A5F88C17E3BA57000DB6B5 /* Build configuration list for PBXProject "Collection" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -323,23 +323,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -352,7 +366,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 2; @@ -363,30 +377,43 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 2; VALIDATE_PRODUCT = YES; @@ -402,6 +429,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Collection/Collection-Prefix.pch"; INFOPLIST_FILE = "Collection/Collection-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -416,6 +444,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Collection/Collection-Prefix.pch"; INFOPLIST_FILE = "Collection/Collection-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -424,7 +453,6 @@ 53A5F8C717E3BA57000DB6B5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Collection.app/Collection"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", @@ -438,6 +466,7 @@ "$(inherited)", ); INFOPLIST_FILE = "CollectionTests/CollectionTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; @@ -447,7 +476,6 @@ 53A5F8C817E3BA57000DB6B5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Collection.app/Collection"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", @@ -457,6 +485,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Collection/Collection-Prefix.pch"; INFOPLIST_FILE = "CollectionTests/CollectionTests-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUNDLE_LOADER)"; WRAPPER_EXTENSION = xctest; diff --git a/Collection/Collection/Base.lproj/Main.storyboard b/Archive/Collection/Collection/Base.lproj/Main.storyboard similarity index 100% rename from Collection/Collection/Base.lproj/Main.storyboard rename to Archive/Collection/Collection/Base.lproj/Main.storyboard diff --git a/Collection/Collection/Collection-Info.plist b/Archive/Collection/Collection/Collection-Info.plist similarity index 94% rename from Collection/Collection/Collection-Info.plist rename to Archive/Collection/Collection/Collection-Info.plist index 6614037..f1c66e4 100644 --- a/Collection/Collection/Collection-Info.plist +++ b/Archive/Collection/Collection/Collection-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Collection/Collection/Collection-Prefix.pch b/Archive/Collection/Collection/Collection-Prefix.pch similarity index 100% rename from Collection/Collection/Collection-Prefix.pch rename to Archive/Collection/Collection/Collection-Prefix.pch diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/Contents.json b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 69% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/Contents.json rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/Contents.json index 55b6e38..8279c03 100644 --- a/Collection/Collection/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", @@ -35,6 +45,16 @@ "idiom" : "ipad", "filename" : "icon-76@2x.png", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29.png b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29.png similarity index 100% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29.png rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29.png diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29@2x.png b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29@2x.png similarity index 100% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29@2x.png rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-29@2x.png diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40.png b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40.png similarity index 100% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40.png rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40.png diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40@2x.png b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40@2x.png similarity index 100% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40@2x.png rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-40@2x.png diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76.png b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76.png similarity index 100% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76.png rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76.png diff --git a/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76@2x.png b/Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76@2x.png similarity index 100% rename from Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76@2x.png rename to Archive/Collection/Collection/Images.xcassets/AppIcon.appiconset/icon-76@2x.png diff --git a/Archive/Collection/Collection/Images.xcassets/Contents.json b/Archive/Collection/Collection/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Archive/Collection/Collection/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Contents.json b/Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Contents.json similarity index 100% rename from Collection/Collection/Images.xcassets/LaunchImage.launchimage/Contents.json rename to Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Contents.json index 2d612de..bc976a6 100644 --- a/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Contents.json +++ b/Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -3,33 +3,33 @@ { "orientation" : "portrait", "idiom" : "ipad", + "filename" : "Default-Portrait~ipad.png", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "Default-Portrait~ipad.png", "scale" : "1x" }, { "orientation" : "landscape", "idiom" : "ipad", + "filename" : "Default-Landscape~ipad.png", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "Default-Landscape~ipad.png", "scale" : "1x" }, { "orientation" : "portrait", "idiom" : "ipad", + "filename" : "Default-Portrait@2x~ipad.png", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "Default-Portrait@2x~ipad.png", "scale" : "2x" }, { "orientation" : "landscape", "idiom" : "ipad", + "filename" : "Default-Landscape@2x~ipad.png", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "Default-Landscape@2x~ipad.png", "scale" : "2x" } ], diff --git a/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x~ipad.png b/Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x~ipad.png similarity index 100% rename from Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x~ipad.png rename to Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape@2x~ipad.png diff --git a/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape~ipad.png b/Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape~ipad.png similarity index 100% rename from Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape~ipad.png rename to Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Landscape~ipad.png diff --git a/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x~ipad.png b/Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x~ipad.png similarity index 100% rename from Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x~ipad.png rename to Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait@2x~ipad.png diff --git a/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait~ipad.png b/Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait~ipad.png similarity index 100% rename from Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait~ipad.png rename to Archive/Collection/Collection/Images.xcassets/LaunchImage.launchimage/Default-Portrait~ipad.png diff --git a/Collection/Collection/UYLAppDelegate.h b/Archive/Collection/Collection/UYLAppDelegate.h similarity index 100% rename from Collection/Collection/UYLAppDelegate.h rename to Archive/Collection/Collection/UYLAppDelegate.h diff --git a/Collection/Collection/UYLAppDelegate.m b/Archive/Collection/Collection/UYLAppDelegate.m similarity index 100% rename from Collection/Collection/UYLAppDelegate.m rename to Archive/Collection/Collection/UYLAppDelegate.m diff --git a/Collection/Collection/UYLCollectionViewController.h b/Archive/Collection/Collection/UYLCollectionViewController.h similarity index 100% rename from Collection/Collection/UYLCollectionViewController.h rename to Archive/Collection/Collection/UYLCollectionViewController.h diff --git a/Collection/Collection/UYLCollectionViewController.m b/Archive/Collection/Collection/UYLCollectionViewController.m similarity index 100% rename from Collection/Collection/UYLCollectionViewController.m rename to Archive/Collection/Collection/UYLCollectionViewController.m diff --git a/Collection/Collection/UYLSimpleCell.h b/Archive/Collection/Collection/UYLSimpleCell.h similarity index 100% rename from Collection/Collection/UYLSimpleCell.h rename to Archive/Collection/Collection/UYLSimpleCell.h diff --git a/Collection/Collection/UYLSimpleCell.m b/Archive/Collection/Collection/UYLSimpleCell.m similarity index 100% rename from Collection/Collection/UYLSimpleCell.m rename to Archive/Collection/Collection/UYLSimpleCell.m diff --git a/Collection/Collection/UYLViewController.h b/Archive/Collection/Collection/UYLViewController.h similarity index 100% rename from Collection/Collection/UYLViewController.h rename to Archive/Collection/Collection/UYLViewController.h diff --git a/Collection/Collection/UYLViewController.m b/Archive/Collection/Collection/UYLViewController.m similarity index 100% rename from Collection/Collection/UYLViewController.m rename to Archive/Collection/Collection/UYLViewController.m diff --git a/Collection/Collection/en.lproj/InfoPlist.strings b/Archive/Collection/Collection/en.lproj/InfoPlist.strings similarity index 100% rename from Collection/Collection/en.lproj/InfoPlist.strings rename to Archive/Collection/Collection/en.lproj/InfoPlist.strings diff --git a/Collection/Collection/main.m b/Archive/Collection/Collection/main.m similarity index 100% rename from Collection/Collection/main.m rename to Archive/Collection/Collection/main.m diff --git a/Collection/CollectionTests/CollectionTests-Info.plist b/Archive/Collection/CollectionTests/CollectionTests-Info.plist similarity index 90% rename from Collection/CollectionTests/CollectionTests-Info.plist rename to Archive/Collection/CollectionTests/CollectionTests-Info.plist index 6dd5353..169b6f7 100644 --- a/Collection/CollectionTests/CollectionTests-Info.plist +++ b/Archive/Collection/CollectionTests/CollectionTests-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType diff --git a/Collection/CollectionTests/CollectionTests.m b/Archive/Collection/CollectionTests/CollectionTests.m similarity index 100% rename from Collection/CollectionTests/CollectionTests.m rename to Archive/Collection/CollectionTests/CollectionTests.m diff --git a/Collection/CollectionTests/en.lproj/InfoPlist.strings b/Archive/Collection/CollectionTests/en.lproj/InfoPlist.strings similarity index 100% rename from Collection/CollectionTests/en.lproj/InfoPlist.strings rename to Archive/Collection/CollectionTests/en.lproj/InfoPlist.strings diff --git a/Collection/README b/Archive/Collection/README similarity index 65% rename from Collection/README rename to Archive/Collection/README index 54a5631..9975405 100644 --- a/Collection/README +++ b/Archive/Collection/README @@ -4,11 +4,13 @@ Collection - A Simple Collection View Version 1.0 27 September 2013 Initial version. ======================================================================= +**THIS BUG WAS RESOLVED IN iOS 9.3** + This is a example project to reproduce a bug in the way that iOS 7 repostions popovers when a view is rotated. For further details see the following blog post: -http://useyourloaf.com/blog/2013/09/27/uipopover-arrow-not-repositioned-correctly-on-rotation.html +https://useyourloaf.com/blog/uipopover-arrow-not-repositioned-correctly-on-rotation/ -You can also view the bug report on Open Radar at http://openradar.appspot.com/14995477 \ No newline at end of file +You can also view the bug report on Open Radar at https://openradar.appspot.com/14995477 diff --git a/MasterSlide/MasterSlide.xcodeproj/project.pbxproj b/Archive/MasterSlide/MasterSlide.xcodeproj/project.pbxproj similarity index 81% rename from MasterSlide/MasterSlide.xcodeproj/project.pbxproj rename to Archive/MasterSlide/MasterSlide.xcodeproj/project.pbxproj index 148bd98..8383db9 100644 --- a/MasterSlide/MasterSlide.xcodeproj/project.pbxproj +++ b/Archive/MasterSlide/MasterSlide.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -21,6 +21,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5334609323CA65EF00BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLMasterViewController.xib; sourceTree = ""; }; + 5334609423CA65F000BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLDetailViewController.xib; sourceTree = ""; }; 53A7615E146C7E9600B4F8F6 /* masterslide.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = masterslide.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53A76162146C7E9600B4F8F6 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53A76164146C7E9600B4F8F6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -35,8 +37,6 @@ 53A76175146C7E9600B4F8F6 /* UYLMasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLMasterViewController.m; sourceTree = ""; }; 53A76177146C7E9600B4F8F6 /* UYLDetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLDetailViewController.h; sourceTree = ""; }; 53A76178146C7E9600B4F8F6 /* UYLDetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLDetailViewController.m; sourceTree = ""; }; - 53A7617B146C7E9700B4F8F6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLMasterViewController.xib; sourceTree = ""; }; - 53A7617E146C7E9700B4F8F6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLDetailViewController.xib; sourceTree = ""; }; 53FF8C18146F264400005E54 /* MainWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; /* End PBXFileReference section */ @@ -151,14 +151,15 @@ 53A76155146C7E9600B4F8F6 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 1120; }; - buildConfigurationList = 53A76158146C7E9600B4F8F6 /* Build configuration list for PBXProject "masterslide" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + buildConfigurationList = 53A76158146C7E9600B4F8F6 /* Build configuration list for PBXProject "MasterSlide" */; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 53A76153146C7E9600B4F8F6; productRefGroup = 53A7615F146C7E9600B4F8F6 /* Products */; @@ -210,7 +211,7 @@ 53A7617A146C7E9700B4F8F6 /* UYLMasterViewController.xib */ = { isa = PBXVariantGroup; children = ( - 53A7617B146C7E9700B4F8F6 /* en */, + 5334609323CA65EF00BE943E /* Base */, ); name = UYLMasterViewController.xib; sourceTree = ""; @@ -218,7 +219,7 @@ 53A7617D146C7E9700B4F8F6 /* UYLDetailViewController.xib */ = { isa = PBXVariantGroup; children = ( - 53A7617E146C7E9700B4F8F6 /* en */, + 5334609423CA65F000BE943E /* Base */, ); name = UYLDetailViewController.xib; sourceTree = ""; @@ -230,11 +231,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -242,10 +263,15 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 2; }; @@ -255,15 +281,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 2; @@ -274,9 +323,11 @@ 53A76183146C7E9700B4F8F6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "masterslide/masterslide-Prefix.pch"; INFOPLIST_FILE = "masterslide/masterslide-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -285,9 +336,11 @@ 53A76184146C7E9700B4F8F6 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "masterslide/masterslide-Prefix.pch"; INFOPLIST_FILE = "masterslide/masterslide-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -296,7 +349,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 53A76158146C7E9600B4F8F6 /* Build configuration list for PBXProject "masterslide" */ = { + 53A76158146C7E9600B4F8F6 /* Build configuration list for PBXProject "MasterSlide" */ = { isa = XCConfigurationList; buildConfigurations = ( 53A76180146C7E9700B4F8F6 /* Debug */, diff --git a/Archive/MasterSlide/MasterSlide/Base.lproj/UYLDetailViewController.xib b/Archive/MasterSlide/MasterSlide/Base.lproj/UYLDetailViewController.xib new file mode 100644 index 0000000..4f045c5 --- /dev/null +++ b/Archive/MasterSlide/MasterSlide/Base.lproj/UYLDetailViewController.xib @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/MasterSlide/MasterSlide/Base.lproj/UYLMasterViewController.xib b/Archive/MasterSlide/MasterSlide/Base.lproj/UYLMasterViewController.xib new file mode 100644 index 0000000..77a8e58 --- /dev/null +++ b/Archive/MasterSlide/MasterSlide/Base.lproj/UYLMasterViewController.xib @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/MasterSlide/MasterSlide/MainWindow.xib b/Archive/MasterSlide/MasterSlide/MainWindow.xib new file mode 100644 index 0000000..dc9f4e1 --- /dev/null +++ b/Archive/MasterSlide/MasterSlide/MainWindow.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MasterSlide/MasterSlide/MasterSlide-Info.plist b/Archive/MasterSlide/MasterSlide/MasterSlide-Info.plist similarity index 95% rename from MasterSlide/MasterSlide/MasterSlide-Info.plist rename to Archive/MasterSlide/MasterSlide/MasterSlide-Info.plist index 410100c..7d691bc 100644 --- a/MasterSlide/MasterSlide/MasterSlide-Info.plist +++ b/Archive/MasterSlide/MasterSlide/MasterSlide-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFiles CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -26,6 +26,8 @@ 1.0 LSRequiresIPhoneOS + NSMainNibFile + MainWindow UIRequiredDeviceCapabilities armv7 @@ -43,7 +45,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - NSMainNibFile - MainWindow diff --git a/MasterSlide/MasterSlide/MasterSlide-Prefix.pch b/Archive/MasterSlide/MasterSlide/MasterSlide-Prefix.pch similarity index 100% rename from MasterSlide/MasterSlide/MasterSlide-Prefix.pch rename to Archive/MasterSlide/MasterSlide/MasterSlide-Prefix.pch diff --git a/MasterSlide/MasterSlide/UYLAppDelegate.h b/Archive/MasterSlide/MasterSlide/UYLAppDelegate.h similarity index 100% rename from MasterSlide/MasterSlide/UYLAppDelegate.h rename to Archive/MasterSlide/MasterSlide/UYLAppDelegate.h diff --git a/MasterSlide/MasterSlide/UYLAppDelegate.m b/Archive/MasterSlide/MasterSlide/UYLAppDelegate.m similarity index 100% rename from MasterSlide/MasterSlide/UYLAppDelegate.m rename to Archive/MasterSlide/MasterSlide/UYLAppDelegate.m diff --git a/MasterSlide/MasterSlide/UYLDetailViewController.h b/Archive/MasterSlide/MasterSlide/UYLDetailViewController.h similarity index 100% rename from MasterSlide/MasterSlide/UYLDetailViewController.h rename to Archive/MasterSlide/MasterSlide/UYLDetailViewController.h diff --git a/MasterSlide/MasterSlide/UYLDetailViewController.m b/Archive/MasterSlide/MasterSlide/UYLDetailViewController.m similarity index 100% rename from MasterSlide/MasterSlide/UYLDetailViewController.m rename to Archive/MasterSlide/MasterSlide/UYLDetailViewController.m diff --git a/MasterSlide/MasterSlide/UYLMasterViewController.h b/Archive/MasterSlide/MasterSlide/UYLMasterViewController.h similarity index 100% rename from MasterSlide/MasterSlide/UYLMasterViewController.h rename to Archive/MasterSlide/MasterSlide/UYLMasterViewController.h diff --git a/MasterSlide/MasterSlide/UYLMasterViewController.m b/Archive/MasterSlide/MasterSlide/UYLMasterViewController.m similarity index 100% rename from MasterSlide/MasterSlide/UYLMasterViewController.m rename to Archive/MasterSlide/MasterSlide/UYLMasterViewController.m diff --git a/DynamicText/DynamicTextTests/en.lproj/InfoPlist.strings b/Archive/MasterSlide/MasterSlide/en.lproj/InfoPlist.strings similarity index 100% rename from DynamicText/DynamicTextTests/en.lproj/InfoPlist.strings rename to Archive/MasterSlide/MasterSlide/en.lproj/InfoPlist.strings diff --git a/MasterSlide/MasterSlide/main.m b/Archive/MasterSlide/MasterSlide/main.m similarity index 100% rename from MasterSlide/MasterSlide/main.m rename to Archive/MasterSlide/MasterSlide/main.m diff --git a/RemindMe/Base.lproj/Localizable.strings b/Archive/RemindMe/Base.lproj/Localizable.strings similarity index 100% rename from RemindMe/Base.lproj/Localizable.strings rename to Archive/RemindMe/Base.lproj/Localizable.strings diff --git a/RemindMe/Base.lproj/Main.storyboard b/Archive/RemindMe/Base.lproj/Main.storyboard similarity index 76% rename from RemindMe/Base.lproj/Main.storyboard rename to Archive/RemindMe/Base.lproj/Main.storyboard index 9994924..d10e6fb 100644 --- a/RemindMe/Base.lproj/Main.storyboard +++ b/Archive/RemindMe/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - - + + + - - + @@ -19,24 +19,25 @@ - - + + + - diff --git a/RemindMe/Classes/AppDelegate.h b/Archive/RemindMe/Classes/AppDelegate.h similarity index 100% rename from RemindMe/Classes/AppDelegate.h rename to Archive/RemindMe/Classes/AppDelegate.h diff --git a/RemindMe/Classes/AppDelegate.m b/Archive/RemindMe/Classes/AppDelegate.m similarity index 100% rename from RemindMe/Classes/AppDelegate.m rename to Archive/RemindMe/Classes/AppDelegate.m diff --git a/RemindMe/Classes/RemindMeViewController.h b/Archive/RemindMe/Classes/RemindMeViewController.h similarity index 100% rename from RemindMe/Classes/RemindMeViewController.h rename to Archive/RemindMe/Classes/RemindMeViewController.h diff --git a/RemindMe/Classes/RemindMeViewController.m b/Archive/RemindMe/Classes/RemindMeViewController.m similarity index 100% rename from RemindMe/Classes/RemindMeViewController.m rename to Archive/RemindMe/Classes/RemindMeViewController.m diff --git a/RemindMe/Info.plist b/Archive/RemindMe/Info.plist similarity index 100% rename from RemindMe/Info.plist rename to Archive/RemindMe/Info.plist diff --git a/RemindMe/LaunchScreen.storyboard b/Archive/RemindMe/LaunchScreen.storyboard similarity index 100% rename from RemindMe/LaunchScreen.storyboard rename to Archive/RemindMe/LaunchScreen.storyboard diff --git a/RemindMe/README.md b/Archive/RemindMe/README.md similarity index 61% rename from RemindMe/README.md rename to Archive/RemindMe/README.md index 4292e86..fe0054d 100644 --- a/RemindMe/README.md +++ b/Archive/RemindMe/README.md @@ -8,5 +8,5 @@ The RemindMe App is a demonstration on how to schedule local notifications using The original posts were written for iOS 4 a long time ago: -+ [Repeating an iOS local notification](http://useyourloaf.com/blog/repeating-an-ios-local-notification/) -+ [Add Local Notification with iOS 4](http://useyourloaf.com/blog/adding-local-notifications-with-ios-4/) ++ [Repeating an iOS local notification](https://useyourloaf.com/blog/repeating-an-ios-local-notification/) ++ [Add Local Notification with iOS 4](https://useyourloaf.com/blog/adding-local-notifications-with-ios-4/) diff --git a/RemindMe/RemindMe.xcodeproj/project.pbxproj b/Archive/RemindMe/RemindMe.xcodeproj/project.pbxproj similarity index 92% rename from RemindMe/RemindMe.xcodeproj/project.pbxproj rename to Archive/RemindMe/RemindMe.xcodeproj/project.pbxproj index b3bbd79..f12800f 100755 --- a/RemindMe/RemindMe.xcodeproj/project.pbxproj +++ b/Archive/RemindMe/RemindMe.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 47; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -119,7 +119,7 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 1D6058900D05DD3D006BFB54 = { @@ -129,15 +129,12 @@ }; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "RemindMe" */; - compatibilityVersion = "Xcode 6.3"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 1; knownRegions = ( - English, - Japanese, - French, - German, Base, + en, ); mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; projectDirPath = ""; @@ -238,11 +235,21 @@ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -268,11 +275,21 @@ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; diff --git a/RemindMe/RemindMe/Images.xcassets/AppIcon.appiconset/Contents.json b/Archive/RemindMe/RemindMe/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from RemindMe/RemindMe/Images.xcassets/AppIcon.appiconset/Contents.json rename to Archive/RemindMe/RemindMe/Images.xcassets/AppIcon.appiconset/Contents.json diff --git a/Archive/RemindMe/RemindMe/Images.xcassets/Contents.json b/Archive/RemindMe/RemindMe/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Archive/RemindMe/RemindMe/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RemindMe/main.m b/Archive/RemindMe/main.m similarity index 100% rename from RemindMe/main.m rename to Archive/RemindMe/main.m diff --git a/StaticTable/README.markdown b/Archive/StaticTable/README.markdown similarity index 100% rename from StaticTable/README.markdown rename to Archive/StaticTable/README.markdown diff --git a/StaticTable/StaticTable.xcodeproj/project.pbxproj b/Archive/StaticTable/StaticTable.xcodeproj/project.pbxproj similarity index 87% rename from StaticTable/StaticTable.xcodeproj/project.pbxproj rename to Archive/StaticTable/StaticTable.xcodeproj/project.pbxproj index bb3438f..e8d0a88 100644 --- a/StaticTable/StaticTable.xcodeproj/project.pbxproj +++ b/Archive/StaticTable/StaticTable.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -42,7 +42,7 @@ 532B11F7154F362C004B4780 /* second.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = second.png; sourceTree = ""; }; 532B11F9154F362C004B4780 /* second@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "second@2x.png"; sourceTree = ""; }; 532B1206154F3712004B4780 /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = ""; }; - 53ACC43215582581005E26DC /* README.markdown */ = {isa = PBXFileReference; fileEncoding = 4; path = README.markdown; sourceTree = ""; }; + 53ACC43215582581005E26DC /* README.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.markdown; sourceTree = ""; }; 53F33DE215508DBE0094277E /* UYLGeneralSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLGeneralSettingsTableViewController.h; sourceTree = ""; }; 53F33DE315508DBE0094277E /* UYLGeneralSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLGeneralSettingsTableViewController.m; sourceTree = ""; }; 53F33DE915509B360094277E /* UYLAdvancedSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLAdvancedSettingsViewController.h; sourceTree = ""; }; @@ -190,14 +190,15 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0430; + LastUpgradeCheck = 1120; }; buildConfigurationList = 532B11D1154F362C004B4780 /* Build configuration list for PBXProject "StaticTable" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 532B11CC154F362C004B4780; productRefGroup = 532B11D8154F362C004B4780 /* Products */; @@ -259,12 +260,32 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -272,10 +293,14 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -284,16 +309,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -306,6 +353,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "StaticTable/StaticTable-Prefix.pch"; INFOPLIST_FILE = "StaticTable/StaticTable-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -317,6 +365,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "StaticTable/StaticTable-Prefix.pch"; INFOPLIST_FILE = "StaticTable/StaticTable-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/StaticTable/StaticTable/Settings.storyboard b/Archive/StaticTable/StaticTable/Settings.storyboard similarity index 70% rename from StaticTable/StaticTable/Settings.storyboard rename to Archive/StaticTable/StaticTable/Settings.storyboard index 9a8474f..bd38de0 100644 --- a/StaticTable/StaticTable/Settings.storyboard +++ b/Archive/StaticTable/StaticTable/Settings.storyboard @@ -1,140 +1,136 @@ - - + + + - - - + + + - + - - - + + - + - - + + - - + + - - - + - + - - + + - - + + - - - + - + - - + + - - + + - - - + - + - - + + - - + + - - - + @@ -154,132 +150,126 @@ + - + - + - - - + + - + - - + + - - - + - + - - + + - - - + - + - - + + - - - + - + - - + + - - - + - + - - + + - - - + - + - - + + - - - + @@ -291,17 +281,17 @@ + - + - - + @@ -309,38 +299,37 @@ + - + - + - - - + + - + - - + + - - - + @@ -350,22 +339,21 @@ - + - - + + - - - + @@ -380,34 +368,9 @@ + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/StaticTable/StaticTable/StaticTable-Info.plist b/Archive/StaticTable/StaticTable/StaticTable-Info.plist similarity index 94% rename from StaticTable/StaticTable/StaticTable-Info.plist rename to Archive/StaticTable/StaticTable/StaticTable-Info.plist index 408dd6d..9989d33 100644 --- a/StaticTable/StaticTable/StaticTable-Info.plist +++ b/Archive/StaticTable/StaticTable/StaticTable-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/StaticTable/StaticTable/StaticTable-Prefix.pch b/Archive/StaticTable/StaticTable/StaticTable-Prefix.pch similarity index 100% rename from StaticTable/StaticTable/StaticTable-Prefix.pch rename to Archive/StaticTable/StaticTable/StaticTable-Prefix.pch diff --git a/StaticTable/StaticTable/UYLAdvancedSettingsViewController.h b/Archive/StaticTable/StaticTable/UYLAdvancedSettingsViewController.h similarity index 100% rename from StaticTable/StaticTable/UYLAdvancedSettingsViewController.h rename to Archive/StaticTable/StaticTable/UYLAdvancedSettingsViewController.h diff --git a/StaticTable/StaticTable/UYLAdvancedSettingsViewController.m b/Archive/StaticTable/StaticTable/UYLAdvancedSettingsViewController.m similarity index 100% rename from StaticTable/StaticTable/UYLAdvancedSettingsViewController.m rename to Archive/StaticTable/StaticTable/UYLAdvancedSettingsViewController.m diff --git a/StaticTable/StaticTable/UYLAppDelegate.h b/Archive/StaticTable/StaticTable/UYLAppDelegate.h similarity index 100% rename from StaticTable/StaticTable/UYLAppDelegate.h rename to Archive/StaticTable/StaticTable/UYLAppDelegate.h diff --git a/StaticTable/StaticTable/UYLAppDelegate.m b/Archive/StaticTable/StaticTable/UYLAppDelegate.m similarity index 100% rename from StaticTable/StaticTable/UYLAppDelegate.m rename to Archive/StaticTable/StaticTable/UYLAppDelegate.m diff --git a/StaticTable/StaticTable/UYLFirstViewController.h b/Archive/StaticTable/StaticTable/UYLFirstViewController.h similarity index 100% rename from StaticTable/StaticTable/UYLFirstViewController.h rename to Archive/StaticTable/StaticTable/UYLFirstViewController.h diff --git a/StaticTable/StaticTable/UYLFirstViewController.m b/Archive/StaticTable/StaticTable/UYLFirstViewController.m similarity index 100% rename from StaticTable/StaticTable/UYLFirstViewController.m rename to Archive/StaticTable/StaticTable/UYLFirstViewController.m diff --git a/Archive/StaticTable/StaticTable/UYLFirstViewController.xib b/Archive/StaticTable/StaticTable/UYLFirstViewController.xib new file mode 100644 index 0000000..8325205 --- /dev/null +++ b/Archive/StaticTable/StaticTable/UYLFirstViewController.xib @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StaticTable/StaticTable/UYLGeneralSettingsTableViewController.h b/Archive/StaticTable/StaticTable/UYLGeneralSettingsTableViewController.h similarity index 100% rename from StaticTable/StaticTable/UYLGeneralSettingsTableViewController.h rename to Archive/StaticTable/StaticTable/UYLGeneralSettingsTableViewController.h diff --git a/StaticTable/StaticTable/UYLGeneralSettingsTableViewController.m b/Archive/StaticTable/StaticTable/UYLGeneralSettingsTableViewController.m similarity index 100% rename from StaticTable/StaticTable/UYLGeneralSettingsTableViewController.m rename to Archive/StaticTable/StaticTable/UYLGeneralSettingsTableViewController.m diff --git a/StaticTable/StaticTable/UYLRotatingTableViewController.h b/Archive/StaticTable/StaticTable/UYLRotatingTableViewController.h similarity index 100% rename from StaticTable/StaticTable/UYLRotatingTableViewController.h rename to Archive/StaticTable/StaticTable/UYLRotatingTableViewController.h diff --git a/StaticTable/StaticTable/UYLRotatingTableViewController.m b/Archive/StaticTable/StaticTable/UYLRotatingTableViewController.m similarity index 100% rename from StaticTable/StaticTable/UYLRotatingTableViewController.m rename to Archive/StaticTable/StaticTable/UYLRotatingTableViewController.m diff --git a/MasterSlide/MasterSlide/en.lproj/InfoPlist.strings b/Archive/StaticTable/StaticTable/en.lproj/InfoPlist.strings similarity index 100% rename from MasterSlide/MasterSlide/en.lproj/InfoPlist.strings rename to Archive/StaticTable/StaticTable/en.lproj/InfoPlist.strings diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first.png b/Archive/StaticTable/StaticTable/first.png similarity index 100% rename from DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first.png rename to Archive/StaticTable/StaticTable/first.png diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first@2x.png b/Archive/StaticTable/StaticTable/first@2x.png similarity index 100% rename from DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first@2x.png rename to Archive/StaticTable/StaticTable/first@2x.png diff --git a/StaticTable/StaticTable/main.m b/Archive/StaticTable/StaticTable/main.m similarity index 100% rename from StaticTable/StaticTable/main.m rename to Archive/StaticTable/StaticTable/main.m diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second.png b/Archive/StaticTable/StaticTable/second.png similarity index 100% rename from DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second.png rename to Archive/StaticTable/StaticTable/second.png diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second@2x.png b/Archive/StaticTable/StaticTable/second@2x.png similarity index 100% rename from DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second@2x.png rename to Archive/StaticTable/StaticTable/second@2x.png diff --git a/Stepper/Stepper.xcodeproj/project.pbxproj b/Archive/Stepper/Stepper.xcodeproj/project.pbxproj similarity index 81% rename from Stepper/Stepper.xcodeproj/project.pbxproj rename to Archive/Stepper/Stepper.xcodeproj/project.pbxproj index 3056532..9e328cf 100644 --- a/Stepper/Stepper.xcodeproj/project.pbxproj +++ b/Archive/Stepper/Stepper.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5334608F23CA627F00BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLViewController.xib; sourceTree = ""; }; 53CA1FB714B3B08500432C8E /* Stepper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stepper.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53CA1FBB14B3B08500432C8E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53CA1FBD14B3B08500432C8E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -30,7 +31,6 @@ 53CA1FCB14B3B08500432C8E /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 53CA1FCD14B3B08500432C8E /* UYLViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLViewController.h; sourceTree = ""; }; 53CA1FCE14B3B08500432C8E /* UYLViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLViewController.m; sourceTree = ""; }; - 53CA1FD114B3B08500432C8E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLViewController.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -124,14 +124,15 @@ 53CA1FAE14B3B08500432C8E /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; + LastUpgradeCheck = 1120; }; buildConfigurationList = 53CA1FB114B3B08500432C8E /* Build configuration list for PBXProject "Stepper" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 53CA1FAC14B3B08500432C8E; productRefGroup = 53CA1FB814B3B08500432C8E /* Products */; @@ -180,7 +181,7 @@ 53CA1FD014B3B08500432C8E /* UYLViewController.xib */ = { isa = PBXVariantGroup; children = ( - 53CA1FD114B3B08500432C8E /* en */, + 5334608F23CA627F00BE943E /* Base */, ); name = UYLViewController.xib; sourceTree = ""; @@ -192,11 +193,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -204,10 +225,15 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -216,15 +242,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -238,6 +287,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Stepper/Stepper-Prefix.pch"; INFOPLIST_FILE = "Stepper/Stepper-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -250,6 +300,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Stepper/Stepper-Prefix.pch"; INFOPLIST_FILE = "Stepper/Stepper-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Archive/Stepper/Stepper/Base.lproj/UYLViewController.xib b/Archive/Stepper/Stepper/Base.lproj/UYLViewController.xib new file mode 100644 index 0000000..e957a6e --- /dev/null +++ b/Archive/Stepper/Stepper/Base.lproj/UYLViewController.xib @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Stepper/Stepper/Stepper-Info.plist b/Archive/Stepper/Stepper/Stepper-Info.plist similarity index 94% rename from Stepper/Stepper/Stepper-Info.plist rename to Archive/Stepper/Stepper/Stepper-Info.plist index 82d3103..a5a6331 100644 --- a/Stepper/Stepper/Stepper-Info.plist +++ b/Archive/Stepper/Stepper/Stepper-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFiles CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/Stepper/Stepper/Stepper-Prefix.pch b/Archive/Stepper/Stepper/Stepper-Prefix.pch similarity index 100% rename from Stepper/Stepper/Stepper-Prefix.pch rename to Archive/Stepper/Stepper/Stepper-Prefix.pch diff --git a/Stepper/Stepper/UYLAppDelegate.h b/Archive/Stepper/Stepper/UYLAppDelegate.h similarity index 100% rename from Stepper/Stepper/UYLAppDelegate.h rename to Archive/Stepper/Stepper/UYLAppDelegate.h diff --git a/Stepper/Stepper/UYLAppDelegate.m b/Archive/Stepper/Stepper/UYLAppDelegate.m similarity index 100% rename from Stepper/Stepper/UYLAppDelegate.m rename to Archive/Stepper/Stepper/UYLAppDelegate.m diff --git a/Stepper/Stepper/UYLViewController.h b/Archive/Stepper/Stepper/UYLViewController.h similarity index 100% rename from Stepper/Stepper/UYLViewController.h rename to Archive/Stepper/Stepper/UYLViewController.h diff --git a/Stepper/Stepper/UYLViewController.m b/Archive/Stepper/Stepper/UYLViewController.m similarity index 100% rename from Stepper/Stepper/UYLViewController.m rename to Archive/Stepper/Stepper/UYLViewController.m diff --git a/Refresh/Refresh/en.lproj/InfoPlist.strings b/Archive/Stepper/Stepper/en.lproj/InfoPlist.strings similarity index 100% rename from Refresh/Refresh/en.lproj/InfoPlist.strings rename to Archive/Stepper/Stepper/en.lproj/InfoPlist.strings diff --git a/Stepper/Stepper/main.m b/Archive/Stepper/Stepper/main.m similarity index 100% rename from Stepper/Stepper/main.m rename to Archive/Stepper/Stepper/main.m diff --git a/Styles/README b/Archive/Styles/README similarity index 94% rename from Styles/README rename to Archive/Styles/README index 463bf10..029456c 100644 --- a/Styles/README +++ b/Archive/Styles/README @@ -9,7 +9,7 @@ customise the appearance of common UIKit controls. For further details see: -useyourloaf.com/blog/2012/08/24/using-appearance-proxy-to-style-apps.html +useyourloaf.com/blog/using-appearance-proxy-to-style-apps/ ======================================================================= @@ -68,4 +68,4 @@ UYLRotatingViewController.h UYLRotatingViewController.m This is a container class used for all of the UIKit control views. The viewDidLoad method is used to set the view background. It also implements -the standard method to enable interface orientation. \ No newline at end of file +the standard method to enable interface orientation. diff --git a/Styles/Styles.xcodeproj/project.pbxproj b/Archive/Styles/Styles.xcodeproj/project.pbxproj similarity index 88% rename from Styles/Styles.xcodeproj/project.pbxproj rename to Archive/Styles/Styles.xcodeproj/project.pbxproj index 26e39d7..f63390f 100644 --- a/Styles/Styles.xcodeproj/project.pbxproj +++ b/Archive/Styles/Styles.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -13,6 +13,7 @@ 532F266715BDDF7A00321881 /* UYLRotatingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 532F266615BDDF7A00321881 /* UYLRotatingViewController.m */; }; 532F267915BDE44F00321881 /* UYLResetButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 532F267815BDE44F00321881 /* UYLResetButton.m */; }; 532F267C15BDEAEB00321881 /* UYLStyleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 532F267B15BDEAEB00321881 /* UYLStyleController.m */; }; + 5334608A23CA316E00BE943E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5334608923CA316E00BE943E /* LaunchScreen.storyboard */; }; 535734EA15B75876006F0E6A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 535734E915B75876006F0E6A /* UIKit.framework */; }; 535734EC15B75876006F0E6A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 535734EB15B75876006F0E6A /* Foundation.framework */; }; 535734EE15B75876006F0E6A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 535734ED15B75876006F0E6A /* CoreGraphics.framework */; }; @@ -51,6 +52,8 @@ 532F267815BDE44F00321881 /* UYLResetButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLResetButton.m; sourceTree = ""; }; 532F267A15BDEAEA00321881 /* UYLStyleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLStyleController.h; sourceTree = ""; }; 532F267B15BDEAEB00321881 /* UYLStyleController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLStyleController.m; sourceTree = ""; }; + 5334608823CA30B700BE943E /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; + 5334608923CA316E00BE943E /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 535734E515B75876006F0E6A /* Styles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Styles.app; sourceTree = BUILT_PRODUCTS_DIR; }; 535734E915B75876006F0E6A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 535734EB15B75876006F0E6A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -101,6 +104,7 @@ 535734DA15B75875006F0E6A = { isa = PBXGroup; children = ( + 5334608823CA30B700BE943E /* README */, 535734EF15B75876006F0E6A /* Styles */, 535734E815B75876006F0E6A /* Frameworks */, 535734E615B75876006F0E6A /* Products */, @@ -145,6 +149,7 @@ 535734F215B75876006F0E6A /* InfoPlist.strings */, 535734F515B75877006F0E6A /* main.m */, 535734F715B75877006F0E6A /* Styles-Prefix.pch */, + 5334608923CA316E00BE943E /* LaunchScreen.storyboard */, ); name = "Supporting Files"; sourceTree = ""; @@ -228,14 +233,15 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0430; + LastUpgradeCheck = 1120; }; buildConfigurationList = 535734DF15B75875006F0E6A /* Build configuration list for PBXProject "Styles" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 535734DA15B75875006F0E6A; productRefGroup = 535734E615B75876006F0E6A /* Products */; @@ -270,6 +276,7 @@ 53AA527915E58E9B000C8D04 /* back-button@2x.png in Resources */, 53AA527C15E591BF000C8D04 /* back-button-landscape.png in Resources */, 53AA527D15E591BF000C8D04 /* back-button-landscape@2x.png in Resources */, + 5334608A23CA316E00BE943E /* LaunchScreen.storyboard in Resources */, 5305B54615E6408500AC81F4 /* divider.png in Resources */, 5305B54715E6408500AC81F4 /* divider@2x.png in Resources */, ); @@ -311,12 +318,32 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -324,10 +351,14 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -336,16 +367,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -355,9 +408,11 @@ 5357350F15B75878006F0E6A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Styles/Styles-Prefix.pch"; INFOPLIST_FILE = "Styles/Styles-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -366,9 +421,11 @@ 5357351015B75878006F0E6A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Styles/Styles-Prefix.pch"; INFOPLIST_FILE = "Styles/Styles-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Archive/Styles/Styles/LaunchScreen.storyboard b/Archive/Styles/Styles/LaunchScreen.storyboard new file mode 100644 index 0000000..06d6044 --- /dev/null +++ b/Archive/Styles/Styles/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Styles/Styles/MainStoryboard.storyboard b/Archive/Styles/Styles/MainStoryboard.storyboard similarity index 66% rename from Styles/Styles/MainStoryboard.storyboard rename to Archive/Styles/Styles/MainStoryboard.storyboard index 494f317..e0db02c 100644 --- a/Styles/Styles/MainStoryboard.storyboard +++ b/Archive/Styles/Styles/MainStoryboard.storyboard @@ -1,123 +1,119 @@ - - + + + - - + + + - + - - - + + - + - - + + - - + - + - - + + - - + - + - - + + - - + - + - - + + - - + - + - - + + - - + @@ -132,45 +128,49 @@ + - + - + - + + + + - + - - + + - - + + - + - + - + + + + - + - - - - - - - - - - - - - + + - + - + - - + @@ -374,23 +366,27 @@ + - + - + - + + + + - + - - + + - - + + - + - + - + + + + - + - - + + @@ -423,79 +423,62 @@ - + + - + - + - + + + + - + - - + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/Styles/Styles/Resources/back-button-landscape.png b/Archive/Styles/Styles/Resources/back-button-landscape.png similarity index 100% rename from Styles/Styles/Resources/back-button-landscape.png rename to Archive/Styles/Styles/Resources/back-button-landscape.png diff --git a/Styles/Styles/Resources/back-button-landscape@2x.png b/Archive/Styles/Styles/Resources/back-button-landscape@2x.png similarity index 100% rename from Styles/Styles/Resources/back-button-landscape@2x.png rename to Archive/Styles/Styles/Resources/back-button-landscape@2x.png diff --git a/Styles/Styles/Resources/back-button.png b/Archive/Styles/Styles/Resources/back-button.png similarity index 100% rename from Styles/Styles/Resources/back-button.png rename to Archive/Styles/Styles/Resources/back-button.png diff --git a/Styles/Styles/Resources/back-button@2x.png b/Archive/Styles/Styles/Resources/back-button@2x.png similarity index 100% rename from Styles/Styles/Resources/back-button@2x.png rename to Archive/Styles/Styles/Resources/back-button@2x.png diff --git a/Styles/Styles/Resources/divider.png b/Archive/Styles/Styles/Resources/divider.png similarity index 100% rename from Styles/Styles/Resources/divider.png rename to Archive/Styles/Styles/Resources/divider.png diff --git a/Styles/Styles/Resources/divider@2x.png b/Archive/Styles/Styles/Resources/divider@2x.png similarity index 100% rename from Styles/Styles/Resources/divider@2x.png rename to Archive/Styles/Styles/Resources/divider@2x.png diff --git a/Styles/Styles/Resources/green-button.png b/Archive/Styles/Styles/Resources/green-button.png similarity index 100% rename from Styles/Styles/Resources/green-button.png rename to Archive/Styles/Styles/Resources/green-button.png diff --git a/Styles/Styles/Resources/green-button@2x.png b/Archive/Styles/Styles/Resources/green-button@2x.png similarity index 100% rename from Styles/Styles/Resources/green-button@2x.png rename to Archive/Styles/Styles/Resources/green-button@2x.png diff --git a/Styles/Styles/Resources/navbar-landscape.png b/Archive/Styles/Styles/Resources/navbar-landscape.png similarity index 100% rename from Styles/Styles/Resources/navbar-landscape.png rename to Archive/Styles/Styles/Resources/navbar-landscape.png diff --git a/Styles/Styles/Resources/navbar-landscape@2x.png b/Archive/Styles/Styles/Resources/navbar-landscape@2x.png similarity index 100% rename from Styles/Styles/Resources/navbar-landscape@2x.png rename to Archive/Styles/Styles/Resources/navbar-landscape@2x.png diff --git a/Styles/Styles/Resources/navbar.png b/Archive/Styles/Styles/Resources/navbar.png similarity index 100% rename from Styles/Styles/Resources/navbar.png rename to Archive/Styles/Styles/Resources/navbar.png diff --git a/Styles/Styles/Resources/navbar@2x.png b/Archive/Styles/Styles/Resources/navbar@2x.png similarity index 100% rename from Styles/Styles/Resources/navbar@2x.png rename to Archive/Styles/Styles/Resources/navbar@2x.png diff --git a/Styles/Styles/Resources/orange-button.png b/Archive/Styles/Styles/Resources/orange-button.png similarity index 100% rename from Styles/Styles/Resources/orange-button.png rename to Archive/Styles/Styles/Resources/orange-button.png diff --git a/Styles/Styles/Resources/orange-button@2x.png b/Archive/Styles/Styles/Resources/orange-button@2x.png similarity index 100% rename from Styles/Styles/Resources/orange-button@2x.png rename to Archive/Styles/Styles/Resources/orange-button@2x.png diff --git a/Styles/Styles/Resources/orange.png b/Archive/Styles/Styles/Resources/orange.png similarity index 100% rename from Styles/Styles/Resources/orange.png rename to Archive/Styles/Styles/Resources/orange.png diff --git a/Styles/Styles/Resources/orange@2x.png b/Archive/Styles/Styles/Resources/orange@2x.png similarity index 100% rename from Styles/Styles/Resources/orange@2x.png rename to Archive/Styles/Styles/Resources/orange@2x.png diff --git a/Styles/Styles/Resources/red-button.png b/Archive/Styles/Styles/Resources/red-button.png similarity index 100% rename from Styles/Styles/Resources/red-button.png rename to Archive/Styles/Styles/Resources/red-button.png diff --git a/Styles/Styles/Resources/red-button@2x.png b/Archive/Styles/Styles/Resources/red-button@2x.png similarity index 100% rename from Styles/Styles/Resources/red-button@2x.png rename to Archive/Styles/Styles/Resources/red-button@2x.png diff --git a/Styles/Styles/Resources/steel-button.png b/Archive/Styles/Styles/Resources/steel-button.png similarity index 100% rename from Styles/Styles/Resources/steel-button.png rename to Archive/Styles/Styles/Resources/steel-button.png diff --git a/Styles/Styles/Resources/steel-button@2x.png b/Archive/Styles/Styles/Resources/steel-button@2x.png similarity index 100% rename from Styles/Styles/Resources/steel-button@2x.png rename to Archive/Styles/Styles/Resources/steel-button@2x.png diff --git a/Styles/Styles/Styles-Info.plist b/Archive/Styles/Styles/Styles-Info.plist similarity index 91% rename from Styles/Styles/Styles-Info.plist rename to Archive/Styles/Styles/Styles-Info.plist index faa11bb..66a4d0c 100644 --- a/Styles/Styles/Styles-Info.plist +++ b/Archive/Styles/Styles/Styles-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +24,8 @@ 1.0 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile MainStoryboard UIRequiredDeviceCapabilities diff --git a/Styles/Styles/Styles-Prefix.pch b/Archive/Styles/Styles/Styles-Prefix.pch similarity index 100% rename from Styles/Styles/Styles-Prefix.pch rename to Archive/Styles/Styles/Styles-Prefix.pch diff --git a/Styles/Styles/UYLAppDelegate.h b/Archive/Styles/Styles/UYLAppDelegate.h similarity index 100% rename from Styles/Styles/UYLAppDelegate.h rename to Archive/Styles/Styles/UYLAppDelegate.h diff --git a/Styles/Styles/UYLAppDelegate.m b/Archive/Styles/Styles/UYLAppDelegate.m similarity index 100% rename from Styles/Styles/UYLAppDelegate.m rename to Archive/Styles/Styles/UYLAppDelegate.m diff --git a/Styles/Styles/UYLListViewController.h b/Archive/Styles/Styles/UYLListViewController.h similarity index 100% rename from Styles/Styles/UYLListViewController.h rename to Archive/Styles/Styles/UYLListViewController.h diff --git a/Styles/Styles/UYLListViewController.m b/Archive/Styles/Styles/UYLListViewController.m similarity index 93% rename from Styles/Styles/UYLListViewController.m rename to Archive/Styles/Styles/UYLListViewController.m index eddda08..ca15048 100644 --- a/Styles/Styles/UYLListViewController.m +++ b/Archive/Styles/Styles/UYLListViewController.m @@ -37,9 +37,9 @@ @interface UYLListViewController () @implementation UYLListViewController -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} +//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +//{ +// return YES; +//} @end diff --git a/Styles/Styles/UYLOkButton.h b/Archive/Styles/Styles/UYLOkButton.h similarity index 100% rename from Styles/Styles/UYLOkButton.h rename to Archive/Styles/Styles/UYLOkButton.h diff --git a/Styles/Styles/UYLOkButton.m b/Archive/Styles/Styles/UYLOkButton.m similarity index 100% rename from Styles/Styles/UYLOkButton.m rename to Archive/Styles/Styles/UYLOkButton.m diff --git a/Styles/Styles/UYLResetButton.h b/Archive/Styles/Styles/UYLResetButton.h similarity index 100% rename from Styles/Styles/UYLResetButton.h rename to Archive/Styles/Styles/UYLResetButton.h diff --git a/Styles/Styles/UYLResetButton.m b/Archive/Styles/Styles/UYLResetButton.m similarity index 100% rename from Styles/Styles/UYLResetButton.m rename to Archive/Styles/Styles/UYLResetButton.m diff --git a/Styles/Styles/UYLRotatingViewController.h b/Archive/Styles/Styles/UYLRotatingViewController.h similarity index 100% rename from Styles/Styles/UYLRotatingViewController.h rename to Archive/Styles/Styles/UYLRotatingViewController.h diff --git a/Styles/Styles/UYLRotatingViewController.m b/Archive/Styles/Styles/UYLRotatingViewController.m similarity index 93% rename from Styles/Styles/UYLRotatingViewController.m rename to Archive/Styles/Styles/UYLRotatingViewController.m index 7333012..243d96f 100644 --- a/Styles/Styles/UYLRotatingViewController.m +++ b/Archive/Styles/Styles/UYLRotatingViewController.m @@ -41,9 +41,9 @@ - (void) viewDidLoad self.view.backgroundColor = [UIColor lightGrayColor]; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} +//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +//{ +// return YES; +//} @end diff --git a/Styles/Styles/UYLStyleController.h b/Archive/Styles/Styles/UYLStyleController.h similarity index 100% rename from Styles/Styles/UYLStyleController.h rename to Archive/Styles/Styles/UYLStyleController.h diff --git a/Styles/Styles/UYLStyleController.m b/Archive/Styles/Styles/UYLStyleController.m similarity index 98% rename from Styles/Styles/UYLStyleController.m rename to Archive/Styles/Styles/UYLStyleController.m index b12ad10..7310ba7 100644 --- a/Styles/Styles/UYLStyleController.m +++ b/Archive/Styles/Styles/UYLStyleController.m @@ -52,7 +52,7 @@ + (void)applyStyle [navigationBarAppearance setBackgroundImage:navBarImage forBarMetrics:UIBarMetricsDefault]; [navigationBarAppearance setBackgroundImage:navBarLandscapeImage forBarMetrics:UIBarMetricsLandscapePhone]; - NSDictionary *textAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor grayColor], UITextAttributeTextColor, nil]; + NSDictionary *textAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[UIColor grayColor], NSForegroundColorAttributeName, nil]; [navigationBarAppearance setTitleTextAttributes:textAttributes]; UIImage *backButtonImage = [UIImage imageNamed:@"back-button"]; diff --git a/Styles/Styles/UYLZeroButton.h b/Archive/Styles/Styles/UYLZeroButton.h similarity index 100% rename from Styles/Styles/UYLZeroButton.h rename to Archive/Styles/Styles/UYLZeroButton.h diff --git a/Styles/Styles/UYLZeroButton.m b/Archive/Styles/Styles/UYLZeroButton.m similarity index 100% rename from Styles/Styles/UYLZeroButton.m rename to Archive/Styles/Styles/UYLZeroButton.m diff --git a/StaticTable/StaticTable/en.lproj/InfoPlist.strings b/Archive/Styles/Styles/en.lproj/InfoPlist.strings similarity index 100% rename from StaticTable/StaticTable/en.lproj/InfoPlist.strings rename to Archive/Styles/Styles/en.lproj/InfoPlist.strings diff --git a/Styles/Styles/main.m b/Archive/Styles/Styles/main.m similarity index 100% rename from Styles/Styles/main.m rename to Archive/Styles/Styles/main.m diff --git a/SyncMe/SyncMe.xcodeproj/project.pbxproj b/Archive/SyncMe/SyncMe.xcodeproj/project.pbxproj similarity index 80% rename from SyncMe/SyncMe.xcodeproj/project.pbxproj rename to Archive/SyncMe/SyncMe.xcodeproj/project.pbxproj index b823bf1..df3f587 100644 --- a/SyncMe/SyncMe.xcodeproj/project.pbxproj +++ b/Archive/SyncMe/SyncMe.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -18,6 +18,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5334609523CA6B2500BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLViewController.xib; sourceTree = ""; }; 53DA6A481454A1C300368AB3 /* SyncMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SyncMe.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53DA6A4C1454A1C300368AB3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53DA6A4E1454A1C300368AB3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -30,7 +31,6 @@ 53DA6A5C1454A1C300368AB3 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 53DA6A5E1454A1C300368AB3 /* UYLViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLViewController.h; sourceTree = ""; }; 53DA6A5F1454A1C400368AB3 /* UYLViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLViewController.m; sourceTree = ""; }; - 53DA6A621454A1C400368AB3 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLViewController.xib; sourceTree = ""; }; 53DA6A771454B39300368AB3 /* SyncMe.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = SyncMe.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ @@ -126,14 +126,15 @@ 53DA6A3F1454A1C300368AB3 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0420; + LastUpgradeCheck = 1120; }; buildConfigurationList = 53DA6A421454A1C300368AB3 /* Build configuration list for PBXProject "SyncMe" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 53DA6A3D1454A1C300368AB3; productRefGroup = 53DA6A491454A1C300368AB3 /* Products */; @@ -182,7 +183,7 @@ 53DA6A611454A1C400368AB3 /* UYLViewController.xib */ = { isa = PBXVariantGroup; children = ( - 53DA6A621454A1C400368AB3 /* en */, + 5334609523CA6B2500BE943E /* Base */, ); name = UYLViewController.xib; sourceTree = ""; @@ -194,11 +195,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -206,10 +227,15 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -218,15 +244,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -236,10 +285,12 @@ 53DA6A671454A1C400368AB3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; CODE_SIGN_ENTITLEMENTS = SyncMe/SyncMe.entitlements; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SyncMe/SyncMe-Prefix.pch"; INFOPLIST_FILE = "SyncMe/SyncMe-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -248,10 +299,12 @@ 53DA6A681454A1C400368AB3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; CODE_SIGN_ENTITLEMENTS = SyncMe/SyncMe.entitlements; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SyncMe/SyncMe-Prefix.pch"; INFOPLIST_FILE = "SyncMe/SyncMe-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/SyncMe/SyncMe/en.lproj/UYLViewController.xib b/Archive/SyncMe/SyncMe/Base.lproj/UYLViewController.xib similarity index 100% rename from SyncMe/SyncMe/en.lproj/UYLViewController.xib rename to Archive/SyncMe/SyncMe/Base.lproj/UYLViewController.xib diff --git a/SyncMe/SyncMe/SyncMe-Info.plist b/Archive/SyncMe/SyncMe/SyncMe-Info.plist similarity index 94% rename from SyncMe/SyncMe/SyncMe-Info.plist rename to Archive/SyncMe/SyncMe/SyncMe-Info.plist index f5d7a12..5da589d 100644 --- a/SyncMe/SyncMe/SyncMe-Info.plist +++ b/Archive/SyncMe/SyncMe/SyncMe-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFiles CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/SyncMe/SyncMe/SyncMe-Prefix.pch b/Archive/SyncMe/SyncMe/SyncMe-Prefix.pch similarity index 100% rename from SyncMe/SyncMe/SyncMe-Prefix.pch rename to Archive/SyncMe/SyncMe/SyncMe-Prefix.pch diff --git a/SyncMe/SyncMe/SyncMe.entitlements b/Archive/SyncMe/SyncMe/SyncMe.entitlements similarity index 100% rename from SyncMe/SyncMe/SyncMe.entitlements rename to Archive/SyncMe/SyncMe/SyncMe.entitlements diff --git a/SyncMe/SyncMe/UYLAppDelegate.h b/Archive/SyncMe/SyncMe/UYLAppDelegate.h similarity index 100% rename from SyncMe/SyncMe/UYLAppDelegate.h rename to Archive/SyncMe/SyncMe/UYLAppDelegate.h diff --git a/SyncMe/SyncMe/UYLAppDelegate.m b/Archive/SyncMe/SyncMe/UYLAppDelegate.m similarity index 100% rename from SyncMe/SyncMe/UYLAppDelegate.m rename to Archive/SyncMe/SyncMe/UYLAppDelegate.m diff --git a/SyncMe/SyncMe/UYLViewController.h b/Archive/SyncMe/SyncMe/UYLViewController.h similarity index 100% rename from SyncMe/SyncMe/UYLViewController.h rename to Archive/SyncMe/SyncMe/UYLViewController.h diff --git a/SyncMe/SyncMe/UYLViewController.m b/Archive/SyncMe/SyncMe/UYLViewController.m similarity index 100% rename from SyncMe/SyncMe/UYLViewController.m rename to Archive/SyncMe/SyncMe/UYLViewController.m diff --git a/Stepper/Stepper/en.lproj/InfoPlist.strings b/Archive/SyncMe/SyncMe/en.lproj/InfoPlist.strings similarity index 100% rename from Stepper/Stepper/en.lproj/InfoPlist.strings rename to Archive/SyncMe/SyncMe/en.lproj/InfoPlist.strings diff --git a/SyncMe/SyncMe/main.m b/Archive/SyncMe/SyncMe/main.m similarity index 100% rename from SyncMe/SyncMe/main.m rename to Archive/SyncMe/SyncMe/main.m diff --git a/TCNibLoad/Classes/NewViewController.h b/Archive/TCNibLoad/Classes/NewViewController.h similarity index 100% rename from TCNibLoad/Classes/NewViewController.h rename to Archive/TCNibLoad/Classes/NewViewController.h diff --git a/TCNibLoad/Classes/NewViewController.m b/Archive/TCNibLoad/Classes/NewViewController.m similarity index 100% rename from TCNibLoad/Classes/NewViewController.m rename to Archive/TCNibLoad/Classes/NewViewController.m diff --git a/TCNibLoad/Classes/OldViewController.h b/Archive/TCNibLoad/Classes/OldViewController.h similarity index 100% rename from TCNibLoad/Classes/OldViewController.h rename to Archive/TCNibLoad/Classes/OldViewController.h diff --git a/TCNibLoad/Classes/OldViewController.m b/Archive/TCNibLoad/Classes/OldViewController.m similarity index 100% rename from TCNibLoad/Classes/OldViewController.m rename to Archive/TCNibLoad/Classes/OldViewController.m diff --git a/Archive/TCNibLoad/Classes/OldViewController.xib b/Archive/TCNibLoad/Classes/OldViewController.xib new file mode 100644 index 0000000..331aaf2 --- /dev/null +++ b/Archive/TCNibLoad/Classes/OldViewController.xib @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TCNibLoad/Classes/TCNibLoadAppDelegate.h b/Archive/TCNibLoad/Classes/TCNibLoadAppDelegate.h similarity index 100% rename from TCNibLoad/Classes/TCNibLoadAppDelegate.h rename to Archive/TCNibLoad/Classes/TCNibLoadAppDelegate.h diff --git a/TCNibLoad/Classes/TCNibLoadAppDelegate.m b/Archive/TCNibLoad/Classes/TCNibLoadAppDelegate.m similarity index 100% rename from TCNibLoad/Classes/TCNibLoadAppDelegate.m rename to Archive/TCNibLoad/Classes/TCNibLoadAppDelegate.m diff --git a/Archive/TCNibLoad/LabelCell.xib b/Archive/TCNibLoad/LabelCell.xib new file mode 100644 index 0000000..3b87b28 --- /dev/null +++ b/Archive/TCNibLoad/LabelCell.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/TCNibLoad/MainWindow.xib b/Archive/TCNibLoad/MainWindow.xib new file mode 100644 index 0000000..36be6bd --- /dev/null +++ b/Archive/TCNibLoad/MainWindow.xib @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TCNibLoad/TCNibLoad-Info.plist b/Archive/TCNibLoad/TCNibLoad-Info.plist similarity index 92% rename from TCNibLoad/TCNibLoad-Info.plist rename to Archive/TCNibLoad/TCNibLoad-Info.plist index 3289444..276e6f6 100644 --- a/TCNibLoad/TCNibLoad-Info.plist +++ b/Archive/TCNibLoad/TCNibLoad-Info.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/TCNibLoad/TCNibLoad.xcodeproj/project.pbxproj b/Archive/TCNibLoad/TCNibLoad.xcodeproj/project.pbxproj similarity index 80% rename from TCNibLoad/TCNibLoad.xcodeproj/project.pbxproj rename to Archive/TCNibLoad/TCNibLoad.xcodeproj/project.pbxproj index e814942..f00f8fe 100644 --- a/TCNibLoad/TCNibLoad.xcodeproj/project.pbxproj +++ b/Archive/TCNibLoad/TCNibLoad.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -140,15 +140,16 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 1120; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TCNibLoad" */; - compatibilityVersion = "Xcode 3.1"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 1; knownRegions = ( - English, - Japanese, - French, - German, + Base, + en, ); mainGroup = 29B97314FDCFA39411CA2CEA /* TCNibLoad */; projectDirPath = ""; @@ -191,16 +192,22 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = TCNibLoad_Prefix.pch; INFOPLIST_FILE = "TCNibLoad-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TCNibLoad; PRODUCT_NAME = TCNibLoad; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; @@ -208,14 +215,20 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign"; + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = YES; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = TCNibLoad_Prefix.pch; INFOPLIST_FILE = "TCNibLoad-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 3.1.3; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TCNibLoad; PRODUCT_NAME = TCNibLoad; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; VALIDATE_PRODUCT = YES; }; name = Release; @@ -223,12 +236,36 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = c99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; name = Debug; @@ -236,13 +273,35 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = c99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - PREBINDING = NO; SDKROOT = iphoneos; }; name = Release; diff --git a/TCNibLoad/TCNibLoad_Prefix.pch b/Archive/TCNibLoad/TCNibLoad_Prefix.pch similarity index 100% rename from TCNibLoad/TCNibLoad_Prefix.pch rename to Archive/TCNibLoad/TCNibLoad_Prefix.pch diff --git a/TCNibLoad/main.m b/Archive/TCNibLoad/main.m similarity index 100% rename from TCNibLoad/main.m rename to Archive/TCNibLoad/main.m diff --git a/TaskTimer/README b/Archive/TaskTimer/README similarity index 95% rename from TaskTimer/README rename to Archive/TaskTimer/README index fd14c10..949762d 100644 --- a/TaskTimer/README +++ b/Archive/TaskTimer/README @@ -13,8 +13,8 @@ perform a list of tasks. For further details see: -http://useyourloaf.com/blog/2012/4/23/voiceover-accessibility.html -http://useyourloaf.com/blog/2012/5/14/detecting-voiceover-status-changes.html +https://useyourloaf.com/blog/voiceover-accessibility/ +https://useyourloaf.com/blog/detecting-voiceover-status-changes/ ======================================================================= Model diff --git a/TaskTimer/TaskTimer.xcodeproj/project.pbxproj b/Archive/TaskTimer/TaskTimer.xcodeproj/project.pbxproj similarity index 87% rename from TaskTimer/TaskTimer.xcodeproj/project.pbxproj rename to Archive/TaskTimer/TaskTimer.xcodeproj/project.pbxproj index b1fb648..c30bd55 100644 --- a/TaskTimer/TaskTimer.xcodeproj/project.pbxproj +++ b/Archive/TaskTimer/TaskTimer.xcodeproj/project.pbxproj @@ -44,10 +44,10 @@ 532DD95F1530C90300ED5845 /* UYLTaskViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLTaskViewController.m; sourceTree = ""; }; 532DD96A1530C9AD00ED5845 /* UYLAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 532DD96B1530C9AD00ED5845 /* UYLAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; - 532DD96E1530CA6400ED5845 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLTaskListViewController_iPad.xib; sourceTree = ""; }; - 532DD9701530CA6400ED5845 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLTaskListViewController_iPhone.xib; sourceTree = ""; }; - 532DD9721530CA6400ED5845 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLTaskViewController_iPad.xib; sourceTree = ""; }; - 532DD9741530CA6400ED5845 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/UYLTaskViewController_iPhone.xib; sourceTree = ""; }; + 5334608B23CA3B5E00BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLTaskListViewController_iPad.xib; sourceTree = ""; }; + 5334608C23CA3B5E00BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLTaskListViewController_iPhone.xib; sourceTree = ""; }; + 5334608D23CA3B5E00BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLTaskViewController_iPad.xib; sourceTree = ""; }; + 5334608E23CA3B5E00BE943E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLTaskViewController_iPhone.xib; sourceTree = ""; }; 534644A4155F083D00B20849 /* redbutton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = redbutton.png; sourceTree = ""; }; 536270F1152E0A55009732E1 /* TaskTimer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TaskTimer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 536270F5152E0A55009732E1 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -230,14 +230,15 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0430; + LastUpgradeCheck = 1120; }; buildConfigurationList = 536270EB152E0A55009732E1 /* Build configuration list for PBXProject "TaskTimer" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 536270E6152E0A55009732E1; productRefGroup = 536270F2152E0A55009732E1 /* Products */; @@ -295,7 +296,7 @@ 532DD96D1530CA6400ED5845 /* UYLTaskListViewController_iPad.xib */ = { isa = PBXVariantGroup; children = ( - 532DD96E1530CA6400ED5845 /* en */, + 5334608B23CA3B5E00BE943E /* Base */, ); name = UYLTaskListViewController_iPad.xib; sourceTree = ""; @@ -303,7 +304,7 @@ 532DD96F1530CA6400ED5845 /* UYLTaskListViewController_iPhone.xib */ = { isa = PBXVariantGroup; children = ( - 532DD9701530CA6400ED5845 /* en */, + 5334608C23CA3B5E00BE943E /* Base */, ); name = UYLTaskListViewController_iPhone.xib; sourceTree = ""; @@ -311,7 +312,7 @@ 532DD9711530CA6400ED5845 /* UYLTaskViewController_iPad.xib */ = { isa = PBXVariantGroup; children = ( - 532DD9721530CA6400ED5845 /* en */, + 5334608D23CA3B5E00BE943E /* Base */, ); name = UYLTaskViewController_iPad.xib; sourceTree = ""; @@ -319,7 +320,7 @@ 532DD9731530CA6400ED5845 /* UYLTaskViewController_iPhone.xib */ = { isa = PBXVariantGroup; children = ( - 532DD9741530CA6400ED5845 /* en */, + 5334608E23CA3B5E00BE943E /* Base */, ); name = UYLTaskViewController_iPhone.xib; sourceTree = ""; @@ -339,12 +340,32 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -352,10 +373,14 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -365,16 +390,38 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -388,6 +435,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "TaskTimer/TaskTimer-Prefix.pch"; INFOPLIST_FILE = "TaskTimer/TaskTimer-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -399,6 +447,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "TaskTimer/TaskTimer-Prefix.pch"; INFOPLIST_FILE = "TaskTimer/TaskTimer-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskListViewController_iPad.xib b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskListViewController_iPad.xib new file mode 100644 index 0000000..f37ea5e --- /dev/null +++ b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskListViewController_iPad.xib @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskListViewController_iPhone.xib b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskListViewController_iPhone.xib new file mode 100644 index 0000000..477fd87 --- /dev/null +++ b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskListViewController_iPhone.xib @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskViewController_iPad.xib b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskViewController_iPad.xib new file mode 100644 index 0000000..1fd7bab --- /dev/null +++ b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskViewController_iPad.xib @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskViewController_iPhone.xib b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskViewController_iPhone.xib new file mode 100644 index 0000000..328cc4f --- /dev/null +++ b/Archive/TaskTimer/TaskTimer/Base.lproj/UYLTaskViewController_iPhone.xib @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.h b/Archive/TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.h similarity index 100% rename from TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.h rename to Archive/TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.h diff --git a/TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.m b/Archive/TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.m similarity index 100% rename from TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.m rename to Archive/TaskTimer/TaskTimer/NSNumber+UYLTimeFormatter.m diff --git a/TaskTimer/TaskTimer/Task.h b/Archive/TaskTimer/TaskTimer/Task.h similarity index 100% rename from TaskTimer/TaskTimer/Task.h rename to Archive/TaskTimer/TaskTimer/Task.h diff --git a/TaskTimer/TaskTimer/Task.m b/Archive/TaskTimer/TaskTimer/Task.m similarity index 100% rename from TaskTimer/TaskTimer/Task.m rename to Archive/TaskTimer/TaskTimer/Task.m diff --git a/TaskTimer/TaskTimer/TaskTimer-Info.plist b/Archive/TaskTimer/TaskTimer/TaskTimer-Info.plist similarity index 95% rename from TaskTimer/TaskTimer/TaskTimer-Info.plist rename to Archive/TaskTimer/TaskTimer/TaskTimer-Info.plist index 3c50c87..363537d 100644 --- a/TaskTimer/TaskTimer/TaskTimer-Info.plist +++ b/Archive/TaskTimer/TaskTimer/TaskTimer-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/TaskTimer/TaskTimer/TaskTimer-Prefix.pch b/Archive/TaskTimer/TaskTimer/TaskTimer-Prefix.pch similarity index 100% rename from TaskTimer/TaskTimer/TaskTimer-Prefix.pch rename to Archive/TaskTimer/TaskTimer/TaskTimer-Prefix.pch diff --git a/TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/.xccurrentversion b/Archive/TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/.xccurrentversion similarity index 100% rename from TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/.xccurrentversion rename to Archive/TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/.xccurrentversion diff --git a/TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/Accessibile.xcdatamodel/contents b/Archive/TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/Accessibile.xcdatamodel/contents similarity index 100% rename from TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/Accessibile.xcdatamodel/contents rename to Archive/TaskTimer/TaskTimer/TaskTimer.xcdatamodeld/Accessibile.xcdatamodel/contents diff --git a/TaskTimer/TaskTimer/UYLAppDelegate.h b/Archive/TaskTimer/TaskTimer/UYLAppDelegate.h similarity index 100% rename from TaskTimer/TaskTimer/UYLAppDelegate.h rename to Archive/TaskTimer/TaskTimer/UYLAppDelegate.h diff --git a/TaskTimer/TaskTimer/UYLAppDelegate.m b/Archive/TaskTimer/TaskTimer/UYLAppDelegate.m similarity index 100% rename from TaskTimer/TaskTimer/UYLAppDelegate.m rename to Archive/TaskTimer/TaskTimer/UYLAppDelegate.m diff --git a/TaskTimer/TaskTimer/UYLCounterView.h b/Archive/TaskTimer/TaskTimer/UYLCounterView.h similarity index 100% rename from TaskTimer/TaskTimer/UYLCounterView.h rename to Archive/TaskTimer/TaskTimer/UYLCounterView.h diff --git a/TaskTimer/TaskTimer/UYLCounterView.m b/Archive/TaskTimer/TaskTimer/UYLCounterView.m similarity index 100% rename from TaskTimer/TaskTimer/UYLCounterView.m rename to Archive/TaskTimer/TaskTimer/UYLCounterView.m diff --git a/TaskTimer/TaskTimer/UYLTaskListViewController.h b/Archive/TaskTimer/TaskTimer/UYLTaskListViewController.h similarity index 100% rename from TaskTimer/TaskTimer/UYLTaskListViewController.h rename to Archive/TaskTimer/TaskTimer/UYLTaskListViewController.h diff --git a/TaskTimer/TaskTimer/UYLTaskListViewController.m b/Archive/TaskTimer/TaskTimer/UYLTaskListViewController.m similarity index 100% rename from TaskTimer/TaskTimer/UYLTaskListViewController.m rename to Archive/TaskTimer/TaskTimer/UYLTaskListViewController.m diff --git a/TaskTimer/TaskTimer/UYLTaskViewController.h b/Archive/TaskTimer/TaskTimer/UYLTaskViewController.h similarity index 100% rename from TaskTimer/TaskTimer/UYLTaskViewController.h rename to Archive/TaskTimer/TaskTimer/UYLTaskViewController.h diff --git a/TaskTimer/TaskTimer/UYLTaskViewController.m b/Archive/TaskTimer/TaskTimer/UYLTaskViewController.m similarity index 100% rename from TaskTimer/TaskTimer/UYLTaskViewController.m rename to Archive/TaskTimer/TaskTimer/UYLTaskViewController.m diff --git a/TaskTimer/TaskTimer/checked.png b/Archive/TaskTimer/TaskTimer/checked.png similarity index 100% rename from TaskTimer/TaskTimer/checked.png rename to Archive/TaskTimer/TaskTimer/checked.png diff --git a/TaskTimer/TaskTimer/checked@2x.png b/Archive/TaskTimer/TaskTimer/checked@2x.png similarity index 100% rename from TaskTimer/TaskTimer/checked@2x.png rename to Archive/TaskTimer/TaskTimer/checked@2x.png diff --git a/Styles/Styles/en.lproj/InfoPlist.strings b/Archive/TaskTimer/TaskTimer/en.lproj/InfoPlist.strings similarity index 100% rename from Styles/Styles/en.lproj/InfoPlist.strings rename to Archive/TaskTimer/TaskTimer/en.lproj/InfoPlist.strings diff --git a/TaskTimer/TaskTimer/main.m b/Archive/TaskTimer/TaskTimer/main.m similarity index 100% rename from TaskTimer/TaskTimer/main.m rename to Archive/TaskTimer/TaskTimer/main.m diff --git a/TaskTimer/TaskTimer/redbutton.png b/Archive/TaskTimer/TaskTimer/redbutton.png similarity index 100% rename from TaskTimer/TaskTimer/redbutton.png rename to Archive/TaskTimer/TaskTimer/redbutton.png diff --git a/TaskTimer/TaskTimer/start.png b/Archive/TaskTimer/TaskTimer/start.png similarity index 100% rename from TaskTimer/TaskTimer/start.png rename to Archive/TaskTimer/TaskTimer/start.png diff --git a/TaskTimer/TaskTimer/start@2x.png b/Archive/TaskTimer/TaskTimer/start@2x.png similarity index 100% rename from TaskTimer/TaskTimer/start@2x.png rename to Archive/TaskTimer/TaskTimer/start@2x.png diff --git a/TaskTimer/TaskTimer/stop.png b/Archive/TaskTimer/TaskTimer/stop.png similarity index 100% rename from TaskTimer/TaskTimer/stop.png rename to Archive/TaskTimer/TaskTimer/stop.png diff --git a/TaskTimer/TaskTimer/stop@2x.png b/Archive/TaskTimer/TaskTimer/stop@2x.png similarity index 100% rename from TaskTimer/TaskTimer/stop@2x.png rename to Archive/TaskTimer/TaskTimer/stop@2x.png diff --git a/TaskTimer/TaskTimer/unchecked.png b/Archive/TaskTimer/TaskTimer/unchecked.png similarity index 100% rename from TaskTimer/TaskTimer/unchecked.png rename to Archive/TaskTimer/TaskTimer/unchecked.png diff --git a/TaskTimer/TaskTimer/unchecked@2x.png b/Archive/TaskTimer/TaskTimer/unchecked@2x.png similarity index 100% rename from TaskTimer/TaskTimer/unchecked@2x.png rename to Archive/TaskTimer/TaskTimer/unchecked@2x.png diff --git a/TwitterSearch/TwitterSearch.xcodeproj/project.pbxproj b/Archive/TwitterSearch/TwitterSearch.xcodeproj/project.pbxproj similarity index 90% rename from TwitterSearch/TwitterSearch.xcodeproj/project.pbxproj rename to Archive/TwitterSearch/TwitterSearch.xcodeproj/project.pbxproj index 4b86589..7223dfd 100644 --- a/TwitterSearch/TwitterSearch.xcodeproj/project.pbxproj +++ b/Archive/TwitterSearch/TwitterSearch.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 47; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -209,7 +209,7 @@ 53CB80F0139D70FF0030ADD7 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 1120; TargetAttributes = { 5345C8541C32CC3C00B88AB7 = { CreatedOnToolsVersion = 7.2; @@ -221,11 +221,12 @@ }; }; buildConfigurationList = 53CB80F3139D70FF0030ADD7 /* Build configuration list for PBXProject "TwitterSearch" */; - compatibilityVersion = "Xcode 6.3"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 53CB80EE139D70FF0030ADD7; productRefGroup = 53CB80FA139D70FF0030ADD7 /* Products */; @@ -338,7 +339,11 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = TwitterSearchUnitTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TwitterSearchUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -377,7 +382,11 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = TwitterSearchUnitTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TwitterSearchUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -389,14 +398,38 @@ 53CB8118139D70FF0030ADD7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; @@ -407,10 +440,34 @@ 53CB8119139D70FF0030ADD7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; @@ -472,6 +529,7 @@ 5345C85E1C32CC3C00B88AB7 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 53CB80F3139D70FF0030ADD7 /* Build configuration list for PBXProject "TwitterSearch" */ = { isa = XCConfigurationList; diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Contents.json b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 72% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Contents.json rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Contents.json index 49901b5..dd3842a 100644 --- a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,17 @@ { "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon2-20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon2-20@3x.png", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", @@ -36,6 +48,18 @@ "filename" : "Icon@3x.png", "scale" : "3x" }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon2-20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon2-20@2x-1.png", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", @@ -77,6 +101,12 @@ "idiom" : "ipad", "filename" : "Icon2-835@2x.png", "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "icon2-1024.png", + "scale" : "1x" } ], "info" : { diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x-1.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x-1.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x-1.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x-1.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@2x.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x-1.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x-1.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x-1.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x-1.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-40@2x.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76@2x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76@2x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76@2x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-76@2x.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x-1.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x-1.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x-1.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x-1.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@2x.png diff --git a/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@3x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@3x.png similarity index 100% rename from TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@3x.png rename to Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/Icon@3x.png diff --git a/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-1024.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-1024.png new file mode 100644 index 0000000..b628b9e Binary files /dev/null and b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-1024.png differ diff --git a/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20.png new file mode 100644 index 0000000..08dee7a Binary files /dev/null and b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20.png differ diff --git a/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@2x-1.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@2x-1.png new file mode 100644 index 0000000..d6fccd4 Binary files /dev/null and b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@2x-1.png differ diff --git a/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@2x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@2x.png new file mode 100644 index 0000000..d6fccd4 Binary files /dev/null and b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@2x.png differ diff --git a/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@3x.png b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@3x.png new file mode 100644 index 0000000..fafe147 Binary files /dev/null and b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/AppIcon.appiconset/icon2-20@3x.png differ diff --git a/Archive/TwitterSearch/TwitterSearch/Images.xcassets/Contents.json b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Archive/TwitterSearch/TwitterSearch/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TwitterSearch/TwitterSearch/LaunchScreen.storyboard b/Archive/TwitterSearch/TwitterSearch/LaunchScreen.storyboard similarity index 78% rename from TwitterSearch/TwitterSearch/LaunchScreen.storyboard rename to Archive/TwitterSearch/TwitterSearch/LaunchScreen.storyboard index 360a69a..b3944d6 100644 --- a/TwitterSearch/TwitterSearch/LaunchScreen.storyboard +++ b/Archive/TwitterSearch/TwitterSearch/LaunchScreen.storyboard @@ -1,8 +1,10 @@ - - + + + - + + @@ -10,13 +12,13 @@ - - + + - + - + @@ -30,7 +32,7 @@ - + diff --git a/TwitterSearch/TwitterSearch/NSString+URLEncoding.h b/Archive/TwitterSearch/TwitterSearch/NSString+URLEncoding.h similarity index 100% rename from TwitterSearch/TwitterSearch/NSString+URLEncoding.h rename to Archive/TwitterSearch/TwitterSearch/NSString+URLEncoding.h diff --git a/TwitterSearch/TwitterSearch/NSString+URLEncoding.m b/Archive/TwitterSearch/TwitterSearch/NSString+URLEncoding.m similarity index 100% rename from TwitterSearch/TwitterSearch/NSString+URLEncoding.m rename to Archive/TwitterSearch/TwitterSearch/NSString+URLEncoding.m diff --git a/TwitterSearch/TwitterSearch/RootViewController.h b/Archive/TwitterSearch/TwitterSearch/RootViewController.h similarity index 100% rename from TwitterSearch/TwitterSearch/RootViewController.h rename to Archive/TwitterSearch/TwitterSearch/RootViewController.h diff --git a/TwitterSearch/TwitterSearch/RootViewController.m b/Archive/TwitterSearch/TwitterSearch/RootViewController.m similarity index 100% rename from TwitterSearch/TwitterSearch/RootViewController.m rename to Archive/TwitterSearch/TwitterSearch/RootViewController.m diff --git a/TwitterSearch/TwitterSearch/SearchViewController.h b/Archive/TwitterSearch/TwitterSearch/SearchViewController.h similarity index 100% rename from TwitterSearch/TwitterSearch/SearchViewController.h rename to Archive/TwitterSearch/TwitterSearch/SearchViewController.h diff --git a/TwitterSearch/TwitterSearch/SearchViewController.m b/Archive/TwitterSearch/TwitterSearch/SearchViewController.m similarity index 100% rename from TwitterSearch/TwitterSearch/SearchViewController.m rename to Archive/TwitterSearch/TwitterSearch/SearchViewController.m diff --git a/TwitterSearch/TwitterSearch/Storyboard.storyboard b/Archive/TwitterSearch/TwitterSearch/Storyboard.storyboard similarity index 86% rename from TwitterSearch/TwitterSearch/Storyboard.storyboard rename to Archive/TwitterSearch/TwitterSearch/Storyboard.storyboard index e6f596e..4739dc5 100644 --- a/TwitterSearch/TwitterSearch/Storyboard.storyboard +++ b/Archive/TwitterSearch/TwitterSearch/Storyboard.storyboard @@ -1,9 +1,10 @@ - - + + + - - + + @@ -11,6 +12,7 @@ + @@ -26,15 +28,15 @@ - - + + - + - + @@ -42,11 +44,11 @@ - + - + @@ -63,38 +65,38 @@ - + - + - + - + - + - + @@ -121,7 +123,7 @@ - + diff --git a/TwitterSearch/TwitterSearch/TweetCell.h b/Archive/TwitterSearch/TwitterSearch/TweetCell.h similarity index 100% rename from TwitterSearch/TwitterSearch/TweetCell.h rename to Archive/TwitterSearch/TwitterSearch/TweetCell.h diff --git a/TwitterSearch/TwitterSearch/TweetCell.m b/Archive/TwitterSearch/TwitterSearch/TweetCell.m similarity index 100% rename from TwitterSearch/TwitterSearch/TweetCell.m rename to Archive/TwitterSearch/TwitterSearch/TweetCell.m diff --git a/TwitterSearch/TwitterSearch/TwitterSearch-Info.plist b/Archive/TwitterSearch/TwitterSearch/TwitterSearch-Info.plist similarity index 100% rename from TwitterSearch/TwitterSearch/TwitterSearch-Info.plist rename to Archive/TwitterSearch/TwitterSearch/TwitterSearch-Info.plist diff --git a/TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.h b/Archive/TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.h similarity index 100% rename from TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.h rename to Archive/TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.h diff --git a/TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.m b/Archive/TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.m similarity index 100% rename from TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.m rename to Archive/TwitterSearch/TwitterSearch/TwitterSearchAppDelegate.m diff --git a/SyncMe/SyncMe/en.lproj/InfoPlist.strings b/Archive/TwitterSearch/TwitterSearch/en.lproj/InfoPlist.strings similarity index 100% rename from SyncMe/SyncMe/en.lproj/InfoPlist.strings rename to Archive/TwitterSearch/TwitterSearch/en.lproj/InfoPlist.strings diff --git a/TwitterSearch/TwitterSearch/main.m b/Archive/TwitterSearch/TwitterSearch/main.m similarity index 100% rename from TwitterSearch/TwitterSearch/main.m rename to Archive/TwitterSearch/TwitterSearch/main.m diff --git a/Stacks/StacksTests/Info.plist b/Archive/TwitterSearch/TwitterSearchUnitTests/Info.plist similarity index 100% rename from Stacks/StacksTests/Info.plist rename to Archive/TwitterSearch/TwitterSearchUnitTests/Info.plist diff --git a/TwitterSearch/TwitterSearchUnitTests/NSStringURLEncodingUnitTests.m b/Archive/TwitterSearch/TwitterSearchUnitTests/NSStringURLEncodingUnitTests.m similarity index 100% rename from TwitterSearch/TwitterSearchUnitTests/NSStringURLEncodingUnitTests.m rename to Archive/TwitterSearch/TwitterSearchUnitTests/NSStringURLEncodingUnitTests.m diff --git a/AutoLayout/AutoLayout.xcodeproj/project.pbxproj b/AutoLayout/AutoLayout.xcodeproj/project.pbxproj index b537959..d37e045 100644 --- a/AutoLayout/AutoLayout.xcodeproj/project.pbxproj +++ b/AutoLayout/AutoLayout.xcodeproj/project.pbxproj @@ -132,22 +132,24 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53D6A5EC1C53BF5200A81A14 = { CreatedOnToolsVersion = 7.2; - LastSwiftMigration = 0800; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1020; }; }; }; buildConfigurationList = 53D6A5E81C53BF5200A81A14 /* Build configuration list for PBXProject "AutoLayout" */; compatibilityVersion = "Xcode 6.3"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, + ar, ); mainGroup = 53D6A5E41C53BF5200A81A14; productRefGroup = 53D6A5EE1C53BF5200A81A14 /* Products */; @@ -224,13 +226,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -270,13 +282,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -304,11 +326,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AutoLayout/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AutoLayout; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -316,12 +339,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = AutoLayout/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.AutoLayout; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/AutoLayout/AutoLayout/AdaptiveViewController.swift b/AutoLayout/AutoLayout/AdaptiveViewController.swift index 4d2cce3..e96eb39 100644 --- a/AutoLayout/AutoLayout/AdaptiveViewController.swift +++ b/AutoLayout/AutoLayout/AdaptiveViewController.swift @@ -67,18 +67,18 @@ class AdaptiveViewController: UIViewController { textLabel.textColor = .gray redButton.translatesAutoresizingMaskIntoConstraints = false - redButton.setTitle("No don't do it", for: UIControlState()) + redButton.setTitle("No don't do it", for: UIControl.State()) let redImage = UIImage(named: "redButton") - redButton.setBackgroundImage(redImage, for: UIControlState()) - redButton.contentEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 16) + redButton.setBackgroundImage(redImage, for: UIControl.State()) + redButton.contentEdgeInsets = UIEdgeInsets.init(top: 8, left: 16, bottom: 8, right: 16) let noAction = #selector(noAction(_:)) redButton.addTarget(self, action: noAction, for: .touchUpInside) greenButton.translatesAutoresizingMaskIntoConstraints = false - greenButton.setTitle("Start the Countdown!!!", for: UIControlState()) + greenButton.setTitle("Start the Countdown!!!", for: UIControl.State()) let greenImage = UIImage(named: "greenButton") - greenButton.setBackgroundImage(greenImage, for: UIControlState()) - greenButton.contentEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 16) + greenButton.setBackgroundImage(greenImage, for: UIControl.State()) + greenButton.contentEdgeInsets = UIEdgeInsets.init(top: 8, left: 16, bottom: 8, right: 16) let yesAction = #selector(yesAction(_:)) greenButton.addTarget(self, action: yesAction, for: .touchUpInside) @@ -89,7 +89,16 @@ class AdaptiveViewController: UIViewController { view.addLayoutGuide(middleGuide) view.addLayoutGuide(trailingGuide) } - + + private var firstTime = true + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + if firstTime { + firstTime = false + enableConstraintsForWidth(traitCollection.horizontalSizeClass) + } + } + private func setupConstraints() { // ========================================= @@ -150,8 +159,6 @@ class AdaptiveViewController: UIViewController { compactConstraints.append(redButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)) compactConstraints.append(greenButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)) compactConstraints.append(greenButton.topAnchor.constraint(equalTo: redButton.bottomAnchor, constant: 8.0)) - - enableConstraintsForWidth(traitCollection.horizontalSizeClass) } private func enableConstraintsForWidth(_ horizontalSizeClass: UIUserInterfaceSizeClass) { @@ -164,11 +171,11 @@ class AdaptiveViewController: UIViewController { } } - func noAction(_ sender: UIButton) { + @objc func noAction(_ sender: UIButton) { print("No") } - func yesAction(_ sender: UIButton) { + @objc func yesAction(_ sender: UIButton) { print("Yes") } } diff --git a/AutoLayout/AutoLayout/AppDelegate.swift b/AutoLayout/AutoLayout/AppDelegate.swift index de5cca2..828bcfd 100644 --- a/AutoLayout/AutoLayout/AppDelegate.swift +++ b/AutoLayout/AutoLayout/AppDelegate.swift @@ -38,7 +38,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let splitViewController = self.window!.rootViewController as! UISplitViewController splitViewController.delegate = self return true diff --git a/AutoLayout/AutoLayout/Assets.xcassets/AppIcon.appiconset/Contents.json b/AutoLayout/AutoLayout/Assets.xcassets/AppIcon.appiconset/Contents.json index eeea76c..d8db8d6 100644 --- a/AutoLayout/AutoLayout/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/AutoLayout/AutoLayout/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -64,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/AutoLayout/AutoLayout/LayoutGuideController.swift b/AutoLayout/AutoLayout/LayoutGuideController.swift index 5fd4327..b092cd7 100644 --- a/AutoLayout/AutoLayout/LayoutGuideController.swift +++ b/AutoLayout/AutoLayout/LayoutGuideController.swift @@ -33,24 +33,23 @@ import UIKit -class LayoutGuideController: UIViewController { - +final class LayoutGuideController: UIViewController { // Use layout guides as an alternative to spacer views // The two buttons will be placed between the view margins // with equal spacing between the buttons and the margins // so that the width of the three guides is equal. - + // = |+++++++++++************+++++++++++************+++++++++++| = // = |+ leading +* no *+ middle +* yes *+ trailing+| = // = |+ guide +* button *+ guide +* button *+ guide +| = // = |+++++++++++************+++++++++++************+++++++++++| = - + let leadingGuide = UILayoutGuide() let noButton = UIButton(type: .custom) let middleGuide = UILayoutGuide() let yesButton = UIButton(type: .custom) let trailingGuide = UILayoutGuide() - + override func viewDidLoad() { super.viewDidLoad() setupViews() @@ -58,76 +57,73 @@ class LayoutGuideController: UIViewController { } private func setupViews() { - // Configure the buttons and add them to the superview - + noButton.translatesAutoresizingMaskIntoConstraints = false - noButton.setTitle("No", for: UIControlState()) + noButton.setTitle("No", for: .normal) let redImage = UIImage(named: "redButton") - noButton.setBackgroundImage(redImage, for: UIControlState()) - noButton.contentEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 16) - let noThanksAction = #selector(LayoutGuideController.noThanks(_:)) - noButton.addTarget(self, action: noThanksAction, for: .touchUpInside) - + noButton.setBackgroundImage(redImage, for: .normal) + noButton.contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) + noButton.addTarget(self, action: #selector(LayoutGuideController.noThanks(_:)), for: .touchUpInside) + yesButton.translatesAutoresizingMaskIntoConstraints = false - yesButton.setTitle("Yes please!", for: UIControlState()) + yesButton.setTitle("Yes please!", for: .normal) let greenImage = UIImage(named: "greenButton") - yesButton.setBackgroundImage(greenImage, for: UIControlState()) - yesButton.contentEdgeInsets = UIEdgeInsetsMake(8, 16, 8, 16) - let yesPleaseAction = #selector(LayoutGuideController.yesPlease(_:)) - yesButton.addTarget(self, action: yesPleaseAction, for: .touchUpInside) - + yesButton.setBackgroundImage(greenImage, for: .normal) + yesButton.contentEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) + yesButton.addTarget(self, action: #selector(LayoutGuideController.yesPlease(_:)), for: .touchUpInside) + view.addSubview(noButton) view.addSubview(yesButton) - + // Add the layout guides to the view // Note that the guides are not part of the // view hierarchy - + view.addLayoutGuide(leadingGuide) view.addLayoutGuide(middleGuide) view.addLayoutGuide(trailingGuide) } - + private func setupConstraints() { - // The views are spaced relative to the margings of // the superview. To space the views relative to the - // edges of the super view replace "margings" with + // edges of the super view replace "margins" with // "view" in the constraints below - + let margins = view.layoutMarginsGuide - - // leading to trailing constraints - // working from left to right - - margins.leadingAnchor.constraint(equalTo: leadingGuide.leadingAnchor).isActive = true - leadingGuide.trailingAnchor.constraint(equalTo: noButton.leadingAnchor).isActive = true - noButton.trailingAnchor.constraint(equalTo: middleGuide.leadingAnchor).isActive = true - middleGuide.trailingAnchor.constraint(equalTo: yesButton.leadingAnchor).isActive = true - yesButton.trailingAnchor.constraint(equalTo: trailingGuide.leadingAnchor).isActive = true - trailingGuide.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true - - // The buttons should have the same width - noButton.widthAnchor.constraint(equalTo: yesButton.widthAnchor).isActive = true - - // The guides should have the same width - leadingGuide.widthAnchor.constraint(equalTo: middleGuide.widthAnchor).isActive = true - leadingGuide.widthAnchor.constraint(equalTo: trailingGuide.widthAnchor).isActive = true - - // Center everything vertically in the super view - leadingGuide.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true - middleGuide.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true - trailingGuide.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true - noButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true - yesButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true + NSLayoutConstraint.activate([ + // leading to trailing constraints + // working from left to right + + margins.leadingAnchor.constraint(equalTo: leadingGuide.leadingAnchor), + leadingGuide.trailingAnchor.constraint(equalTo: noButton.leadingAnchor), + noButton.trailingAnchor.constraint(equalTo: middleGuide.leadingAnchor), + middleGuide.trailingAnchor.constraint(equalTo: yesButton.leadingAnchor), + yesButton.trailingAnchor.constraint(equalTo: trailingGuide.leadingAnchor), + trailingGuide.trailingAnchor.constraint(equalTo: margins.trailingAnchor), + + // The buttons should have the same width + noButton.widthAnchor.constraint(equalTo: yesButton.widthAnchor), + + // The guides should have the same width + leadingGuide.widthAnchor.constraint(equalTo: middleGuide.widthAnchor), + leadingGuide.widthAnchor.constraint(equalTo: trailingGuide.widthAnchor), + + // Center everything vertically in the super view + leadingGuide.centerYAnchor.constraint(equalTo: view.centerYAnchor), + middleGuide.centerYAnchor.constraint(equalTo: view.centerYAnchor), + trailingGuide.centerYAnchor.constraint(equalTo: view.centerYAnchor), + noButton.centerYAnchor.constraint(equalTo: view.centerYAnchor), + yesButton.centerYAnchor.constraint(equalTo: view.centerYAnchor) + ]) } - - func noThanks(_ sender: UIButton) { + + @objc private func noThanks(_ sender: UIButton) { print("No thanks!") } - - func yesPlease(_ sender: UIButton) { + + @objc private func yesPlease(_ sender: UIButton) { print("Yes please!") } } diff --git a/AutoLayout/AutoLayout/UIViewController+Constraint.swift b/AutoLayout/AutoLayout/UIViewController+Constraint.swift index a553a3a..8cb4f05 100644 --- a/AutoLayout/AutoLayout/UIViewController+Constraint.swift +++ b/AutoLayout/AutoLayout/UIViewController+Constraint.swift @@ -69,7 +69,7 @@ extension UIViewController { - Parameter identifier: A String identifier to aid debugging. */ - func addConstraintFromView(_ subview: UIView?, attribute: NSLayoutAttribute, multiplier: CGFloat, identifier: String) { + func addConstraintFromView(_ subview: UIView?, attribute: NSLayoutConstraint.Attribute, multiplier: CGFloat, identifier: String) { if let subview = subview { let constraint = NSLayoutConstraint(item: subview, attribute: attribute, diff --git a/AutoLayout/README.md b/AutoLayout/README.md index 5905031..42086b1 100644 --- a/AutoLayout/README.md +++ b/AutoLayout/README.md @@ -12,12 +12,12 @@ Auto Layout examples using Interface Builder and in code. See the following posts further details: -+ [Proportional Spacing with Auto Layout](http://useyourloaf.com/blog/proportional-spacing-with-auto-layout/) -+ [Adapting Images for Size Classes](http://useyourloaf.com/blog/adapting-images-for-size-classes/) -+ [Pain Free Constraints with Layout Anchors](http://useyourloaf.com/blog/pain-free-constraints-with-layout-anchors/) -+ [Goodbye Spacer Views Hello Layout Guides](http://useyourloaf.com/blog/goodbye-spacer-views-hello-layout-guides/) -+ [Adapting AutoLayout Without Interface Builder](http://useyourloaf.com/blog/adapting-auto-layout-without-interface-builder/) -+ [Natural Text Alignment for RTL Languages](http://useyourloaf.com/blog/natural-text-alignment-for-rtl-languages/) ++ [Proportional Spacing with Auto Layout](https://useyourloaf.com/blog/proportional-spacing-with-auto-layout/) ++ [Adapting Images for Size Classes](https://useyourloaf.com/blog/adapting-images-for-size-classes/) ++ [Pain Free Constraints with Layout Anchors](https://useyourloaf.com/blog/pain-free-constraints-with-layout-anchors/) ++ [Goodbye Spacer Views Hello Layout Guides](https://useyourloaf.com/blog/goodbye-spacer-views-hello-layout-guides/) ++ [Adapting AutoLayout Without Interface Builder](https://useyourloaf.com/blog/adapting-auto-layout-without-interface-builder/) ++ [Natural Text Alignment for RTL Languages](https://useyourloaf.com/blog/natural-text-alignment-for-rtl-languages/) #### Version History diff --git a/BlastOff/BlastOff.xcodeproj/project.pbxproj b/BlastOff/BlastOff.xcodeproj/project.pbxproj new file mode 100644 index 0000000..0f9f4af --- /dev/null +++ b/BlastOff/BlastOff.xcodeproj/project.pbxproj @@ -0,0 +1,349 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 53E5DCE32184979D001EE0D8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E5DCE22184979D001EE0D8 /* AppDelegate.swift */; }; + 53E5DCE82184979D001EE0D8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53E5DCE62184979D001EE0D8 /* Main.storyboard */; }; + 53E5DCEA2184979E001EE0D8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53E5DCE92184979E001EE0D8 /* Assets.xcassets */; }; + 53E5DCED2184979E001EE0D8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53E5DCEB2184979E001EE0D8 /* LaunchScreen.storyboard */; }; + 53E5DCFE2184A8EF001EE0D8 /* LaunchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E5DCFD2184A8EF001EE0D8 /* LaunchController.swift */; }; + 53E5DCFF2184A938001EE0D8 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 53E5DCF42184A728001EE0D8 /* Localizable.stringsdict */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53B0B511218750E800BBD609 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53E5DCDF2184979D001EE0D8 /* BlastOff.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BlastOff.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53E5DCE22184979D001EE0D8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53E5DCE72184979D001EE0D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53E5DCE92184979E001EE0D8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53E5DCEC2184979E001EE0D8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53E5DCEE2184979E001EE0D8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53E5DCF42184A728001EE0D8 /* Localizable.stringsdict */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = ""; }; + 53E5DCFD2184A8EF001EE0D8 /* LaunchController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53E5DCDC2184979D001EE0D8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53E5DCD62184979D001EE0D8 = { + isa = PBXGroup; + children = ( + 53B0B511218750E800BBD609 /* README.md */, + 53E5DCE12184979D001EE0D8 /* BlastOff */, + 53E5DCE02184979D001EE0D8 /* Products */, + ); + sourceTree = ""; + }; + 53E5DCE02184979D001EE0D8 /* Products */ = { + isa = PBXGroup; + children = ( + 53E5DCDF2184979D001EE0D8 /* BlastOff.app */, + ); + name = Products; + sourceTree = ""; + }; + 53E5DCE12184979D001EE0D8 /* BlastOff */ = { + isa = PBXGroup; + children = ( + 53E5DCE22184979D001EE0D8 /* AppDelegate.swift */, + 53E5DCFD2184A8EF001EE0D8 /* LaunchController.swift */, + 53E5DCF42184A728001EE0D8 /* Localizable.stringsdict */, + 53E5DCE62184979D001EE0D8 /* Main.storyboard */, + 53E5DCE92184979E001EE0D8 /* Assets.xcassets */, + 53E5DCEB2184979E001EE0D8 /* LaunchScreen.storyboard */, + 53E5DCEE2184979E001EE0D8 /* Info.plist */, + ); + path = BlastOff; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53E5DCDE2184979D001EE0D8 /* BlastOff */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53E5DCF12184979E001EE0D8 /* Build configuration list for PBXNativeTarget "BlastOff" */; + buildPhases = ( + 53E5DCDB2184979D001EE0D8 /* Sources */, + 53E5DCDC2184979D001EE0D8 /* Frameworks */, + 53E5DCDD2184979D001EE0D8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BlastOff; + productName = BlastOff; + productReference = 53E5DCDF2184979D001EE0D8 /* BlastOff.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53E5DCD72184979D001EE0D8 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1000; + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53E5DCDE2184979D001EE0D8 = { + CreatedOnToolsVersion = 10.0; + }; + }; + }; + buildConfigurationList = 53E5DCDA2184979D001EE0D8 /* Build configuration list for PBXProject "BlastOff" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53E5DCD62184979D001EE0D8; + productRefGroup = 53E5DCE02184979D001EE0D8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53E5DCDE2184979D001EE0D8 /* BlastOff */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53E5DCDD2184979D001EE0D8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E5DCED2184979E001EE0D8 /* LaunchScreen.storyboard in Resources */, + 53E5DCFF2184A938001EE0D8 /* Localizable.stringsdict in Resources */, + 53E5DCEA2184979E001EE0D8 /* Assets.xcassets in Resources */, + 53E5DCE82184979D001EE0D8 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53E5DCDB2184979D001EE0D8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E5DCFE2184A8EF001EE0D8 /* LaunchController.swift in Sources */, + 53E5DCE32184979D001EE0D8 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53E5DCE62184979D001EE0D8 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53E5DCE72184979D001EE0D8 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53E5DCEB2184979E001EE0D8 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53E5DCEC2184979E001EE0D8 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53E5DCEF2184979E001EE0D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53E5DCF02184979E001EE0D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53E5DCF22184979E001EE0D8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = BlastOff/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.BlastOff; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53E5DCF32184979E001EE0D8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = BlastOff/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.BlastOff; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53E5DCDA2184979D001EE0D8 /* Build configuration list for PBXProject "BlastOff" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53E5DCEF2184979E001EE0D8 /* Debug */, + 53E5DCF02184979E001EE0D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53E5DCF12184979E001EE0D8 /* Build configuration list for PBXNativeTarget "BlastOff" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53E5DCF22184979E001EE0D8 /* Debug */, + 53E5DCF32184979E001EE0D8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53E5DCD72184979D001EE0D8 /* Project object */; +} diff --git a/BlastOff/BlastOff/AppDelegate.swift b/BlastOff/BlastOff/AppDelegate.swift new file mode 100644 index 0000000..dd55aa9 --- /dev/null +++ b/BlastOff/BlastOff/AppDelegate.swift @@ -0,0 +1,35 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? +} diff --git a/BlastOff/BlastOff/Assets.xcassets/AppIcon.appiconset/Contents.json b/BlastOff/BlastOff/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/BlastOff/BlastOff/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/BlastOff/BlastOff/Assets.xcassets/Contents.json b/BlastOff/BlastOff/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/BlastOff/BlastOff/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/BlastOff/BlastOff/Base.lproj/LaunchScreen.storyboard b/BlastOff/BlastOff/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/BlastOff/BlastOff/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BlastOff/BlastOff/Base.lproj/Main.storyboard b/BlastOff/BlastOff/Base.lproj/Main.storyboard new file mode 100644 index 0000000..d7b776c --- /dev/null +++ b/BlastOff/BlastOff/Base.lproj/Main.storyboard @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BlastOff/BlastOff/Info.plist b/BlastOff/BlastOff/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/BlastOff/BlastOff/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/BlastOff/BlastOff/LaunchController.swift b/BlastOff/BlastOff/LaunchController.swift new file mode 100644 index 0000000..51718d4 --- /dev/null +++ b/BlastOff/BlastOff/LaunchController.swift @@ -0,0 +1,48 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LaunchController: UIViewController { + + @IBOutlet private var abortButton: UIButton! + @IBOutlet private var startButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + } + + private func setupView() { + let startTitle = NSLocalizedString("Start", comment: "Start button") + startButton.setTitle(startTitle, for: .normal) + + let abortTitle = NSLocalizedString("Abort", comment: "Abort button") + abortButton.setTitle(abortTitle, for: .normal) + } +} diff --git a/BlastOff/BlastOff/Localizable.stringsdict b/BlastOff/BlastOff/Localizable.stringsdict new file mode 100755 index 0000000..f2f6b22 --- /dev/null +++ b/BlastOff/BlastOff/Localizable.stringsdict @@ -0,0 +1,30 @@ + + + + + Abort + + NSStringVariableWidthRuleType + + 20 + Abort + 25 + Abort Launch + 50 + Abort Launch Sequence + + + Start + + NSStringVariableWidthRuleType + + 20 + Start + 25 + Start Countdown + 50 + Start Launch Countdown + + + + diff --git a/BlastOff/README.md b/BlastOff/README.md new file mode 100644 index 0000000..8526a74 --- /dev/null +++ b/BlastOff/README.md @@ -0,0 +1,7 @@ +# Variable Width Strings + +An example of using a **localization strings dictionary** to create variable width strings. A `UILabel` or `UIButton` will automatically show the best string from the dictionary for the available screen width. + +For further details see the following blog post: + ++ [Variable Width Strings](https://useyourloaf.com/blog/variable-width-strings/) diff --git a/Buttons/Buttons.xcodeproj/project.pbxproj b/Buttons/Buttons.xcodeproj/project.pbxproj index 468cb69..587fde8 100644 --- a/Buttons/Buttons.xcodeproj/project.pbxproj +++ b/Buttons/Buttons.xcodeproj/project.pbxproj @@ -91,17 +91,19 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 5323B0B31C88D97300B183DD = { CreatedOnToolsVersion = 7.2.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 0810; }; }; }; buildConfigurationList = 5323B0AF1C88D97300B183DD /* Build configuration list for PBXProject "Buttons" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -166,17 +168,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -203,6 +216,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -211,17 +225,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -240,6 +265,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -249,10 +276,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = Buttons/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Buttons; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -260,10 +289,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = Buttons/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Buttons; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/Buttons/Buttons/Assets.xcassets/AppIcon.appiconset/Contents.json b/Buttons/Buttons/Assets.xcassets/AppIcon.appiconset/Contents.json index eeea76c..1d060ed 100644 --- a/Buttons/Buttons/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Buttons/Buttons/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", diff --git a/Buttons/Buttons/Base.lproj/LaunchScreen.storyboard b/Buttons/Buttons/Base.lproj/LaunchScreen.storyboard index 90d6157..548dc01 100644 --- a/Buttons/Buttons/Base.lproj/LaunchScreen.storyboard +++ b/Buttons/Buttons/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -14,9 +18,9 @@ - + - + diff --git a/Buttons/Buttons/Base.lproj/Main.storyboard b/Buttons/Buttons/Base.lproj/Main.storyboard index 15ac78d..f5830ed 100644 --- a/Buttons/Buttons/Base.lproj/Main.storyboard +++ b/Buttons/Buttons/Base.lproj/Main.storyboard @@ -1,9 +1,13 @@ - - + + + + + - + + @@ -15,34 +19,34 @@ - + - + @@ -51,7 +55,7 @@ - + @@ -71,5 +75,5 @@ - + diff --git a/Buttons/Buttons/ViewController.swift b/Buttons/Buttons/ViewController.swift index c3b7cc9..dac117a 100644 --- a/Buttons/Buttons/ViewController.swift +++ b/Buttons/Buttons/ViewController.swift @@ -42,12 +42,12 @@ class ViewController: UIViewController { // Create a custom button and set title label style - let orangeButton = UIButton(type: .Custom) - orangeButton.setTitle("Orange", forState: .Normal) - orangeButton.setTitleColor(.orangeColor(), forState: .Normal) - orangeButton.setTitleColor(.whiteColor(), forState: .Highlighted) - orangeButton.titleLabel?.font = UIFont.systemFontOfSize(14) - orangeButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 8) + let orangeButton = UIButton(type: .custom) + orangeButton.setTitle("Orange", for: .normal) + orangeButton.setTitleColor(.orange, for: .normal) + orangeButton.setTitleColor(.white, for: .highlighted) + orangeButton.titleLabel?.font = UIFont.systemFont(ofSize: 14) + orangeButton.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) // Get the pre-sliced template images direct from the // asset catalog for the default and hightlighted states @@ -55,14 +55,14 @@ class ViewController: UIViewController { let slicedBorderTemplate = UIImage(named: "slicedBorderTemplate") let slicedFillTemplate = UIImage(named: "slicedFillTemplate") - orangeButton.setBackgroundImage(slicedBorderTemplate, forState: .Normal) - orangeButton.setBackgroundImage(slicedFillTemplate, forState: .Highlighted) + orangeButton.setBackgroundImage(slicedBorderTemplate, for: .normal) + orangeButton.setBackgroundImage(slicedFillTemplate, for: .highlighted) // The tintColor controls the colour used by the template images // Defaults to inherited value - orangeButton.tintColor = .orangeColor() + orangeButton.tintColor = .orange stackView.addArrangedSubview(orangeButton) } -} \ No newline at end of file +} diff --git a/Container/Container-SB/Container.xcodeproj/project.pbxproj b/Container/Container-SB/Container.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f7d1a57 --- /dev/null +++ b/Container/Container-SB/Container.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 534452FA1E61BA1F00649AF9 /* LocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 534452F91E61BA1F00649AF9 /* LocationTests.swift */; }; + 534452FE1E61DF6200649AF9 /* locations.plist in Resources */ = {isa = PBXBuildFile; fileRef = 534452FD1E61DF6100649AF9 /* locations.plist */; }; + 5367B24C1E608B79001744C8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B24B1E608B79001744C8 /* AppDelegate.swift */; }; + 5367B2511E608B79001744C8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5367B24F1E608B79001744C8 /* Main.storyboard */; }; + 5367B2531E608B79001744C8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5367B2521E608B79001744C8 /* Assets.xcassets */; }; + 5367B2561E608B79001744C8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5367B2541E608B79001744C8 /* LaunchScreen.storyboard */; }; + 5367B25E1E608BE4001744C8 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B25D1E608BE4001744C8 /* MasterViewController.swift */; }; + 5367B2601E60A129001744C8 /* LocationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B25F1E60A129001744C8 /* LocationTableViewController.swift */; }; + 5367B2621E60A140001744C8 /* LocationDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2611E60A140001744C8 /* LocationDataSource.swift */; }; + 5367B2641E60A1A9001744C8 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2631E60A1A9001744C8 /* MapViewController.swift */; }; + 5367B2691E60A3C3001744C8 /* LocationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2681E60A3C3001744C8 /* LocationCell.swift */; }; + 5367B26B1E60A5C6001744C8 /* ReusableIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B26A1E60A5C6001744C8 /* ReusableIdentifier.swift */; }; + 5367B26E1E60A641001744C8 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B26D1E60A641001744C8 /* ConfigurableCell.swift */; }; + 5367B2721E60A694001744C8 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2711E60A694001744C8 /* Location.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 534452F41E61B9E600649AF9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5367B2401E608B79001744C8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5367B2471E608B79001744C8; + remoteInfo = Container; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 534452EF1E61B9E600649AF9 /* ContainerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ContainerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 534452F31E61B9E600649AF9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 534452F91E61BA1F00649AF9 /* LocationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationTests.swift; sourceTree = ""; }; + 534452FD1E61DF6100649AF9 /* locations.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = locations.plist; sourceTree = ""; }; + 534452FF1E6216A100649AF9 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; }; + 5367B2481E608B79001744C8 /* Container.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Container.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5367B24B1E608B79001744C8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5367B2501E608B79001744C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5367B2521E608B79001744C8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5367B2551E608B79001744C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5367B2571E608B79001744C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5367B25D1E608BE4001744C8 /* MasterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterViewController.swift; sourceTree = ""; }; + 5367B25F1E60A129001744C8 /* LocationTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationTableViewController.swift; sourceTree = ""; }; + 5367B2611E60A140001744C8 /* LocationDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationDataSource.swift; sourceTree = ""; }; + 5367B2631E60A1A9001744C8 /* MapViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = ""; }; + 5367B2661E60A29E001744C8 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 5367B2681E60A3C3001744C8 /* LocationCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationCell.swift; sourceTree = ""; }; + 5367B26A1E60A5C6001744C8 /* ReusableIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReusableIdentifier.swift; sourceTree = ""; }; + 5367B26D1E60A641001744C8 /* ConfigurableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurableCell.swift; sourceTree = ""; }; + 5367B2711E60A694001744C8 /* Location.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 534452EC1E61B9E600649AF9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5367B2451E608B79001744C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 534452F01E61B9E600649AF9 /* ContainerTests */ = { + isa = PBXGroup; + children = ( + 534452F91E61BA1F00649AF9 /* LocationTests.swift */, + 534452F31E61B9E600649AF9 /* Info.plist */, + ); + path = ContainerTests; + sourceTree = ""; + }; + 534453011E6217D600649AF9 /* Controllers */ = { + isa = PBXGroup; + children = ( + 5367B25D1E608BE4001744C8 /* MasterViewController.swift */, + 5367B2631E60A1A9001744C8 /* MapViewController.swift */, + 5367B25F1E60A129001744C8 /* LocationTableViewController.swift */, + ); + name = Controllers; + sourceTree = ""; + }; + 534453021E6217E300649AF9 /* Delegates and DataSources */ = { + isa = PBXGroup; + children = ( + 5367B24B1E608B79001744C8 /* AppDelegate.swift */, + 5367B2611E60A140001744C8 /* LocationDataSource.swift */, + ); + name = "Delegates and DataSources"; + sourceTree = ""; + }; + 534453031E6217F800649AF9 /* Model */ = { + isa = PBXGroup; + children = ( + 534452FD1E61DF6100649AF9 /* locations.plist */, + 5367B2711E60A694001744C8 /* Location.swift */, + ); + name = Model; + sourceTree = ""; + }; + 534453041E62181D00649AF9 /* Views */ = { + isa = PBXGroup; + children = ( + 5367B2681E60A3C3001744C8 /* LocationCell.swift */, + 5367B24F1E608B79001744C8 /* Main.storyboard */, + 5367B2521E608B79001744C8 /* Assets.xcassets */, + 5367B2541E608B79001744C8 /* LaunchScreen.storyboard */, + ); + name = Views; + sourceTree = ""; + }; + 534453051E62182900649AF9 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5367B2571E608B79001744C8 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5367B23F1E608B79001744C8 = { + isa = PBXGroup; + children = ( + 534452FF1E6216A100649AF9 /* README.md */, + 5367B24A1E608B79001744C8 /* Container */, + 534452F01E61B9E600649AF9 /* ContainerTests */, + 5367B2491E608B79001744C8 /* Products */, + 5367B2651E60A29E001744C8 /* Frameworks */, + ); + sourceTree = ""; + }; + 5367B2491E608B79001744C8 /* Products */ = { + isa = PBXGroup; + children = ( + 5367B2481E608B79001744C8 /* Container.app */, + 534452EF1E61B9E600649AF9 /* ContainerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5367B24A1E608B79001744C8 /* Container */ = { + isa = PBXGroup; + children = ( + 5367B26C1E60A5F0001744C8 /* Protocols and Extensions */, + 534453031E6217F800649AF9 /* Model */, + 534453011E6217D600649AF9 /* Controllers */, + 534453021E6217E300649AF9 /* Delegates and DataSources */, + 534453041E62181D00649AF9 /* Views */, + 534453051E62182900649AF9 /* Supporting Files */, + ); + path = Container; + sourceTree = ""; + }; + 5367B2651E60A29E001744C8 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5367B2661E60A29E001744C8 /* MapKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5367B26C1E60A5F0001744C8 /* Protocols and Extensions */ = { + isa = PBXGroup; + children = ( + 5367B26D1E60A641001744C8 /* ConfigurableCell.swift */, + 5367B26A1E60A5C6001744C8 /* ReusableIdentifier.swift */, + ); + name = "Protocols and Extensions"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 534452EE1E61B9E600649AF9 /* ContainerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 534452F61E61B9E600649AF9 /* Build configuration list for PBXNativeTarget "ContainerTests" */; + buildPhases = ( + 534452EB1E61B9E600649AF9 /* Sources */, + 534452EC1E61B9E600649AF9 /* Frameworks */, + 534452ED1E61B9E600649AF9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 534452F51E61B9E600649AF9 /* PBXTargetDependency */, + ); + name = ContainerTests; + productName = ContainerTests; + productReference = 534452EF1E61B9E600649AF9 /* ContainerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5367B2471E608B79001744C8 /* Container */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5367B25A1E608B79001744C8 /* Build configuration list for PBXNativeTarget "Container" */; + buildPhases = ( + 5367B2441E608B79001744C8 /* Sources */, + 5367B2451E608B79001744C8 /* Frameworks */, + 5367B2461E608B79001744C8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Container; + productName = Container; + productReference = 5367B2481E608B79001744C8 /* Container.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5367B2401E608B79001744C8 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 534452EE1E61B9E600649AF9 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + TestTargetID = 5367B2471E608B79001744C8; + }; + 5367B2471E608B79001744C8 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5367B2431E608B79001744C8 /* Build configuration list for PBXProject "Container" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5367B23F1E608B79001744C8; + productRefGroup = 5367B2491E608B79001744C8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5367B2471E608B79001744C8 /* Container */, + 534452EE1E61B9E600649AF9 /* ContainerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 534452ED1E61B9E600649AF9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5367B2461E608B79001744C8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5367B2561E608B79001744C8 /* LaunchScreen.storyboard in Resources */, + 534452FE1E61DF6200649AF9 /* locations.plist in Resources */, + 5367B2531E608B79001744C8 /* Assets.xcassets in Resources */, + 5367B2511E608B79001744C8 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 534452EB1E61B9E600649AF9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 534452FA1E61BA1F00649AF9 /* LocationTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5367B2441E608B79001744C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5367B26B1E60A5C6001744C8 /* ReusableIdentifier.swift in Sources */, + 5367B2691E60A3C3001744C8 /* LocationCell.swift in Sources */, + 5367B26E1E60A641001744C8 /* ConfigurableCell.swift in Sources */, + 5367B25E1E608BE4001744C8 /* MasterViewController.swift in Sources */, + 5367B2721E60A694001744C8 /* Location.swift in Sources */, + 5367B24C1E608B79001744C8 /* AppDelegate.swift in Sources */, + 5367B2601E60A129001744C8 /* LocationTableViewController.swift in Sources */, + 5367B2641E60A1A9001744C8 /* MapViewController.swift in Sources */, + 5367B2621E60A140001744C8 /* LocationDataSource.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 534452F51E61B9E600649AF9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5367B2471E608B79001744C8 /* Container */; + targetProxy = 534452F41E61B9E600649AF9 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5367B24F1E608B79001744C8 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5367B2501E608B79001744C8 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5367B2541E608B79001744C8 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5367B2551E608B79001744C8 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 534452F71E61B9E600649AF9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ContainerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ContainerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Container.app/Container"; + }; + name = Debug; + }; + 534452F81E61B9E600649AF9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ContainerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ContainerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Container.app/Container"; + }; + name = Release; + }; + 5367B2581E608B79001744C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5367B2591E608B79001744C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5367B25B1E608B79001744C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Container/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Container; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5367B25C1E608B79001744C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Container/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Container; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 534452F61E61B9E600649AF9 /* Build configuration list for PBXNativeTarget "ContainerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 534452F71E61B9E600649AF9 /* Debug */, + 534452F81E61B9E600649AF9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5367B2431E608B79001744C8 /* Build configuration list for PBXProject "Container" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5367B2581E608B79001744C8 /* Debug */, + 5367B2591E608B79001744C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5367B25A1E608B79001744C8 /* Build configuration list for PBXNativeTarget "Container" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5367B25B1E608B79001744C8 /* Debug */, + 5367B25C1E608B79001744C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5367B2401E608B79001744C8 /* Project object */; +} diff --git a/Container/Container-SB/Container/AppDelegate.swift b/Container/Container-SB/Container/AppDelegate.swift new file mode 100644 index 0000000..1e60a63 --- /dev/null +++ b/Container/Container-SB/Container/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/Container/Container-SB/Container/Assets.xcassets/AppIcon.appiconset/Contents.json b/Container/Container-SB/Container/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/Container/Container-SB/Container/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Container/Container-SB/Container/Base.lproj/LaunchScreen.storyboard b/Container/Container-SB/Container/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/Container/Container-SB/Container/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Container/Container-SB/Container/Base.lproj/Main.storyboard b/Container/Container-SB/Container/Base.lproj/Main.storyboard new file mode 100644 index 0000000..e5bdbfe --- /dev/null +++ b/Container/Container-SB/Container/Base.lproj/Main.storyboard @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Container/Container-SB/Container/ConfigurableCell.swift b/Container/Container-SB/Container/ConfigurableCell.swift new file mode 100644 index 0000000..eced6d5 --- /dev/null +++ b/Container/Container-SB/Container/ConfigurableCell.swift @@ -0,0 +1,38 @@ +// +// ConfigurableCell.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol ConfigurableCell { + associatedtype Object + func configure(object: Object) +} diff --git a/Container/Container-SB/Container/Info.plist b/Container/Container-SB/Container/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/Container/Container-SB/Container/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Container/Container-SB/Container/Location.swift b/Container/Container-SB/Container/Location.swift new file mode 100644 index 0000000..d65003c --- /dev/null +++ b/Container/Container-SB/Container/Location.swift @@ -0,0 +1,96 @@ +// +// Location.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 CoreLocation + +/// A structure representing the location of a point on +/// the map. + +struct Location { + + /// The name of the location. + + let name: String + + /// The latitude of the location in degrees. + + let latitude: CLLocationDegrees + + /// The longitude of the location in degrees. + + let longitude: CLLocationDegrees + + /// A read-only `CLLocationCoordinate2D` value for the + /// geographic coordinate of the location. + + var coordinate: CLLocationCoordinate2D { + return CLLocationCoordinate2DMake(latitude, longitude) + } +} + +extension Location { + + /// A failable initializer that builds a `Location` from + /// a dictionary of String keys and values. The dictionary + /// must contain at least "name", "latitude" and "longitude" + /// items. + /// + /// The values must all be `String` and the `latitude` + /// and `longitude` must convert to a `CLLocationDegrees` + /// value (Double) and specify a valid coordinate. A valid + /// latitude is from -90 to +90 and a valid longitude is + /// from -180 to +180. + /// + /// - Parameter dictionary: A dictionary containing the + /// details to initialize the location. + /// + /// - Returns: A `Location` structure or `nil` if the + /// dictionary was invalid, + + init?(dictionary: Dictionary) { + guard let name = dictionary["name"], + let latitudeItem = dictionary["latitude"], + let latitude = CLLocationDegrees(latitudeItem), + let longitudeItem = dictionary["longitude"], + let longitude = CLLocationDegrees(longitudeItem) else { + return nil + } + + self.name = name + self.latitude = latitude + self.longitude = longitude + if !CLLocationCoordinate2DIsValid(coordinate) { + return nil + } + } +} diff --git a/Container/Container-SB/Container/LocationCell.swift b/Container/Container-SB/Container/LocationCell.swift new file mode 100644 index 0000000..a2b4da9 --- /dev/null +++ b/Container/Container-SB/Container/LocationCell.swift @@ -0,0 +1,46 @@ +// +// LocationCell.swift +// Container +// +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017-2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LocationCell: UITableViewCell, ReusableIdentifier { + @IBOutlet private var name: UILabel! + @IBOutlet private var coordinates: UILabel! +} + +extension LocationCell: ConfigurableCell { + func configure(object: Location) { + name.text = object.name + coordinates.text = String("\(object.latitude) \(object.longitude)") + } +} diff --git a/Container/Container-SB/Container/LocationDataSource.swift b/Container/Container-SB/Container/LocationDataSource.swift new file mode 100644 index 0000000..96ac6e3 --- /dev/null +++ b/Container/Container-SB/Container/LocationDataSource.swift @@ -0,0 +1,88 @@ +// +// LocationDataSource.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LocationDataSource: NSObject { + + private let tableView: UITableView + private var locations = [Location]() + + init(tableView: UITableView, from path: String) { + self.tableView = tableView + super.init() + readFromPlist(name: path) + tableView.dataSource = self + tableView.reloadData() + } + + func locationAtIndexPath(_ indexPath: IndexPath) -> Location? { + return indexPath.row < locations.count ? locations[indexPath.row] : nil + } + + private func readFromPlist(name: String) { + guard let items = NSArray(contentsOfFile: name) as? [Dictionary] else { + return + } + for item in items { + if let location = Location(dictionary: item) { + locations.append(location) + } + } + } +} + +extension LocationDataSource: UITableViewDataSource { + + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return locations.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: LocationCell.reuseIdentifier, for: indexPath) + configure(cell: cell, indexPath: indexPath) + return cell + } + + private func configure(cell: UITableViewCell, indexPath: IndexPath) { + if let cell = cell as? LocationCell { + let object = locations[indexPath.row] + cell.configure(object: object) + } + } +} + diff --git a/Container/Container-SB/Container/LocationTableViewController.swift b/Container/Container-SB/Container/LocationTableViewController.swift new file mode 100644 index 0000000..fa87ebb --- /dev/null +++ b/Container/Container-SB/Container/LocationTableViewController.swift @@ -0,0 +1,63 @@ +// +// LocationTableViewController.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol LocationProviderDelegate: AnyObject { + func didSelectLocation(_ location: Location) +} + +final class LocationTableViewController: UITableViewController { + + weak var delegate:LocationProviderDelegate? + + private var locationDataSource: LocationDataSource? + + override func viewDidLoad() { + super.viewDidLoad() + tableView.rowHeight = UITableView.automaticDimension + tableView.estimatedRowHeight = UITableView.automaticDimension + tableView.delegate = self + + if let plistPath = Bundle.main.path(forResource: "locations", ofType: "plist") { + locationDataSource = LocationDataSource(tableView: tableView, from: plistPath) + tableView.dataSource = locationDataSource + } + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if let location = locationDataSource?.locationAtIndexPath(indexPath) { + delegate?.didSelectLocation(location) + } + } +} diff --git a/Container/Container-SB/Container/MapViewController.swift b/Container/Container-SB/Container/MapViewController.swift new file mode 100644 index 0000000..34ab9c7 --- /dev/null +++ b/Container/Container-SB/Container/MapViewController.swift @@ -0,0 +1,92 @@ +// +// MapViewController.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +import MapKit + +final class MapViewController: UIViewController { + + @IBOutlet private var mapView: MKMapView! + + /// The zoom level to use when setting the span + /// of the map region to show. Default is 10 degrees. + + var zoom: CLLocationDegrees = 10.0 + + /// The coordinate to center the map on. Setting a new + /// coordinate centers the map on a region spanned by + /// the `zoom` level and drops a pin annotation at the + /// coordinate. + + var coordinate: CLLocationCoordinate2D? { + didSet { + if let coordinate = coordinate { + centerMap(coordinate) + annotate(coordinate) + } + } + } + + private func centerMap(_ coordinate: CLLocationCoordinate2D) { + let span = MKCoordinateSpan.init(latitudeDelta: zoom, longitudeDelta: zoom) + let region = MKCoordinateRegion(center: coordinate, span: span) + mapView.setRegion(region, animated: true) + } + + private func annotate(_ coordinate: CLLocationCoordinate2D) { + let annotation = MKPointAnnotation() + annotation.coordinate = coordinate + mapView.addAnnotation(annotation) + } +} + +extension MapViewController: MKMapViewDelegate { + + private enum AnnotationView: String { + case pin = "Pin" + } + + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + guard let annotation = annotation as? MKPointAnnotation else { + return nil + } + + let identifier = AnnotationView.pin.rawValue + guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView else { + return MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) + } + + annotationView.annotation = annotation + return annotationView + } +} diff --git a/Container/Container-SB/Container/MasterViewController.swift b/Container/Container-SB/Container/MasterViewController.swift new file mode 100644 index 0000000..13c91d1 --- /dev/null +++ b/Container/Container-SB/Container/MasterViewController.swift @@ -0,0 +1,86 @@ +// +// MasterViewController.swift +// Container +// +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017-2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class MasterViewController: UIViewController { + @IBOutlet private var topStackView: UIStackView! + private var locationTableViewController: LocationTableViewController? + private var mapViewController: MapViewController? + +// override func viewDidLoad() { +// super.viewDidLoad() +// guard let locationController = childViewControllers.first as? LocationTableViewController else { +// fatalError("Check storyboard for missing LocationTableViewController") +// } +// +// guard let mapController = childViewControllers.last as? MapViewController else { +// fatalError("Check storyboard for missing MapViewController") +// } +// +// locationTableViewController = locationController +// mapViewController = mapController +// locationController.delegate = self +// } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + topStackView.axis = axisForSize(view.bounds.size) + } + + // Alternative to wiring up the interface in viewDidLoad (above) is to + // use prepare(for segue:sender:) which is still called for + // embed segues. + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + let destination = segue.destination + if let locationController = destination as? LocationTableViewController { + locationTableViewController = locationController + locationController.delegate = self + } + + if let mapController = destination as? MapViewController { + mapViewController = mapController + } + } + + private func axisForSize(_ size: CGSize) -> NSLayoutConstraint.Axis { + return size.width > size.height ? .horizontal : .vertical + } +} + +extension MasterViewController: LocationProviderDelegate { + func didSelectLocation(_ location: Location) { + mapViewController?.coordinate = location.coordinate + } +} diff --git a/Container/Container-SB/Container/ReusableIdentifier.swift b/Container/Container-SB/Container/ReusableIdentifier.swift new file mode 100644 index 0000000..893e7f4 --- /dev/null +++ b/Container/Container-SB/Container/ReusableIdentifier.swift @@ -0,0 +1,43 @@ +// +// ReusableIdentifier.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016-2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol ReusableIdentifier: class { + static var reuseIdentifier: String { get } +} + +extension ReusableIdentifier { + static var reuseIdentifier: String { + return "\(self)" + } +} diff --git a/Container/Container-SB/Container/locations.plist b/Container/Container-SB/Container/locations.plist new file mode 100644 index 0000000..1d4ad3c --- /dev/null +++ b/Container/Container-SB/Container/locations.plist @@ -0,0 +1,247 @@ +( +{name="Afghanistan";latitude="33.93911";longitude="67.709953";}, +{name="Albania";latitude="41.153332";longitude="20.168331";}, +{name="Algeria";latitude="28.033886";longitude="1.659626";}, +{name="American Samoa";latitude="-14.270972";longitude="-170.132217";}, +{name="Andorra";latitude="42.546245";longitude="1.601554";}, +{name="Angola";latitude="-11.202692";longitude="17.873887";}, +{name="Anguilla";latitude="18.220554";longitude="-63.068615";}, +{name="Antarctica";latitude="-75.250973";longitude="-0.071389";}, +{name="Antigua and Barbuda";latitude="17.060816";longitude="-61.796428";}, +{name="Argentina";latitude="-38.416097";longitude="-63.616672";}, +{name="Armenia";latitude="40.069099";longitude="45.038189";}, +{name="Aruba";latitude="12.52111";longitude="-69.968338";}, +{name="Australia";latitude="-25.274398";longitude="133.775136";}, +{name="Austria";latitude="47.516231";longitude="14.550072";}, +{name="Azerbaijan";latitude="40.143105";longitude="47.576927";}, +{name="Bahamas";latitude="25.03428";longitude="-77.39628";}, +{name="Bahrain";latitude="25.930414";longitude="50.637772";}, +{name="Bangladesh";latitude="23.684994";longitude="90.356331";}, +{name="Barbados";latitude="13.193887";longitude="-59.543198";}, +{name="Belarus";latitude="53.709807";longitude="27.953389";}, +{name="Belgium";latitude="50.503887";longitude="4.469936";}, +{name="Belize";latitude="17.189877";longitude="-88.49765";}, +{name="Benin";latitude="9.30769";longitude="2.315834";}, +{name="Bermuda";latitude="32.321384";longitude="-64.75737";}, +{name="Bhutan";latitude="27.514162";longitude="90.433601";}, +{name="Bolivia";latitude="-16.290154";longitude="-63.588653";}, +{name="Bosnia and Herzegovina";latitude="43.915886";longitude="17.679076";}, +{name="Botswana";latitude="-22.328474";longitude="24.684866";}, +{name="Bouvet Island";latitude="-54.423199";longitude="3.413194";}, +{name="Brazil";latitude="-14.235004";longitude="-51.92528";}, +{name="British Indian Ocean Territory";latitude="-6.343194";longitude="71.876519";}, +{name="British Virgin Islands";latitude="18.420695";longitude="-64.639968";}, +{name="Brunei";latitude="4.535277";longitude="114.727669";}, +{name="Bulgaria";latitude="42.733883";longitude="25.48583";}, +{name="Burkina Faso";latitude="12.238333";longitude="-1.561593";}, +{name="Burundi";latitude="-3.373056";longitude="29.918886";}, +{name="Cambodia";latitude="12.565679";longitude="104.990963";}, +{name="Cameroon";latitude="7.369722";longitude="12.354722";}, +{name="Canada";latitude="56.130366";longitude="-106.346771";}, +{name="Cape Verde";latitude="16.002082";longitude="-24.013197";}, +{name="Cayman Islands";latitude="19.513469";longitude="-80.566956";}, +{name="Central African Republic";latitude="6.611111";longitude="20.939444";}, +{name="Chad";latitude="15.454166";longitude="18.732207";}, +{name="Chile";latitude="-35.675147";longitude="-71.542969";}, +{name="China";latitude="35.86166";longitude="104.195397";}, +{name="Christmas Island";latitude="-10.447525";longitude="105.690449";}, +{name="Cocos [Keeling] Islands";latitude="-12.164165";longitude="96.870956";}, +{name="Colombia";latitude="4.570868";longitude="-74.297333";}, +{name="Comoros";latitude="-11.875001";longitude="43.872219";}, +{name="Congo [DRC]";latitude="-4.038333";longitude="21.758664";}, +{name="Congo [Republic]";latitude="-0.228021";longitude="15.827659";}, +{name="Cook Islands";latitude="-21.236736";longitude="-159.777671";}, +{name="Costa Rica";latitude="9.748917";longitude="-83.753428";}, +{name="Croatia";latitude="45.1";longitude="15.2";}, +{name="Cuba";latitude="21.521757";longitude="-77.781167";}, +{name="Cyprus";latitude="35.126413";longitude="33.429859";}, +{name="Czech Republic";latitude="49.817492";longitude="15.472962";}, +{name="Côte d'Ivoire";latitude="7.539989";longitude="-5.54708";}, +{name="Denmark";latitude="56.26392";longitude="9.501785";}, +{name="Djibouti";latitude="11.825138";longitude="42.590275";}, +{name="Dominica";latitude="15.414999";longitude="-61.370976";}, +{name="Dominican Republic";latitude="18.735693";longitude="-70.162651";}, +{name="Ecuador";latitude="-1.831239";longitude="-78.183406";}, +{name="Egypt";latitude="26.820553";longitude="30.802498";}, +{name="El Salvador";latitude="13.794185";longitude="-88.89653";}, +{name="Equatorial Guinea";latitude="1.650801";longitude="10.267895";}, +{name="Eritrea";latitude="15.179384";longitude="39.782334";}, +{name="Estonia";latitude="58.595272";longitude="25.013607";}, +{name="Ethiopia";latitude="9.145";longitude="40.489673";}, +{name="Falkland Islands [Islas Malvinas]";latitude="-51.796253";longitude="-59.523613";}, +{name="Faroe Islands";latitude="61.892635";longitude="-6.911806";}, +{name="Fiji";latitude="-16.578193";longitude="179.414413";}, +{name="Finland";latitude="61.92411";longitude="25.748151";}, +{name="France";latitude="46.227638";longitude="2.213749";}, +{name="French Guiana";latitude="3.933889";longitude="-53.125782";}, +{name="French Polynesia";latitude="-17.679742";longitude="-149.406843";}, +{name="French Southern Territories";latitude="-49.280366";longitude="69.348557";}, +{name="Gabon";latitude="-0.803689";longitude="11.609444";}, +{name="Gambia";latitude="13.443182";longitude="-15.310139";}, +{name="Gaza Strip";latitude="31.354676";longitude="34.308825";}, +{name="Georgia";latitude="42.315407";longitude="43.356892";}, +{name="Germany";latitude="51.165691";longitude="10.451526";}, +{name="Ghana";latitude="7.946527";longitude="-1.023194";}, +{name="Gibraltar";latitude="36.137741";longitude="-5.345374";}, +{name="Greece";latitude="39.074208";longitude="21.824312";}, +{name="Greenland";latitude="71.706936";longitude="-42.604303";}, +{name="Grenada";latitude="12.262776";longitude="-61.604171";}, +{name="Guadeloupe";latitude="16.995971";longitude="-62.067641";}, +{name="Guam";latitude="13.444304";longitude="144.793731";}, +{name="Guatemala";latitude="15.783471";longitude="-90.230759";}, +{name="Guernsey";latitude="49.465691";longitude="-2.585278";}, +{name="Guinea";latitude="9.945587";longitude="-9.696645";}, +{name="Guinea-Bissau";latitude="11.803749";longitude="-15.180413";}, +{name="Guyana";latitude="4.860416";longitude="-58.93018";}, +{name="Haiti";latitude="18.971187";longitude="-72.285215";}, +{name="Heard Island and McDonald Islands";latitude="-53.08181";longitude="73.504158";}, +{name="Honduras";latitude="15.199999";longitude="-86.241905";}, +{name="Hong Kong";latitude="22.396428";longitude="114.109497";}, +{name="Hungary";latitude="47.162494";longitude="19.503304";}, +{name="Iceland";latitude="64.963051";longitude="-19.020835";}, +{name="India";latitude="20.593684";longitude="78.96288";}, +{name="Indonesia";latitude="-0.789275";longitude="113.921327";}, +{name="Iran";latitude="32.427908";longitude="53.688046";}, +{name="Iraq";latitude="33.223191";longitude="43.679291";}, +{name="Ireland";latitude="53.41291";longitude="-8.24389";}, +{name="Isle of Man";latitude="54.236107";longitude="-4.548056";}, +{name="Israel";latitude="31.046051";longitude="34.851612";}, +{name="Italy";latitude="41.87194";longitude="12.56738";}, +{name="Jamaica";latitude="18.109581";longitude="-77.297508";}, +{name="Japan";latitude="36.204824";longitude="138.252924";}, +{name="Jersey";latitude="49.214439";longitude="-2.13125";}, +{name="Jordan";latitude="30.585164";longitude="36.238414";}, +{name="Kazakhstan";latitude="48.019573";longitude="66.923684";}, +{name="Kenya";latitude="-0.023559";longitude="37.906193";}, +{name="Kiribati";latitude="-3.370417";longitude="-168.734039";}, +{name="Kosovo";latitude="42.602636";longitude="20.902977";}, +{name="Kuwait";latitude="29.31166";longitude="47.481766";}, +{name="Kyrgyzstan";latitude="41.20438";longitude="74.766098";}, +{name="Laos";latitude="19.85627";longitude="102.495496";}, +{name="Latvia";latitude="56.879635";longitude="24.603189";}, +{name="Lebanon";latitude="33.854721";longitude="35.862285";}, +{name="Lesotho";latitude="-29.609988";longitude="28.233608";}, +{name="Liberia";latitude="6.428055";longitude="-9.429499";}, +{name="Libya";latitude="26.3351";longitude="17.228331";}, +{name="Liechtenstein";latitude="47.166";longitude="9.555373";}, +{name="Lithuania";latitude="55.169438";longitude="23.881275";}, +{name="Luxembourg";latitude="49.815273";longitude="6.129583";}, +{name="Macau";latitude="22.198745";longitude="113.543873";}, +{name="Macedonia [FYROM]";latitude="41.608635";longitude="21.745275";}, +{name="Madagascar";latitude="-18.766947";longitude="46.869107";}, +{name="Malawi";latitude="-13.254308";longitude="34.301525";}, +{name="Malaysia";latitude="4.210484";longitude="101.975766";}, +{name="Maldives";latitude="3.202778";longitude="73.22068";}, +{name="Mali";latitude="17.570692";longitude="-3.996166";}, +{name="Malta";latitude="35.937496";longitude="14.375416";}, +{name="Marshall Islands";latitude="7.131474";longitude="171.184478";}, +{name="Martinique";latitude="14.641528";longitude="-61.024174";}, +{name="Mauritania";latitude="21.00789";longitude="-10.940835";}, +{name="Mauritius";latitude="-20.348404";longitude="57.552152";}, +{name="Mayotte";latitude="-12.8275";longitude="45.166244";}, +{name="Mexico";latitude="23.634501";longitude="-102.552784";}, +{name="Micronesia";latitude="7.425554";longitude="150.550812";}, +{name="Moldova";latitude="47.411631";longitude="28.369885";}, +{name="Monaco";latitude="43.750298";longitude="7.412841";}, +{name="Mongolia";latitude="46.862496";longitude="103.846656";}, +{name="Montenegro";latitude="42.708678";longitude="19.37439";}, +{name="Montserrat";latitude="16.742498";longitude="-62.187366";}, +{name="Morocco";latitude="31.791702";longitude="-7.09262";}, +{name="Mozambique";latitude="-18.665695";longitude="35.529562";}, +{name="Myanmar [Burma]";latitude="21.913965";longitude="95.956223";}, +{name="Namibia";latitude="-22.95764";longitude="18.49041";}, +{name="Nauru";latitude="-0.522778";longitude="166.931503";}, +{name="Nepal";latitude="28.394857";longitude="84.124008";}, +{name="Netherlands Antilles";latitude="12.226079";longitude="-69.060087";}, +{name="Netherlands";latitude="52.132633";longitude="5.291266";}, +{name="New Caledonia";latitude="-20.904305";longitude="165.618042";}, +{name="New Zealand";latitude="-40.900557";longitude="174.885971";}, +{name="Nicaragua";latitude="12.865416";longitude="-85.207229";}, +{name="Niger";latitude="17.607789";longitude="8.081666";}, +{name="Nigeria";latitude="9.081999";longitude="8.675277";}, +{name="Niue";latitude="-19.054445";longitude="-169.867233";}, +{name="Norfolk Island";latitude="-29.040835";longitude="167.954712";}, +{name="North Korea";latitude="40.339852";longitude="127.510093";}, +{name="Northern Mariana Islands";latitude="17.33083";longitude="145.38469";}, +{name="Norway";latitude="60.472024";longitude="8.468946";}, +{name="Oman";latitude="21.512583";longitude="55.923255";}, +{name="Pakistan";latitude="30.375321";longitude="69.345116";}, +{name="Palau";latitude="7.51498";longitude="134.58252";}, +{name="Palestinian Territories";latitude="31.952162";longitude="35.233154";}, +{name="Panama";latitude="8.537981";longitude="-80.782127";}, +{name="Papua New Guinea";latitude="-6.314993";longitude="143.95555";}, +{name="Paraguay";latitude="-23.442503";longitude="-58.443832";}, +{name="Peru";latitude="-9.189967";longitude="-75.015152";}, +{name="Philippines";latitude="12.879721";longitude="121.774017";}, +{name="Pitcairn Islands";latitude="-24.703615";longitude="-127.439308";}, +{name="Poland";latitude="51.919438";longitude="19.145136";}, +{name="Portugal";latitude="39.399872";longitude="-8.224454";}, +{name="Puerto Rico";latitude="18.220833";longitude="-66.590149";}, +{name="Qatar";latitude="25.354826";longitude="51.183884";}, +{name="Romania";latitude="45.943161";longitude="24.96676";}, +{name="Russia";latitude="61.52401";longitude="105.318756";}, +{name="Rwanda";latitude="-1.940278";longitude="29.873888";}, +{name="Réunion";latitude="-21.115141";longitude="55.536384";}, +{name="Saint Helena";latitude="-24.143474";longitude="-10.030696";}, +{name="Saint Kitts and Nevis";latitude="17.357822";longitude="-62.782998";}, +{name="Saint Lucia";latitude="13.909444";longitude="-60.978893";}, +{name="Saint Pierre and Miquelon";latitude="46.941936";longitude="-56.27111";}, +{name="Saint Vincent and the Grenadines";latitude="12.984305";longitude="-61.287228";}, +{name="Samoa";latitude="-13.759029";longitude="-172.104629";}, +{name="San Marino";latitude="43.94236";longitude="12.457777";}, +{name="Saudi Arabia";latitude="23.885942";longitude="45.079162";}, +{name="Senegal";latitude="14.497401";longitude="-14.452362";}, +{name="Serbia";latitude="44.016521";longitude="21.005859";}, +{name="Seychelles";latitude="-4.679574";longitude="55.491977";}, +{name="Sierra Leone";latitude="8.460555";longitude="-11.779889";}, +{name="Singapore";latitude="1.352083";longitude="103.819836";}, +{name="Slovakia";latitude="48.669026";longitude="19.699024";}, +{name="Slovenia";latitude="46.151241";longitude="14.995463";}, +{name="Solomon Islands";latitude="-9.64571";longitude="160.156194";}, +{name="Somalia";latitude="5.152149";longitude="46.199616";}, +{name="South Africa";latitude="-30.559482";longitude="22.937506";}, +{name="South Georgia and the South Sandwich Islands";latitude="-54.429579";longitude="-36.587909";}, +{name="South Korea";latitude="35.907757";longitude="127.766922";}, +{name="Spain";latitude="40.463667";longitude="-3.74922";}, +{name="Sri Lanka";latitude="7.873054";longitude="80.771797";}, +{name="Sudan";latitude="12.862807";longitude="30.217636";}, +{name="Suriname";latitude="3.919305";longitude="-56.027783";}, +{name="Svalbard and Jan Mayen";latitude="77.553604";longitude="23.670272";}, +{name="Swaziland";latitude="-26.522503";longitude="31.465866";}, +{name="Sweden";latitude="60.128161";longitude="18.643501";}, +{name="Switzerland";latitude="46.818188";longitude="8.227512";}, +{name="Syria";latitude="34.802075";longitude="38.996815";}, +{name="São Tomé and Príncipe";latitude="0.18636";longitude="6.613081";}, +{name="Taiwan";latitude="23.69781";longitude="120.960515";}, +{name="Tajikistan";latitude="38.861034";longitude="71.276093";}, +{name="Tanzania";latitude="-6.369028";longitude="34.888822";}, +{name="Thailand";latitude="15.870032";longitude="100.992541";}, +{name="Timor-Leste";latitude="-8.874217";longitude="125.727539";}, +{name="Togo";latitude="8.619543";longitude="0.824782";}, +{name="Tokelau";latitude="-8.967363";longitude="-171.855881";}, +{name="Tonga";latitude="-21.178986";longitude="-175.198242";}, +{name="Trinidad and Tobago";latitude="10.691803";longitude="-61.222503";}, +{name="Tunisia";latitude="33.886917";longitude="9.537499";}, +{name="Turkey";latitude="38.963745";longitude="35.243322";}, +{name="Turkmenistan";latitude="38.969719";longitude="59.556278";}, +{name="Turks and Caicos Islands";latitude="21.694025";longitude="-71.797928";}, +{name="Tuvalu";latitude="-7.109535";longitude="177.64933";}, +{name="U.S. Minor Outlying Islands";latitude="";longitude="";}, +{name="U.S. Virgin Islands";latitude="18.335765";longitude="-64.896335";}, +{name="Uganda";latitude="1.373333";longitude="32.290275";}, +{name="Ukraine";latitude="48.379433";longitude="31.16558";}, +{name="United Arab Emirates";latitude="23.424076";longitude="53.847818";}, +{name="United Kingdom";latitude="55.378051";longitude="-3.435973";}, +{name="United States";latitude="37.09024";longitude="-95.712891";}, +{name="Uruguay";latitude="-32.522779";longitude="-55.765835";}, +{name="Uzbekistan";latitude="41.377491";longitude="64.585262";}, +{name="Vanuatu";latitude="-15.376706";longitude="166.959158";}, +{name="Vatican City";latitude="41.902916";longitude="12.453389";}, +{name="Venezuela";latitude="6.42375";longitude="-66.58973";}, +{name="Vietnam";latitude="14.058324";longitude="108.277199";}, +{name="Wallis and Futuna";latitude="-13.768752";longitude="-177.156097";}, +{name="Western Sahara";latitude="24.215527";longitude="-12.885834";}, +{name="Yemen";latitude="15.552727";longitude="48.516388";}, +{name="Zambia";latitude="-13.133897";longitude="27.849332";}, +{name="Zimbabwe";latitude="-19.015438";longitude="29.154857";} +) diff --git a/Stacks/StacksUITests/Info.plist b/Container/Container-SB/ContainerTests/Info.plist similarity index 92% rename from Stacks/StacksUITests/Info.plist rename to Container/Container-SB/ContainerTests/Info.plist index ba72822..6c6c23c 100644 --- a/Stacks/StacksUITests/Info.plist +++ b/Container/Container-SB/ContainerTests/Info.plist @@ -16,8 +16,6 @@ BNDL CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion 1 diff --git a/Container/Container-SB/ContainerTests/LocationTests.swift b/Container/Container-SB/ContainerTests/LocationTests.swift new file mode 100644 index 0000000..93179fa --- /dev/null +++ b/Container/Container-SB/ContainerTests/LocationTests.swift @@ -0,0 +1,105 @@ +// +// LocationTests.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 XCTest +import CoreLocation + +@testable import Container + +class LocationTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testInitFromDictionary() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "-25", + "longitude" : "135"]) + XCTAssertNotNil(australia) + XCTAssert(australia?.name == "Australia") + XCTAssert(australia?.latitude == -25.0) + XCTAssert(australia?.longitude == 135.0) + } + + func testMissingName() { + let australia = Location(dictionary: ["latitude" : "-25", + "longitude" : "135"]) + XCTAssertNil(australia) + } + + func testMissingLatitude() { + let australia = Location(dictionary: ["name" : "Australis", + "longitude" : "135"]) + XCTAssertNil(australia) + } + + func testMissingLongitude() { + let australia = Location(dictionary: ["name" : "Australis", + "latitude" : "-25"]) + XCTAssertNil(australia) + } + + func testExtraKeysIgnored() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "-25", + "longitude" : "135", + "capital" : "Canberra"]) + XCTAssertNotNil(australia) + } + + func testInvalidLatitude() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "hello", + "longitude" : "135"]) + XCTAssertNil(australia) + } + + func testInvalidLongitude() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "-25", + "longitude" : "12a"]) + XCTAssertNil(australia) + } + + func testInvalidCoordinare() { + let nowhere = Location(dictionary: ["name" : "OffTheGrid", + "latitude" : "-100", + "longitude" : "200"]) + XCTAssertNil(nowhere) + } +} diff --git a/Container/Container-SB/README.md b/Container/Container-SB/README.md new file mode 100644 index 0000000..ce4638f --- /dev/null +++ b/Container/Container-SB/README.md @@ -0,0 +1,6 @@ +### Attribution + +The country location data used in this example is based on work created and [shared by Google](https://developers.google.com/readme/policies/) and used according to terms described in [Creative Commons 3.0 Attribution License](http://creativecommons.org/licenses/by/3.0/). + +See the [original source page](https://developers.google.com/public-data/docs/canonical/countries_csv) for details. + diff --git a/Container/Container-code/Container.xcodeproj/project.pbxproj b/Container/Container-code/Container.xcodeproj/project.pbxproj new file mode 100644 index 0000000..53c988d --- /dev/null +++ b/Container/Container-code/Container.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 534452FA1E61BA1F00649AF9 /* LocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 534452F91E61BA1F00649AF9 /* LocationTests.swift */; }; + 534452FE1E61DF6200649AF9 /* locations.plist in Resources */ = {isa = PBXBuildFile; fileRef = 534452FD1E61DF6100649AF9 /* locations.plist */; }; + 5367B24C1E608B79001744C8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B24B1E608B79001744C8 /* AppDelegate.swift */; }; + 5367B2511E608B79001744C8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5367B24F1E608B79001744C8 /* Main.storyboard */; }; + 5367B2531E608B79001744C8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5367B2521E608B79001744C8 /* Assets.xcassets */; }; + 5367B2561E608B79001744C8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5367B2541E608B79001744C8 /* LaunchScreen.storyboard */; }; + 5367B25E1E608BE4001744C8 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B25D1E608BE4001744C8 /* MasterViewController.swift */; }; + 5367B2601E60A129001744C8 /* LocationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B25F1E60A129001744C8 /* LocationTableViewController.swift */; }; + 5367B2621E60A140001744C8 /* LocationDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2611E60A140001744C8 /* LocationDataSource.swift */; }; + 5367B2641E60A1A9001744C8 /* MapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2631E60A1A9001744C8 /* MapViewController.swift */; }; + 5367B2691E60A3C3001744C8 /* LocationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2681E60A3C3001744C8 /* LocationCell.swift */; }; + 5367B26B1E60A5C6001744C8 /* ReusableIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B26A1E60A5C6001744C8 /* ReusableIdentifier.swift */; }; + 5367B26E1E60A641001744C8 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B26D1E60A641001744C8 /* ConfigurableCell.swift */; }; + 5367B2721E60A694001744C8 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5367B2711E60A694001744C8 /* Location.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 534452F41E61B9E600649AF9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5367B2401E608B79001744C8 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5367B2471E608B79001744C8; + remoteInfo = Container; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 534452EF1E61B9E600649AF9 /* ContainerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ContainerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 534452F31E61B9E600649AF9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 534452F91E61BA1F00649AF9 /* LocationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationTests.swift; sourceTree = ""; }; + 534452FD1E61DF6100649AF9 /* locations.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = locations.plist; sourceTree = ""; }; + 534452FF1E6216A100649AF9 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; }; + 5367B2481E608B79001744C8 /* Container.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Container.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5367B24B1E608B79001744C8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5367B2501E608B79001744C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5367B2521E608B79001744C8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5367B2551E608B79001744C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5367B2571E608B79001744C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5367B25D1E608BE4001744C8 /* MasterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterViewController.swift; sourceTree = ""; }; + 5367B25F1E60A129001744C8 /* LocationTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationTableViewController.swift; sourceTree = ""; }; + 5367B2611E60A140001744C8 /* LocationDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationDataSource.swift; sourceTree = ""; }; + 5367B2631E60A1A9001744C8 /* MapViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapViewController.swift; sourceTree = ""; }; + 5367B2661E60A29E001744C8 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; + 5367B2681E60A3C3001744C8 /* LocationCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationCell.swift; sourceTree = ""; }; + 5367B26A1E60A5C6001744C8 /* ReusableIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReusableIdentifier.swift; sourceTree = ""; }; + 5367B26D1E60A641001744C8 /* ConfigurableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurableCell.swift; sourceTree = ""; }; + 5367B2711E60A694001744C8 /* Location.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 534452EC1E61B9E600649AF9 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5367B2451E608B79001744C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 534452F01E61B9E600649AF9 /* ContainerTests */ = { + isa = PBXGroup; + children = ( + 534452F91E61BA1F00649AF9 /* LocationTests.swift */, + 534452F31E61B9E600649AF9 /* Info.plist */, + ); + path = ContainerTests; + sourceTree = ""; + }; + 534453011E6217D600649AF9 /* Controllers */ = { + isa = PBXGroup; + children = ( + 5367B25D1E608BE4001744C8 /* MasterViewController.swift */, + 5367B2631E60A1A9001744C8 /* MapViewController.swift */, + 5367B25F1E60A129001744C8 /* LocationTableViewController.swift */, + ); + name = Controllers; + sourceTree = ""; + }; + 534453021E6217E300649AF9 /* Delegates and DataSources */ = { + isa = PBXGroup; + children = ( + 5367B24B1E608B79001744C8 /* AppDelegate.swift */, + 5367B2611E60A140001744C8 /* LocationDataSource.swift */, + ); + name = "Delegates and DataSources"; + sourceTree = ""; + }; + 534453031E6217F800649AF9 /* Model */ = { + isa = PBXGroup; + children = ( + 534452FD1E61DF6100649AF9 /* locations.plist */, + 5367B2711E60A694001744C8 /* Location.swift */, + ); + name = Model; + sourceTree = ""; + }; + 534453041E62181D00649AF9 /* Views */ = { + isa = PBXGroup; + children = ( + 5367B2681E60A3C3001744C8 /* LocationCell.swift */, + 5367B24F1E608B79001744C8 /* Main.storyboard */, + 5367B2521E608B79001744C8 /* Assets.xcassets */, + 5367B2541E608B79001744C8 /* LaunchScreen.storyboard */, + ); + name = Views; + sourceTree = ""; + }; + 534453051E62182900649AF9 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5367B2571E608B79001744C8 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5367B23F1E608B79001744C8 = { + isa = PBXGroup; + children = ( + 534452FF1E6216A100649AF9 /* README.md */, + 5367B24A1E608B79001744C8 /* Container */, + 534452F01E61B9E600649AF9 /* ContainerTests */, + 5367B2491E608B79001744C8 /* Products */, + 5367B2651E60A29E001744C8 /* Frameworks */, + ); + sourceTree = ""; + }; + 5367B2491E608B79001744C8 /* Products */ = { + isa = PBXGroup; + children = ( + 5367B2481E608B79001744C8 /* Container.app */, + 534452EF1E61B9E600649AF9 /* ContainerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5367B24A1E608B79001744C8 /* Container */ = { + isa = PBXGroup; + children = ( + 5367B26C1E60A5F0001744C8 /* Protocols and Extensions */, + 534453031E6217F800649AF9 /* Model */, + 534453011E6217D600649AF9 /* Controllers */, + 534453021E6217E300649AF9 /* Delegates and DataSources */, + 534453041E62181D00649AF9 /* Views */, + 534453051E62182900649AF9 /* Supporting Files */, + ); + path = Container; + sourceTree = ""; + }; + 5367B2651E60A29E001744C8 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5367B2661E60A29E001744C8 /* MapKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5367B26C1E60A5F0001744C8 /* Protocols and Extensions */ = { + isa = PBXGroup; + children = ( + 5367B26D1E60A641001744C8 /* ConfigurableCell.swift */, + 5367B26A1E60A5C6001744C8 /* ReusableIdentifier.swift */, + ); + name = "Protocols and Extensions"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 534452EE1E61B9E600649AF9 /* ContainerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 534452F61E61B9E600649AF9 /* Build configuration list for PBXNativeTarget "ContainerTests" */; + buildPhases = ( + 534452EB1E61B9E600649AF9 /* Sources */, + 534452EC1E61B9E600649AF9 /* Frameworks */, + 534452ED1E61B9E600649AF9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 534452F51E61B9E600649AF9 /* PBXTargetDependency */, + ); + name = ContainerTests; + productName = ContainerTests; + productReference = 534452EF1E61B9E600649AF9 /* ContainerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5367B2471E608B79001744C8 /* Container */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5367B25A1E608B79001744C8 /* Build configuration list for PBXNativeTarget "Container" */; + buildPhases = ( + 5367B2441E608B79001744C8 /* Sources */, + 5367B2451E608B79001744C8 /* Frameworks */, + 5367B2461E608B79001744C8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Container; + productName = Container; + productReference = 5367B2481E608B79001744C8 /* Container.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5367B2401E608B79001744C8 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 534452EE1E61B9E600649AF9 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + TestTargetID = 5367B2471E608B79001744C8; + }; + 5367B2471E608B79001744C8 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5367B2431E608B79001744C8 /* Build configuration list for PBXProject "Container" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5367B23F1E608B79001744C8; + productRefGroup = 5367B2491E608B79001744C8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5367B2471E608B79001744C8 /* Container */, + 534452EE1E61B9E600649AF9 /* ContainerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 534452ED1E61B9E600649AF9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5367B2461E608B79001744C8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5367B2561E608B79001744C8 /* LaunchScreen.storyboard in Resources */, + 534452FE1E61DF6200649AF9 /* locations.plist in Resources */, + 5367B2531E608B79001744C8 /* Assets.xcassets in Resources */, + 5367B2511E608B79001744C8 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 534452EB1E61B9E600649AF9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 534452FA1E61BA1F00649AF9 /* LocationTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5367B2441E608B79001744C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5367B26B1E60A5C6001744C8 /* ReusableIdentifier.swift in Sources */, + 5367B2691E60A3C3001744C8 /* LocationCell.swift in Sources */, + 5367B26E1E60A641001744C8 /* ConfigurableCell.swift in Sources */, + 5367B25E1E608BE4001744C8 /* MasterViewController.swift in Sources */, + 5367B2721E60A694001744C8 /* Location.swift in Sources */, + 5367B24C1E608B79001744C8 /* AppDelegate.swift in Sources */, + 5367B2601E60A129001744C8 /* LocationTableViewController.swift in Sources */, + 5367B2641E60A1A9001744C8 /* MapViewController.swift in Sources */, + 5367B2621E60A140001744C8 /* LocationDataSource.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 534452F51E61B9E600649AF9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5367B2471E608B79001744C8 /* Container */; + targetProxy = 534452F41E61B9E600649AF9 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 5367B24F1E608B79001744C8 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5367B2501E608B79001744C8 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5367B2541E608B79001744C8 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5367B2551E608B79001744C8 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 534452F71E61B9E600649AF9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ContainerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ContainerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Container.app/Container"; + }; + name = Debug; + }; + 534452F81E61B9E600649AF9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ContainerTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ContainerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Container.app/Container"; + }; + name = Release; + }; + 5367B2581E608B79001744C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5367B2591E608B79001744C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5367B25B1E608B79001744C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Container/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Container; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5367B25C1E608B79001744C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Container/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Container; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 534452F61E61B9E600649AF9 /* Build configuration list for PBXNativeTarget "ContainerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 534452F71E61B9E600649AF9 /* Debug */, + 534452F81E61B9E600649AF9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5367B2431E608B79001744C8 /* Build configuration list for PBXProject "Container" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5367B2581E608B79001744C8 /* Debug */, + 5367B2591E608B79001744C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5367B25A1E608B79001744C8 /* Build configuration list for PBXNativeTarget "Container" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5367B25B1E608B79001744C8 /* Debug */, + 5367B25C1E608B79001744C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5367B2401E608B79001744C8 /* Project object */; +} diff --git a/Container/Container-code/Container/AppDelegate.swift b/Container/Container-code/Container/AppDelegate.swift new file mode 100644 index 0000000..1e60a63 --- /dev/null +++ b/Container/Container-code/Container/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/Container/Container-code/Container/Assets.xcassets/AppIcon.appiconset/Contents.json b/Container/Container-code/Container/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/Container/Container-code/Container/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Container/Container-code/Container/Base.lproj/LaunchScreen.storyboard b/Container/Container-code/Container/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/Container/Container-code/Container/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Container/Container-code/Container/Base.lproj/Main.storyboard b/Container/Container-code/Container/Base.lproj/Main.storyboard new file mode 100644 index 0000000..7a01916 --- /dev/null +++ b/Container/Container-code/Container/Base.lproj/Main.storyboard @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Container/Container-code/Container/ConfigurableCell.swift b/Container/Container-code/Container/ConfigurableCell.swift new file mode 100644 index 0000000..eced6d5 --- /dev/null +++ b/Container/Container-code/Container/ConfigurableCell.swift @@ -0,0 +1,38 @@ +// +// ConfigurableCell.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol ConfigurableCell { + associatedtype Object + func configure(object: Object) +} diff --git a/Container/Container-code/Container/Info.plist b/Container/Container-code/Container/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/Container/Container-code/Container/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Container/Container-code/Container/Location.swift b/Container/Container-code/Container/Location.swift new file mode 100644 index 0000000..d65003c --- /dev/null +++ b/Container/Container-code/Container/Location.swift @@ -0,0 +1,96 @@ +// +// Location.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 CoreLocation + +/// A structure representing the location of a point on +/// the map. + +struct Location { + + /// The name of the location. + + let name: String + + /// The latitude of the location in degrees. + + let latitude: CLLocationDegrees + + /// The longitude of the location in degrees. + + let longitude: CLLocationDegrees + + /// A read-only `CLLocationCoordinate2D` value for the + /// geographic coordinate of the location. + + var coordinate: CLLocationCoordinate2D { + return CLLocationCoordinate2DMake(latitude, longitude) + } +} + +extension Location { + + /// A failable initializer that builds a `Location` from + /// a dictionary of String keys and values. The dictionary + /// must contain at least "name", "latitude" and "longitude" + /// items. + /// + /// The values must all be `String` and the `latitude` + /// and `longitude` must convert to a `CLLocationDegrees` + /// value (Double) and specify a valid coordinate. A valid + /// latitude is from -90 to +90 and a valid longitude is + /// from -180 to +180. + /// + /// - Parameter dictionary: A dictionary containing the + /// details to initialize the location. + /// + /// - Returns: A `Location` structure or `nil` if the + /// dictionary was invalid, + + init?(dictionary: Dictionary) { + guard let name = dictionary["name"], + let latitudeItem = dictionary["latitude"], + let latitude = CLLocationDegrees(latitudeItem), + let longitudeItem = dictionary["longitude"], + let longitude = CLLocationDegrees(longitudeItem) else { + return nil + } + + self.name = name + self.latitude = latitude + self.longitude = longitude + if !CLLocationCoordinate2DIsValid(coordinate) { + return nil + } + } +} diff --git a/Container/Container-code/Container/LocationCell.swift b/Container/Container-code/Container/LocationCell.swift new file mode 100644 index 0000000..ed28ed3 --- /dev/null +++ b/Container/Container-code/Container/LocationCell.swift @@ -0,0 +1,46 @@ +// +// LocationCell.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LocationCell: UITableViewCell, ReusableIdentifier { + @IBOutlet private var name: UILabel! + @IBOutlet private var coordinates: UILabel! +} + +extension LocationCell: ConfigurableCell { + func configure(object: Location) { + name.text = object.name + coordinates.text = String("\(object.latitude) \(object.longitude)") + } +} diff --git a/Container/Container-code/Container/LocationDataSource.swift b/Container/Container-code/Container/LocationDataSource.swift new file mode 100644 index 0000000..96ac6e3 --- /dev/null +++ b/Container/Container-code/Container/LocationDataSource.swift @@ -0,0 +1,88 @@ +// +// LocationDataSource.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LocationDataSource: NSObject { + + private let tableView: UITableView + private var locations = [Location]() + + init(tableView: UITableView, from path: String) { + self.tableView = tableView + super.init() + readFromPlist(name: path) + tableView.dataSource = self + tableView.reloadData() + } + + func locationAtIndexPath(_ indexPath: IndexPath) -> Location? { + return indexPath.row < locations.count ? locations[indexPath.row] : nil + } + + private func readFromPlist(name: String) { + guard let items = NSArray(contentsOfFile: name) as? [Dictionary] else { + return + } + for item in items { + if let location = Location(dictionary: item) { + locations.append(location) + } + } + } +} + +extension LocationDataSource: UITableViewDataSource { + + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return locations.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: LocationCell.reuseIdentifier, for: indexPath) + configure(cell: cell, indexPath: indexPath) + return cell + } + + private func configure(cell: UITableViewCell, indexPath: IndexPath) { + if let cell = cell as? LocationCell { + let object = locations[indexPath.row] + cell.configure(object: object) + } + } +} + diff --git a/Container/Container-code/Container/LocationTableViewController.swift b/Container/Container-code/Container/LocationTableViewController.swift new file mode 100644 index 0000000..18f743c --- /dev/null +++ b/Container/Container-code/Container/LocationTableViewController.swift @@ -0,0 +1,62 @@ +// +// LocationTableViewController.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol LocationProviderDelegate: AnyObject { + func didSelectLocation(_ location: Location) +} + +final class LocationTableViewController: UITableViewController { + weak var delegate: LocationProviderDelegate? + + private var locationDataSource: LocationDataSource? + + override func viewDidLoad() { + super.viewDidLoad() + tableView.rowHeight = UITableView.automaticDimension + tableView.estimatedRowHeight = UITableView.automaticDimension + tableView.delegate = self + + if let plistPath = Bundle.main.path(forResource: "locations", ofType: "plist") { + locationDataSource = LocationDataSource(tableView: tableView, from: plistPath) + tableView.dataSource = locationDataSource + } + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if let location = locationDataSource?.locationAtIndexPath(indexPath) { + delegate?.didSelectLocation(location) + } + } +} diff --git a/Container/Container-code/Container/MapViewController.swift b/Container/Container-code/Container/MapViewController.swift new file mode 100644 index 0000000..692137e --- /dev/null +++ b/Container/Container-code/Container/MapViewController.swift @@ -0,0 +1,90 @@ +// +// MapViewController.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 MapKit +import UIKit + +final class MapViewController: UIViewController { + @IBOutlet private var mapView: MKMapView! + + /// The zoom level to use when setting the span + /// of the map region to show. Default is 10 degrees. + + var zoom: CLLocationDegrees = 10.0 + + /// The coordinate to center the map on. Setting a new + /// coordinate centers the map on a region spanned by + /// the `zoom` level and drops a pin annotation at the + /// coordinate. + + var coordinate: CLLocationCoordinate2D? { + didSet { + if let coordinate = coordinate { + centerMap(coordinate) + annotate(coordinate) + } + } + } + + private func centerMap(_ coordinate: CLLocationCoordinate2D) { + let span = MKCoordinateSpan(latitudeDelta: zoom, longitudeDelta: zoom) + let region = MKCoordinateRegion(center: coordinate, span: span) + mapView.setRegion(region, animated: true) + } + + private func annotate(_ coordinate: CLLocationCoordinate2D) { + let annotation = MKPointAnnotation() + annotation.coordinate = coordinate + mapView.addAnnotation(annotation) + } +} + +extension MapViewController: MKMapViewDelegate { + private enum AnnotationView: String { + case pin = "Pin" + } + + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + guard let annotation = annotation as? MKPointAnnotation else { + return nil + } + + let identifier = AnnotationView.pin.rawValue + guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView else { + return MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) + } + + annotationView.annotation = annotation + return annotationView + } +} diff --git a/Container/Container-code/Container/MasterViewController.swift b/Container/Container-code/Container/MasterViewController.swift new file mode 100644 index 0000000..dde0d93 --- /dev/null +++ b/Container/Container-code/Container/MasterViewController.swift @@ -0,0 +1,104 @@ +// +// MasterViewController.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class MasterViewController: UIViewController { + private let topStackView = UIStackView() + + private lazy var locationTableViewController: LocationTableViewController = self.buildFromStoryboard("Main") + private lazy var mapViewController: MapViewController = self.buildFromStoryboard("Main") + + override func viewDidLoad() { + super.viewDidLoad() + setupStackView() + + addContentController(locationTableViewController, to: topStackView) + addContentController(mapViewController, to: topStackView) + locationTableViewController.delegate = self + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + topStackView.axis = axisForSize(view.bounds.size) + } + + private func addContentController(_ child: UIViewController, to stackView: UIStackView) { + addChild(child) + stackView.addArrangedSubview(child.view) + child.didMove(toParent: self) + } + + private func removeContentController(_ child: UIViewController, from stackView: UIStackView) { + child.willMove(toParent: nil) + stackView.removeArrangedSubview(child.view) + child.view.removeFromSuperview() + child.removeFromParent() + } + + private func setupStackView() { + topStackView.alignment = .fill + topStackView.distribution = .fillEqually + topStackView.spacing = 8.0 + + topStackView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(topStackView) + + let margins = view.layoutMarginsGuide + NSLayoutConstraint.activate([ + topStackView.leadingAnchor.constraint(equalTo: margins.leadingAnchor), + topStackView.trailingAnchor.constraint(equalTo: margins.trailingAnchor), + topStackView.topAnchor.constraint(equalTo: margins.topAnchor), + topStackView.bottomAnchor.constraint(equalTo: margins.bottomAnchor) + ]) + } + + private func axisForSize(_ size: CGSize) -> NSLayoutConstraint.Axis { + return size.width > size.height ? .horizontal : .vertical + } + + private func buildFromStoryboard(_ name: String) -> T { + let storyboard = UIStoryboard(name: name, bundle: nil) + let identifier = String(describing: T.self) + guard let viewController = storyboard.instantiateViewController(withIdentifier: identifier) as? T else { + fatalError("Missing \(identifier) in Storyboard") + } + return viewController + } +} + +extension MasterViewController: LocationProviderDelegate { + func didSelectLocation(_ location: Location) { + mapViewController.coordinate = location.coordinate + } +} diff --git a/Container/Container-code/Container/ReusableIdentifier.swift b/Container/Container-code/Container/ReusableIdentifier.swift new file mode 100644 index 0000000..893e7f4 --- /dev/null +++ b/Container/Container-code/Container/ReusableIdentifier.swift @@ -0,0 +1,43 @@ +// +// ReusableIdentifier.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016-2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol ReusableIdentifier: class { + static var reuseIdentifier: String { get } +} + +extension ReusableIdentifier { + static var reuseIdentifier: String { + return "\(self)" + } +} diff --git a/Container/Container-code/Container/locations.plist b/Container/Container-code/Container/locations.plist new file mode 100644 index 0000000..1d4ad3c --- /dev/null +++ b/Container/Container-code/Container/locations.plist @@ -0,0 +1,247 @@ +( +{name="Afghanistan";latitude="33.93911";longitude="67.709953";}, +{name="Albania";latitude="41.153332";longitude="20.168331";}, +{name="Algeria";latitude="28.033886";longitude="1.659626";}, +{name="American Samoa";latitude="-14.270972";longitude="-170.132217";}, +{name="Andorra";latitude="42.546245";longitude="1.601554";}, +{name="Angola";latitude="-11.202692";longitude="17.873887";}, +{name="Anguilla";latitude="18.220554";longitude="-63.068615";}, +{name="Antarctica";latitude="-75.250973";longitude="-0.071389";}, +{name="Antigua and Barbuda";latitude="17.060816";longitude="-61.796428";}, +{name="Argentina";latitude="-38.416097";longitude="-63.616672";}, +{name="Armenia";latitude="40.069099";longitude="45.038189";}, +{name="Aruba";latitude="12.52111";longitude="-69.968338";}, +{name="Australia";latitude="-25.274398";longitude="133.775136";}, +{name="Austria";latitude="47.516231";longitude="14.550072";}, +{name="Azerbaijan";latitude="40.143105";longitude="47.576927";}, +{name="Bahamas";latitude="25.03428";longitude="-77.39628";}, +{name="Bahrain";latitude="25.930414";longitude="50.637772";}, +{name="Bangladesh";latitude="23.684994";longitude="90.356331";}, +{name="Barbados";latitude="13.193887";longitude="-59.543198";}, +{name="Belarus";latitude="53.709807";longitude="27.953389";}, +{name="Belgium";latitude="50.503887";longitude="4.469936";}, +{name="Belize";latitude="17.189877";longitude="-88.49765";}, +{name="Benin";latitude="9.30769";longitude="2.315834";}, +{name="Bermuda";latitude="32.321384";longitude="-64.75737";}, +{name="Bhutan";latitude="27.514162";longitude="90.433601";}, +{name="Bolivia";latitude="-16.290154";longitude="-63.588653";}, +{name="Bosnia and Herzegovina";latitude="43.915886";longitude="17.679076";}, +{name="Botswana";latitude="-22.328474";longitude="24.684866";}, +{name="Bouvet Island";latitude="-54.423199";longitude="3.413194";}, +{name="Brazil";latitude="-14.235004";longitude="-51.92528";}, +{name="British Indian Ocean Territory";latitude="-6.343194";longitude="71.876519";}, +{name="British Virgin Islands";latitude="18.420695";longitude="-64.639968";}, +{name="Brunei";latitude="4.535277";longitude="114.727669";}, +{name="Bulgaria";latitude="42.733883";longitude="25.48583";}, +{name="Burkina Faso";latitude="12.238333";longitude="-1.561593";}, +{name="Burundi";latitude="-3.373056";longitude="29.918886";}, +{name="Cambodia";latitude="12.565679";longitude="104.990963";}, +{name="Cameroon";latitude="7.369722";longitude="12.354722";}, +{name="Canada";latitude="56.130366";longitude="-106.346771";}, +{name="Cape Verde";latitude="16.002082";longitude="-24.013197";}, +{name="Cayman Islands";latitude="19.513469";longitude="-80.566956";}, +{name="Central African Republic";latitude="6.611111";longitude="20.939444";}, +{name="Chad";latitude="15.454166";longitude="18.732207";}, +{name="Chile";latitude="-35.675147";longitude="-71.542969";}, +{name="China";latitude="35.86166";longitude="104.195397";}, +{name="Christmas Island";latitude="-10.447525";longitude="105.690449";}, +{name="Cocos [Keeling] Islands";latitude="-12.164165";longitude="96.870956";}, +{name="Colombia";latitude="4.570868";longitude="-74.297333";}, +{name="Comoros";latitude="-11.875001";longitude="43.872219";}, +{name="Congo [DRC]";latitude="-4.038333";longitude="21.758664";}, +{name="Congo [Republic]";latitude="-0.228021";longitude="15.827659";}, +{name="Cook Islands";latitude="-21.236736";longitude="-159.777671";}, +{name="Costa Rica";latitude="9.748917";longitude="-83.753428";}, +{name="Croatia";latitude="45.1";longitude="15.2";}, +{name="Cuba";latitude="21.521757";longitude="-77.781167";}, +{name="Cyprus";latitude="35.126413";longitude="33.429859";}, +{name="Czech Republic";latitude="49.817492";longitude="15.472962";}, +{name="Côte d'Ivoire";latitude="7.539989";longitude="-5.54708";}, +{name="Denmark";latitude="56.26392";longitude="9.501785";}, +{name="Djibouti";latitude="11.825138";longitude="42.590275";}, +{name="Dominica";latitude="15.414999";longitude="-61.370976";}, +{name="Dominican Republic";latitude="18.735693";longitude="-70.162651";}, +{name="Ecuador";latitude="-1.831239";longitude="-78.183406";}, +{name="Egypt";latitude="26.820553";longitude="30.802498";}, +{name="El Salvador";latitude="13.794185";longitude="-88.89653";}, +{name="Equatorial Guinea";latitude="1.650801";longitude="10.267895";}, +{name="Eritrea";latitude="15.179384";longitude="39.782334";}, +{name="Estonia";latitude="58.595272";longitude="25.013607";}, +{name="Ethiopia";latitude="9.145";longitude="40.489673";}, +{name="Falkland Islands [Islas Malvinas]";latitude="-51.796253";longitude="-59.523613";}, +{name="Faroe Islands";latitude="61.892635";longitude="-6.911806";}, +{name="Fiji";latitude="-16.578193";longitude="179.414413";}, +{name="Finland";latitude="61.92411";longitude="25.748151";}, +{name="France";latitude="46.227638";longitude="2.213749";}, +{name="French Guiana";latitude="3.933889";longitude="-53.125782";}, +{name="French Polynesia";latitude="-17.679742";longitude="-149.406843";}, +{name="French Southern Territories";latitude="-49.280366";longitude="69.348557";}, +{name="Gabon";latitude="-0.803689";longitude="11.609444";}, +{name="Gambia";latitude="13.443182";longitude="-15.310139";}, +{name="Gaza Strip";latitude="31.354676";longitude="34.308825";}, +{name="Georgia";latitude="42.315407";longitude="43.356892";}, +{name="Germany";latitude="51.165691";longitude="10.451526";}, +{name="Ghana";latitude="7.946527";longitude="-1.023194";}, +{name="Gibraltar";latitude="36.137741";longitude="-5.345374";}, +{name="Greece";latitude="39.074208";longitude="21.824312";}, +{name="Greenland";latitude="71.706936";longitude="-42.604303";}, +{name="Grenada";latitude="12.262776";longitude="-61.604171";}, +{name="Guadeloupe";latitude="16.995971";longitude="-62.067641";}, +{name="Guam";latitude="13.444304";longitude="144.793731";}, +{name="Guatemala";latitude="15.783471";longitude="-90.230759";}, +{name="Guernsey";latitude="49.465691";longitude="-2.585278";}, +{name="Guinea";latitude="9.945587";longitude="-9.696645";}, +{name="Guinea-Bissau";latitude="11.803749";longitude="-15.180413";}, +{name="Guyana";latitude="4.860416";longitude="-58.93018";}, +{name="Haiti";latitude="18.971187";longitude="-72.285215";}, +{name="Heard Island and McDonald Islands";latitude="-53.08181";longitude="73.504158";}, +{name="Honduras";latitude="15.199999";longitude="-86.241905";}, +{name="Hong Kong";latitude="22.396428";longitude="114.109497";}, +{name="Hungary";latitude="47.162494";longitude="19.503304";}, +{name="Iceland";latitude="64.963051";longitude="-19.020835";}, +{name="India";latitude="20.593684";longitude="78.96288";}, +{name="Indonesia";latitude="-0.789275";longitude="113.921327";}, +{name="Iran";latitude="32.427908";longitude="53.688046";}, +{name="Iraq";latitude="33.223191";longitude="43.679291";}, +{name="Ireland";latitude="53.41291";longitude="-8.24389";}, +{name="Isle of Man";latitude="54.236107";longitude="-4.548056";}, +{name="Israel";latitude="31.046051";longitude="34.851612";}, +{name="Italy";latitude="41.87194";longitude="12.56738";}, +{name="Jamaica";latitude="18.109581";longitude="-77.297508";}, +{name="Japan";latitude="36.204824";longitude="138.252924";}, +{name="Jersey";latitude="49.214439";longitude="-2.13125";}, +{name="Jordan";latitude="30.585164";longitude="36.238414";}, +{name="Kazakhstan";latitude="48.019573";longitude="66.923684";}, +{name="Kenya";latitude="-0.023559";longitude="37.906193";}, +{name="Kiribati";latitude="-3.370417";longitude="-168.734039";}, +{name="Kosovo";latitude="42.602636";longitude="20.902977";}, +{name="Kuwait";latitude="29.31166";longitude="47.481766";}, +{name="Kyrgyzstan";latitude="41.20438";longitude="74.766098";}, +{name="Laos";latitude="19.85627";longitude="102.495496";}, +{name="Latvia";latitude="56.879635";longitude="24.603189";}, +{name="Lebanon";latitude="33.854721";longitude="35.862285";}, +{name="Lesotho";latitude="-29.609988";longitude="28.233608";}, +{name="Liberia";latitude="6.428055";longitude="-9.429499";}, +{name="Libya";latitude="26.3351";longitude="17.228331";}, +{name="Liechtenstein";latitude="47.166";longitude="9.555373";}, +{name="Lithuania";latitude="55.169438";longitude="23.881275";}, +{name="Luxembourg";latitude="49.815273";longitude="6.129583";}, +{name="Macau";latitude="22.198745";longitude="113.543873";}, +{name="Macedonia [FYROM]";latitude="41.608635";longitude="21.745275";}, +{name="Madagascar";latitude="-18.766947";longitude="46.869107";}, +{name="Malawi";latitude="-13.254308";longitude="34.301525";}, +{name="Malaysia";latitude="4.210484";longitude="101.975766";}, +{name="Maldives";latitude="3.202778";longitude="73.22068";}, +{name="Mali";latitude="17.570692";longitude="-3.996166";}, +{name="Malta";latitude="35.937496";longitude="14.375416";}, +{name="Marshall Islands";latitude="7.131474";longitude="171.184478";}, +{name="Martinique";latitude="14.641528";longitude="-61.024174";}, +{name="Mauritania";latitude="21.00789";longitude="-10.940835";}, +{name="Mauritius";latitude="-20.348404";longitude="57.552152";}, +{name="Mayotte";latitude="-12.8275";longitude="45.166244";}, +{name="Mexico";latitude="23.634501";longitude="-102.552784";}, +{name="Micronesia";latitude="7.425554";longitude="150.550812";}, +{name="Moldova";latitude="47.411631";longitude="28.369885";}, +{name="Monaco";latitude="43.750298";longitude="7.412841";}, +{name="Mongolia";latitude="46.862496";longitude="103.846656";}, +{name="Montenegro";latitude="42.708678";longitude="19.37439";}, +{name="Montserrat";latitude="16.742498";longitude="-62.187366";}, +{name="Morocco";latitude="31.791702";longitude="-7.09262";}, +{name="Mozambique";latitude="-18.665695";longitude="35.529562";}, +{name="Myanmar [Burma]";latitude="21.913965";longitude="95.956223";}, +{name="Namibia";latitude="-22.95764";longitude="18.49041";}, +{name="Nauru";latitude="-0.522778";longitude="166.931503";}, +{name="Nepal";latitude="28.394857";longitude="84.124008";}, +{name="Netherlands Antilles";latitude="12.226079";longitude="-69.060087";}, +{name="Netherlands";latitude="52.132633";longitude="5.291266";}, +{name="New Caledonia";latitude="-20.904305";longitude="165.618042";}, +{name="New Zealand";latitude="-40.900557";longitude="174.885971";}, +{name="Nicaragua";latitude="12.865416";longitude="-85.207229";}, +{name="Niger";latitude="17.607789";longitude="8.081666";}, +{name="Nigeria";latitude="9.081999";longitude="8.675277";}, +{name="Niue";latitude="-19.054445";longitude="-169.867233";}, +{name="Norfolk Island";latitude="-29.040835";longitude="167.954712";}, +{name="North Korea";latitude="40.339852";longitude="127.510093";}, +{name="Northern Mariana Islands";latitude="17.33083";longitude="145.38469";}, +{name="Norway";latitude="60.472024";longitude="8.468946";}, +{name="Oman";latitude="21.512583";longitude="55.923255";}, +{name="Pakistan";latitude="30.375321";longitude="69.345116";}, +{name="Palau";latitude="7.51498";longitude="134.58252";}, +{name="Palestinian Territories";latitude="31.952162";longitude="35.233154";}, +{name="Panama";latitude="8.537981";longitude="-80.782127";}, +{name="Papua New Guinea";latitude="-6.314993";longitude="143.95555";}, +{name="Paraguay";latitude="-23.442503";longitude="-58.443832";}, +{name="Peru";latitude="-9.189967";longitude="-75.015152";}, +{name="Philippines";latitude="12.879721";longitude="121.774017";}, +{name="Pitcairn Islands";latitude="-24.703615";longitude="-127.439308";}, +{name="Poland";latitude="51.919438";longitude="19.145136";}, +{name="Portugal";latitude="39.399872";longitude="-8.224454";}, +{name="Puerto Rico";latitude="18.220833";longitude="-66.590149";}, +{name="Qatar";latitude="25.354826";longitude="51.183884";}, +{name="Romania";latitude="45.943161";longitude="24.96676";}, +{name="Russia";latitude="61.52401";longitude="105.318756";}, +{name="Rwanda";latitude="-1.940278";longitude="29.873888";}, +{name="Réunion";latitude="-21.115141";longitude="55.536384";}, +{name="Saint Helena";latitude="-24.143474";longitude="-10.030696";}, +{name="Saint Kitts and Nevis";latitude="17.357822";longitude="-62.782998";}, +{name="Saint Lucia";latitude="13.909444";longitude="-60.978893";}, +{name="Saint Pierre and Miquelon";latitude="46.941936";longitude="-56.27111";}, +{name="Saint Vincent and the Grenadines";latitude="12.984305";longitude="-61.287228";}, +{name="Samoa";latitude="-13.759029";longitude="-172.104629";}, +{name="San Marino";latitude="43.94236";longitude="12.457777";}, +{name="Saudi Arabia";latitude="23.885942";longitude="45.079162";}, +{name="Senegal";latitude="14.497401";longitude="-14.452362";}, +{name="Serbia";latitude="44.016521";longitude="21.005859";}, +{name="Seychelles";latitude="-4.679574";longitude="55.491977";}, +{name="Sierra Leone";latitude="8.460555";longitude="-11.779889";}, +{name="Singapore";latitude="1.352083";longitude="103.819836";}, +{name="Slovakia";latitude="48.669026";longitude="19.699024";}, +{name="Slovenia";latitude="46.151241";longitude="14.995463";}, +{name="Solomon Islands";latitude="-9.64571";longitude="160.156194";}, +{name="Somalia";latitude="5.152149";longitude="46.199616";}, +{name="South Africa";latitude="-30.559482";longitude="22.937506";}, +{name="South Georgia and the South Sandwich Islands";latitude="-54.429579";longitude="-36.587909";}, +{name="South Korea";latitude="35.907757";longitude="127.766922";}, +{name="Spain";latitude="40.463667";longitude="-3.74922";}, +{name="Sri Lanka";latitude="7.873054";longitude="80.771797";}, +{name="Sudan";latitude="12.862807";longitude="30.217636";}, +{name="Suriname";latitude="3.919305";longitude="-56.027783";}, +{name="Svalbard and Jan Mayen";latitude="77.553604";longitude="23.670272";}, +{name="Swaziland";latitude="-26.522503";longitude="31.465866";}, +{name="Sweden";latitude="60.128161";longitude="18.643501";}, +{name="Switzerland";latitude="46.818188";longitude="8.227512";}, +{name="Syria";latitude="34.802075";longitude="38.996815";}, +{name="São Tomé and Príncipe";latitude="0.18636";longitude="6.613081";}, +{name="Taiwan";latitude="23.69781";longitude="120.960515";}, +{name="Tajikistan";latitude="38.861034";longitude="71.276093";}, +{name="Tanzania";latitude="-6.369028";longitude="34.888822";}, +{name="Thailand";latitude="15.870032";longitude="100.992541";}, +{name="Timor-Leste";latitude="-8.874217";longitude="125.727539";}, +{name="Togo";latitude="8.619543";longitude="0.824782";}, +{name="Tokelau";latitude="-8.967363";longitude="-171.855881";}, +{name="Tonga";latitude="-21.178986";longitude="-175.198242";}, +{name="Trinidad and Tobago";latitude="10.691803";longitude="-61.222503";}, +{name="Tunisia";latitude="33.886917";longitude="9.537499";}, +{name="Turkey";latitude="38.963745";longitude="35.243322";}, +{name="Turkmenistan";latitude="38.969719";longitude="59.556278";}, +{name="Turks and Caicos Islands";latitude="21.694025";longitude="-71.797928";}, +{name="Tuvalu";latitude="-7.109535";longitude="177.64933";}, +{name="U.S. Minor Outlying Islands";latitude="";longitude="";}, +{name="U.S. Virgin Islands";latitude="18.335765";longitude="-64.896335";}, +{name="Uganda";latitude="1.373333";longitude="32.290275";}, +{name="Ukraine";latitude="48.379433";longitude="31.16558";}, +{name="United Arab Emirates";latitude="23.424076";longitude="53.847818";}, +{name="United Kingdom";latitude="55.378051";longitude="-3.435973";}, +{name="United States";latitude="37.09024";longitude="-95.712891";}, +{name="Uruguay";latitude="-32.522779";longitude="-55.765835";}, +{name="Uzbekistan";latitude="41.377491";longitude="64.585262";}, +{name="Vanuatu";latitude="-15.376706";longitude="166.959158";}, +{name="Vatican City";latitude="41.902916";longitude="12.453389";}, +{name="Venezuela";latitude="6.42375";longitude="-66.58973";}, +{name="Vietnam";latitude="14.058324";longitude="108.277199";}, +{name="Wallis and Futuna";latitude="-13.768752";longitude="-177.156097";}, +{name="Western Sahara";latitude="24.215527";longitude="-12.885834";}, +{name="Yemen";latitude="15.552727";longitude="48.516388";}, +{name="Zambia";latitude="-13.133897";longitude="27.849332";}, +{name="Zimbabwe";latitude="-19.015438";longitude="29.154857";} +) diff --git a/TwitterSearch/TwitterSearchUnitTests/Info.plist b/Container/Container-code/ContainerTests/Info.plist similarity index 92% rename from TwitterSearch/TwitterSearchUnitTests/Info.plist rename to Container/Container-code/ContainerTests/Info.plist index ba72822..6c6c23c 100644 --- a/TwitterSearch/TwitterSearchUnitTests/Info.plist +++ b/Container/Container-code/ContainerTests/Info.plist @@ -16,8 +16,6 @@ BNDL CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion 1 diff --git a/Container/Container-code/ContainerTests/LocationTests.swift b/Container/Container-code/ContainerTests/LocationTests.swift new file mode 100644 index 0000000..93179fa --- /dev/null +++ b/Container/Container-code/ContainerTests/LocationTests.swift @@ -0,0 +1,105 @@ +// +// LocationTests.swift +// Container +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 XCTest +import CoreLocation + +@testable import Container + +class LocationTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testInitFromDictionary() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "-25", + "longitude" : "135"]) + XCTAssertNotNil(australia) + XCTAssert(australia?.name == "Australia") + XCTAssert(australia?.latitude == -25.0) + XCTAssert(australia?.longitude == 135.0) + } + + func testMissingName() { + let australia = Location(dictionary: ["latitude" : "-25", + "longitude" : "135"]) + XCTAssertNil(australia) + } + + func testMissingLatitude() { + let australia = Location(dictionary: ["name" : "Australis", + "longitude" : "135"]) + XCTAssertNil(australia) + } + + func testMissingLongitude() { + let australia = Location(dictionary: ["name" : "Australis", + "latitude" : "-25"]) + XCTAssertNil(australia) + } + + func testExtraKeysIgnored() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "-25", + "longitude" : "135", + "capital" : "Canberra"]) + XCTAssertNotNil(australia) + } + + func testInvalidLatitude() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "hello", + "longitude" : "135"]) + XCTAssertNil(australia) + } + + func testInvalidLongitude() { + let australia = Location(dictionary: ["name" : "Australia", + "latitude" : "-25", + "longitude" : "12a"]) + XCTAssertNil(australia) + } + + func testInvalidCoordinare() { + let nowhere = Location(dictionary: ["name" : "OffTheGrid", + "latitude" : "-100", + "longitude" : "200"]) + XCTAssertNil(nowhere) + } +} diff --git a/Container/Container-code/README.md b/Container/Container-code/README.md new file mode 100644 index 0000000..ce4638f --- /dev/null +++ b/Container/Container-code/README.md @@ -0,0 +1,6 @@ +### Attribution + +The country location data used in this example is based on work created and [shared by Google](https://developers.google.com/readme/policies/) and used according to terms described in [Creative Commons 3.0 Attribution License](http://creativecommons.org/licenses/by/3.0/). + +See the [original source page](https://developers.google.com/public-data/docs/canonical/countries_csv) for details. + diff --git a/Container/README.md b/Container/README.md new file mode 100644 index 0000000..f4d5777 --- /dev/null +++ b/Container/README.md @@ -0,0 +1,14 @@ +### Container + +Example of using view containment to avoid massive view controllers. This folder contains two Xcode projects: + ++ Container-SB: Implements everything with a Storyboard. ++ Container-code: Manages the child views in code. + +#### Further Information + ++ [Container View Controllers](https://useyourloaf.com/blog/container-view-controllers/) + +#### Version History + ++ Version 1.0 26 Feb 2017 Initial release diff --git a/DarkTheme/DarkTheme.xcodeproj/project.pbxproj b/DarkTheme/DarkTheme.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6940263 --- /dev/null +++ b/DarkTheme/DarkTheme.xcodeproj/project.pbxproj @@ -0,0 +1,357 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 535DFF62241589FD00DF6476 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535DFF61241589FD00DF6476 /* AppDelegate.swift */; }; + 535DFF64241589FD00DF6476 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535DFF63241589FD00DF6476 /* SceneDelegate.swift */; }; + 535DFF6B241589FD00DF6476 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 535DFF69241589FD00DF6476 /* Main.storyboard */; }; + 535DFF6D24158A0100DF6476 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 535DFF6C24158A0100DF6476 /* Assets.xcassets */; }; + 535DFF7024158A0100DF6476 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 535DFF6E24158A0100DF6476 /* LaunchScreen.storyboard */; }; + 535DFF7824158B3E00DF6476 /* ThemeTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535DFF7724158B3E00DF6476 /* ThemeTableViewController.swift */; }; + 535DFF7A24158B8E00DF6476 /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535DFF7924158B8E00DF6476 /* TextViewController.swift */; }; + 535DFF7C241597CA00DF6476 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535DFF7B241597CA00DF6476 /* Theme.swift */; }; + 535DFF7E2415996900DF6476 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535DFF7D2415996900DF6476 /* Settings.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 535DFF5E241589FD00DF6476 /* DarkTheme.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DarkTheme.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 535DFF61241589FD00DF6476 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 535DFF63241589FD00DF6476 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 535DFF6A241589FD00DF6476 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 535DFF6C24158A0100DF6476 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 535DFF6F24158A0100DF6476 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 535DFF7124158A0100DF6476 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 535DFF7724158B3E00DF6476 /* ThemeTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeTableViewController.swift; sourceTree = ""; }; + 535DFF7924158B8E00DF6476 /* TextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewController.swift; sourceTree = ""; }; + 535DFF7B241597CA00DF6476 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; + 535DFF7D2415996900DF6476 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; + 535DFF7F2416A58B00DF6476 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 535DFF5B241589FD00DF6476 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 535DFF55241589FD00DF6476 = { + isa = PBXGroup; + children = ( + 535DFF7F2416A58B00DF6476 /* README.md */, + 535DFF60241589FD00DF6476 /* DarkTheme */, + 535DFF5F241589FD00DF6476 /* Products */, + ); + sourceTree = ""; + }; + 535DFF5F241589FD00DF6476 /* Products */ = { + isa = PBXGroup; + children = ( + 535DFF5E241589FD00DF6476 /* DarkTheme.app */, + ); + name = Products; + sourceTree = ""; + }; + 535DFF60241589FD00DF6476 /* DarkTheme */ = { + isa = PBXGroup; + children = ( + 535DFF7724158B3E00DF6476 /* ThemeTableViewController.swift */, + 535DFF7B241597CA00DF6476 /* Theme.swift */, + 535DFF7D2415996900DF6476 /* Settings.swift */, + 535DFF7924158B8E00DF6476 /* TextViewController.swift */, + 535DFF61241589FD00DF6476 /* AppDelegate.swift */, + 535DFF63241589FD00DF6476 /* SceneDelegate.swift */, + 535DFF69241589FD00DF6476 /* Main.storyboard */, + 535DFF6C24158A0100DF6476 /* Assets.xcassets */, + 535DFF6E24158A0100DF6476 /* LaunchScreen.storyboard */, + 535DFF7124158A0100DF6476 /* Info.plist */, + ); + path = DarkTheme; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 535DFF5D241589FD00DF6476 /* DarkTheme */ = { + isa = PBXNativeTarget; + buildConfigurationList = 535DFF7424158A0100DF6476 /* Build configuration list for PBXNativeTarget "DarkTheme" */; + buildPhases = ( + 535DFF5A241589FD00DF6476 /* Sources */, + 535DFF5B241589FD00DF6476 /* Frameworks */, + 535DFF5C241589FD00DF6476 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DarkTheme; + productName = DarkTheme; + productReference = 535DFF5E241589FD00DF6476 /* DarkTheme.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 535DFF56241589FD00DF6476 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1140; + LastUpgradeCheck = 1140; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 535DFF5D241589FD00DF6476 = { + CreatedOnToolsVersion = 11.4; + }; + }; + }; + buildConfigurationList = 535DFF59241589FD00DF6476 /* Build configuration list for PBXProject "DarkTheme" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 535DFF55241589FD00DF6476; + productRefGroup = 535DFF5F241589FD00DF6476 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 535DFF5D241589FD00DF6476 /* DarkTheme */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 535DFF5C241589FD00DF6476 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 535DFF7024158A0100DF6476 /* LaunchScreen.storyboard in Resources */, + 535DFF6D24158A0100DF6476 /* Assets.xcassets in Resources */, + 535DFF6B241589FD00DF6476 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 535DFF5A241589FD00DF6476 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 535DFF7E2415996900DF6476 /* Settings.swift in Sources */, + 535DFF7824158B3E00DF6476 /* ThemeTableViewController.swift in Sources */, + 535DFF62241589FD00DF6476 /* AppDelegate.swift in Sources */, + 535DFF7C241597CA00DF6476 /* Theme.swift in Sources */, + 535DFF64241589FD00DF6476 /* SceneDelegate.swift in Sources */, + 535DFF7A24158B8E00DF6476 /* TextViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 535DFF69241589FD00DF6476 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 535DFF6A241589FD00DF6476 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 535DFF6E24158A0100DF6476 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 535DFF6F24158A0100DF6476 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 535DFF7224158A0100DF6476 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 535DFF7324158A0100DF6476 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 535DFF7524158A0100DF6476 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DarkTheme/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DarkTheme; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 535DFF7624158A0100DF6476 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DarkTheme/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DarkTheme; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 535DFF59241589FD00DF6476 /* Build configuration list for PBXProject "DarkTheme" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 535DFF7224158A0100DF6476 /* Debug */, + 535DFF7324158A0100DF6476 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 535DFF7424158A0100DF6476 /* Build configuration list for PBXNativeTarget "DarkTheme" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 535DFF7524158A0100DF6476 /* Debug */, + 535DFF7624158A0100DF6476 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 535DFF56241589FD00DF6476 /* Project object */; +} diff --git a/DarkTheme/DarkTheme/AppDelegate.swift b/DarkTheme/DarkTheme/AppDelegate.swift new file mode 100644 index 0000000..2d32c08 --- /dev/null +++ b/DarkTheme/DarkTheme/AppDelegate.swift @@ -0,0 +1,34 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { +} diff --git a/DarkTheme/DarkTheme/Assets.xcassets/AppIcon.appiconset/Contents.json b/DarkTheme/DarkTheme/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/DarkTheme/DarkTheme/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DarkTheme/DarkTheme/Assets.xcassets/Contents.json b/DarkTheme/DarkTheme/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/DarkTheme/DarkTheme/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/Contents.json b/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/defaultBackground.colorset/Contents.json b/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/defaultBackground.colorset/Contents.json new file mode 100644 index 0000000..de36eae --- /dev/null +++ b/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/defaultBackground.colorset/Contents.json @@ -0,0 +1,78 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF0", + "green" : "0xF0", + "red" : "0xF0" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x33", + "green" : "0x33", + "red" : "0x33" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + }, + { + "appearance" : "contrast", + "value" : "high" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/groupedBackground.colorset/Contents.json b/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/groupedBackground.colorset/Contents.json new file mode 100644 index 0000000..3d85e7f --- /dev/null +++ b/DarkTheme/DarkTheme/Assets.xcassets/Dynamic Colors/groupedBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF7", + "green" : "0xF2", + "red" : "0xF2" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x00", + "green" : "0x00", + "red" : "0x00" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DarkTheme/DarkTheme/Base.lproj/LaunchScreen.storyboard b/DarkTheme/DarkTheme/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/DarkTheme/DarkTheme/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DarkTheme/DarkTheme/Base.lproj/Main.storyboard b/DarkTheme/DarkTheme/Base.lproj/Main.storyboard new file mode 100644 index 0000000..e93a726 --- /dev/null +++ b/DarkTheme/DarkTheme/Base.lproj/Main.storyboard @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DarkTheme/DarkTheme/Info.plist b/DarkTheme/DarkTheme/Info.plist new file mode 100644 index 0000000..e7f6f58 --- /dev/null +++ b/DarkTheme/DarkTheme/Info.plist @@ -0,0 +1,74 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/DarkTheme/DarkTheme/SceneDelegate.swift b/DarkTheme/DarkTheme/SceneDelegate.swift new file mode 100644 index 0000000..f5dc8a3 --- /dev/null +++ b/DarkTheme/DarkTheme/SceneDelegate.swift @@ -0,0 +1,39 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + let defaults = UserDefaults.standard + window?.overrideUserInterfaceStyle = defaults.theme.userInterfaceStyle + } +} diff --git a/DarkTheme/DarkTheme/Settings.swift b/DarkTheme/DarkTheme/Settings.swift new file mode 100644 index 0000000..6c54941 --- /dev/null +++ b/DarkTheme/DarkTheme/Settings.swift @@ -0,0 +1,42 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +extension UserDefaults { + var theme: Theme { + get { + register(defaults: [#function: Theme.device.rawValue]) + return Theme(rawValue: integer(forKey: #function)) ?? .device + } + set { + set(newValue.rawValue, forKey: #function) + } + } +} diff --git a/DarkTheme/DarkTheme/TextViewController.swift b/DarkTheme/DarkTheme/TextViewController.swift new file mode 100644 index 0000000..d42d839 --- /dev/null +++ b/DarkTheme/DarkTheme/TextViewController.swift @@ -0,0 +1,48 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class TextViewController: UIViewController { + var text: String? { + didSet { + textView?.text = text + } + } + + @IBOutlet private var textView: UITextView? + + override func viewDidLoad() { + super.viewDidLoad() + text = """ + “Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They're not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can't do is ignore them. Because they change things. They push the human race forward. And while some may see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do.” + ― Rob Siltanen + """ + } +} diff --git a/DarkTheme/DarkTheme/Theme.swift b/DarkTheme/DarkTheme/Theme.swift new file mode 100644 index 0000000..0aaa910 --- /dev/null +++ b/DarkTheme/DarkTheme/Theme.swift @@ -0,0 +1,49 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +enum Theme: Int { + case device + case light + case dark +} + +extension Theme { + var userInterfaceStyle: UIUserInterfaceStyle { + switch self { + case .device: + return .unspecified + case .light: + return .light + case .dark: + return .dark + } + } +} diff --git a/DarkTheme/DarkTheme/ThemeTableViewController.swift b/DarkTheme/DarkTheme/ThemeTableViewController.swift new file mode 100644 index 0000000..438ad54 --- /dev/null +++ b/DarkTheme/DarkTheme/ThemeTableViewController.swift @@ -0,0 +1,67 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class ThemeTableViewController: UITableViewController { + var defaults = UserDefaults.standard + private var theme: Theme { + get { + return defaults.theme + } + set { + defaults.theme = newValue + configureStyle(for: newValue) + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + configureCell(for: theme, checked: true) + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.row != theme.rawValue { + configureCell(for: theme, checked: false) + theme = Theme(rawValue: indexPath.row) ?? .device + configureCell(for: theme, checked: true) + } + + tableView.deselectRow(at: indexPath, animated: true) + } + + private func configureCell(for theme: Theme, checked: Bool) { + let cell = tableView.cellForRow(at: IndexPath(row: theme.rawValue, section: 0)) + cell?.accessoryType = checked ? .checkmark : .none + } + + private func configureStyle(for theme: Theme) { + view.window?.overrideUserInterfaceStyle = theme.userInterfaceStyle + } +} diff --git a/DarkTheme/README.md b/DarkTheme/README.md new file mode 100644 index 0000000..180e52d --- /dev/null +++ b/DarkTheme/README.md @@ -0,0 +1,5 @@ +# Overriding Dark Mode + +An example of using `overrideUserInterfaceStyle` (iOS 13) to control the appearance of an App. See the following post for more details: + ++ [Overriding Dark Mode](https://useyourloaf.com/blog/overriding-dark-mode/) diff --git a/Designable/Designable.xcodeproj/project.pbxproj b/Designable/Designable.xcodeproj/project.pbxproj index 894c6f2..53b2c3e 100644 --- a/Designable/Designable.xcodeproj/project.pbxproj +++ b/Designable/Designable.xcodeproj/project.pbxproj @@ -40,7 +40,6 @@ 53182E3B1B2460D1002D441F /* LevelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LevelViewController.m; sourceTree = ""; }; 53182E6C1B24F75E002D441F /* LevelView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelView.h; sourceTree = ""; }; 53182E6D1B24F75E002D441F /* LevelView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LevelView.m; sourceTree = ""; }; - 5321CAA61B26506100CE5924 /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; 538021F31B20EC3900434436 /* Designable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Designable.app; sourceTree = BUILT_PRODUCTS_DIR; }; 538021F71B20EC3900434436 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 538021F81B20EC3900434436 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -80,7 +79,6 @@ 538021EA1B20EC3900434436 = { isa = PBXGroup; children = ( - 5321CAA61B26506100CE5924 /* README */, 538021F51B20EC3900434436 /* Designable */, 53C515E91B2786EE0062905B /* DesignableSwift */, 538021F41B20EC3900434436 /* Products */, @@ -189,20 +187,23 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0630; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 538021F21B20EC3900434436 = { CreatedOnToolsVersion = 6.3.2; + DevelopmentTeam = LCC2J94N44; }; 53C515E71B2786ED0062905B = { CreatedOnToolsVersion = 6.3.2; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1120; }; }; }; buildConfigurationList = 538021EE1B20EC3900434436 /* Build configuration list for PBXProject "Designable" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -306,23 +307,35 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -342,6 +355,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -350,17 +364,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -379,6 +404,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -388,8 +415,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = Designable/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -398,8 +427,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = Designable/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -408,14 +439,18 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); INFOPLIST_FILE = DesignableSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -423,9 +458,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = DesignableSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/Designable/Designable/Base.lproj/Main.storyboard b/Designable/Designable/Base.lproj/Main.storyboard index 80d939c..5fdf825 100644 --- a/Designable/Designable/Base.lproj/Main.storyboard +++ b/Designable/Designable/Base.lproj/Main.storyboard @@ -1,8 +1,13 @@ - - + + + + + - + + + @@ -14,30 +19,30 @@ - + - - + + - + - + diff --git a/Designable/Designable/Info.plist b/Designable/Designable/Info.plist index 8d07b46..084f30f 100644 --- a/Designable/Designable/Info.plist +++ b/Designable/Designable/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.2 CFBundleSignature ???? CFBundleVersion diff --git a/Designable/Designable/LevelView.h b/Designable/Designable/LevelView.h index 0f81b49..c547079 100644 --- a/Designable/Designable/LevelView.h +++ b/Designable/Designable/LevelView.h @@ -3,7 +3,7 @@ // Designable // // Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2015 Keith Harrison. All rights reserved. +// Copyright (c) 2015-2017 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: diff --git a/Designable/Designable/LevelView.m b/Designable/Designable/LevelView.m index a00237c..ee9f04d 100644 --- a/Designable/Designable/LevelView.m +++ b/Designable/Designable/LevelView.m @@ -3,7 +3,7 @@ // Designable // // Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2015 Keith Harrison. All rights reserved. +// Copyright (c) 2015-2017 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: diff --git a/Designable/DesignableSwift/Base.lproj/Main.storyboard b/Designable/DesignableSwift/Base.lproj/Main.storyboard index 1faad91..831fac8 100644 --- a/Designable/DesignableSwift/Base.lproj/Main.storyboard +++ b/Designable/DesignableSwift/Base.lproj/Main.storyboard @@ -1,8 +1,13 @@ - - + + + + + - + + + @@ -14,30 +19,30 @@ - + - - + + - + - + - + diff --git a/Designable/DesignableSwift/Info.plist b/Designable/DesignableSwift/Info.plist index 8d07b46..084f30f 100644 --- a/Designable/DesignableSwift/Info.plist +++ b/Designable/DesignableSwift/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.2 CFBundleSignature ???? CFBundleVersion diff --git a/Designable/DesignableSwift/LevelView.swift b/Designable/DesignableSwift/LevelView.swift index 0b58733..7897fb2 100644 --- a/Designable/DesignableSwift/LevelView.swift +++ b/Designable/DesignableSwift/LevelView.swift @@ -3,7 +3,7 @@ // Designable // // Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2015 Keith Harrison. All rights reserved. +// Copyright (c) 2015-2017 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -34,18 +34,17 @@ import UIKit /** -A custom level view displayed as a horizontal colored bar which -changes color as the level drops below a configurable theshold. -Set the value of the level as a CGFloat between 0.0 and 1.0. -Customise the colors of the bar, the threshold, border width -and border color as required. -*/ + A custom level view displayed as a horizontal colored bar which + changes color as the level drops below a configurable theshold. + Set the value of the level as a CGFloat between 0.0 and 1.0. + Customise the colors of the bar, the threshold, border width + and border color as required. + */ @IBDesignable class LevelView: UIView { - /** - The current level value in the range 0.0 - 1.0. Defaults to 1.0. - */ + The current level value in the range 0.0 - 1.0. Defaults to 1.0. + */ @IBInspectable var value: CGFloat = 1.0 { didSet { updateLayoutProperties() @@ -53,9 +52,9 @@ class LevelView: UIView { } /** - The threshold value in the range 0.0 - 1.0 at which the bar color - changes between emptyColor and fullColor. Default is 0.3. - */ + The threshold value in the range 0.0 - 1.0 at which the bar color + changes between emptyColor and fullColor. Default is 0.3. + */ @IBInspectable var threshold: CGFloat = 0.3 { didSet { updateLayoutProperties() @@ -63,8 +62,8 @@ class LevelView: UIView { } /** - The border width for the frame surrounding the bar. Default is 2.0. - */ + The border width for the frame surrounding the bar. Default is 2.0. + */ @IBInspectable var borderWidth: CGFloat = 2.0 { didSet { updateLayoutProperties() @@ -72,32 +71,32 @@ class LevelView: UIView { } /** - The color of the bar border. Default is black. - */ - @IBInspectable var borderColor = UIColor.blackColor() { + The color of the bar border. Default is black. + */ + @IBInspectable var borderColor: UIColor = .black { didSet { updateLayoutProperties() } } /** - The color of the bar when value >= threshold. Default is green. - */ - @IBInspectable var fullColor = UIColor.greenColor() { + The color of the bar when value >= threshold. Default is green. + */ + @IBInspectable var fullColor: UIColor = .green { didSet { updateLayoutProperties() } } - + /** - The color of the bar when value < threshold. Default is red. - */ - @IBInspectable var emtpyColor = UIColor.redColor() { + The color of the bar when value < threshold. Default is red. + */ + @IBInspectable var emtpyColor: UIColor = .red { didSet { updateLayoutProperties() } } - + private let barLayer = CAShapeLayer() func setup() { @@ -110,7 +109,7 @@ class LevelView: UIView { setup() } - required init(coder aDecoder: NSCoder) { + required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } @@ -121,14 +120,13 @@ class LevelView: UIView { } func updateLayoutProperties() { - let barRect = CGRectMake(bounds.origin.x, bounds.origin.y, bounds.size.width * value, bounds.size.height) + let barRect = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.size.width * value, height: bounds.size.height) let path = UIBezierPath(rect: barRect) - barLayer.path = path.CGPath - barLayer.fillColor = value >= threshold ? fullColor.CGColor : emtpyColor.CGColor + barLayer.path = path.cgPath + barLayer.fillColor = value >= threshold ? fullColor.cgColor : emtpyColor.cgColor layer.borderWidth = borderWidth - layer.borderColor = borderColor.CGColor + layer.borderColor = borderColor.cgColor layer.cornerRadius = 5.0 layer.masksToBounds = true } - } diff --git a/Designable/DesignableSwift/LevelViewController.swift b/Designable/DesignableSwift/LevelViewController.swift index 78b1793..1c17279 100644 --- a/Designable/DesignableSwift/LevelViewController.swift +++ b/Designable/DesignableSwift/LevelViewController.swift @@ -33,17 +33,16 @@ import UIKit -class LevelViewController: UIViewController { +final class LevelViewController: UIViewController { + @IBOutlet private var levelView: LevelView! + @IBOutlet private var stepper: UIStepper! - @IBOutlet weak var levelView: LevelView! - @IBOutlet weak var stepper: UIStepper! - override func viewDidLoad() { super.viewDidLoad() stepper.value = Double(levelView.value) } - - @IBAction func valueChanged(sender: UIStepper) { + + @IBAction func valueChanged(_ sender: UIStepper) { levelView.value = CGFloat(sender.value) } } diff --git a/Designable/README b/Designable/README deleted file mode 100644 index 5a17a58..0000000 --- a/Designable/README +++ /dev/null @@ -1,11 +0,0 @@ -======================================================================= -Designable - live custom views in Interface Builder - -Version 1.1 10 June 2015 Added Swift version -Version 1.0 07 June 2015 Initial version. -======================================================================= - -Example of how to use IB_DESIGNABLE and IBInspectable to make custom -views live in Interface Builder. See following post for more details - -http://useyourloaf.com/blog/2015/06/08/ib-designable-custom-views-in-interface-builder.html diff --git a/Designable/README.md b/Designable/README.md new file mode 100644 index 0000000..5baabe5 --- /dev/null +++ b/Designable/README.md @@ -0,0 +1,15 @@ +# Designable - live custom views in Interface Builder + +Example of how to use IB_DESIGNABLE and IBInspectable to preview custom views in Interface Builder. + +## Further Information + +See the following blog post: + ++ [IB_DESIGNABLE Custom Views In Interface Builder](https://useyourloaf.com/blog/ib-designable-custom-views-in-interface-builder/) + +## Version History + ++ Version 1.2 26 Oct 2017 Updated for Xcode 9 and Swift 4 ++ Version 1.1 10 June 2015 Added Swift version ++ Version 1.0 07 June 2015 Initial version. diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer.xcodeproj/project.pbxproj b/DynamicContainer/DynamicContainer-v1/DynamicContainer.xcodeproj/project.pbxproj new file mode 100644 index 0000000..3e407e2 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer.xcodeproj/project.pbxproj @@ -0,0 +1,359 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 53F5583B22315783004115F3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5583A22315783004115F3 /* AppDelegate.swift */; }; + 53F5584022315783004115F3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F5583E22315783004115F3 /* Main.storyboard */; }; + 53F5584222315784004115F3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53F5584122315784004115F3 /* Assets.xcassets */; }; + 53F5584522315784004115F3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F5584322315784004115F3 /* LaunchScreen.storyboard */; }; + 53F5584D22316574004115F3 /* BookListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5584C22316574004115F3 /* BookListTableViewController.swift */; }; + 53F5584F2231669B004115F3 /* LibraryContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5584E2231669B004115F3 /* LibraryContainerViewController.swift */; }; + 53F5585122316C99004115F3 /* MessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5585022316C99004115F3 /* MessageViewController.swift */; }; + 53F5585322316D55004115F3 /* Book.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5585222316D55004115F3 /* Book.swift */; }; + 53F5585522316DBB004115F3 /* SegueHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5585422316DBB004115F3 /* SegueHandler.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 535A7A2A2236C513004D643A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53F5583722315783004115F3 /* DynamicContainer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DynamicContainer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53F5583A22315783004115F3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53F5583F22315783004115F3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53F5584122315784004115F3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53F5584422315784004115F3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53F5584622315784004115F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53F5584C22316574004115F3 /* BookListTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookListTableViewController.swift; sourceTree = ""; }; + 53F5584E2231669B004115F3 /* LibraryContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryContainerViewController.swift; sourceTree = ""; }; + 53F5585022316C99004115F3 /* MessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageViewController.swift; sourceTree = ""; }; + 53F5585222316D55004115F3 /* Book.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Book.swift; sourceTree = ""; }; + 53F5585422316DBB004115F3 /* SegueHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegueHandler.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53F5583422315783004115F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53F5582E22315783004115F3 = { + isa = PBXGroup; + children = ( + 535A7A2A2236C513004D643A /* README.md */, + 53F5583922315783004115F3 /* DynamicContainer */, + 53F5583822315783004115F3 /* Products */, + ); + sourceTree = ""; + }; + 53F5583822315783004115F3 /* Products */ = { + isa = PBXGroup; + children = ( + 53F5583722315783004115F3 /* DynamicContainer.app */, + ); + name = Products; + sourceTree = ""; + }; + 53F5583922315783004115F3 /* DynamicContainer */ = { + isa = PBXGroup; + children = ( + 53F5583A22315783004115F3 /* AppDelegate.swift */, + 53F5584E2231669B004115F3 /* LibraryContainerViewController.swift */, + 53F5584C22316574004115F3 /* BookListTableViewController.swift */, + 53F5585022316C99004115F3 /* MessageViewController.swift */, + 53F5585422316DBB004115F3 /* SegueHandler.swift */, + 53F5585222316D55004115F3 /* Book.swift */, + 53F5583E22315783004115F3 /* Main.storyboard */, + 53F5584122315784004115F3 /* Assets.xcassets */, + 53F5584322315784004115F3 /* LaunchScreen.storyboard */, + 53F5584622315784004115F3 /* Info.plist */, + ); + path = DynamicContainer; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53F5583622315783004115F3 /* DynamicContainer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53F5584922315784004115F3 /* Build configuration list for PBXNativeTarget "DynamicContainer" */; + buildPhases = ( + 53F5583322315783004115F3 /* Sources */, + 53F5583422315783004115F3 /* Frameworks */, + 53F5583522315783004115F3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DynamicContainer; + productName = DynamicContainer; + productReference = 53F5583722315783004115F3 /* DynamicContainer.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53F5582F22315783004115F3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1020; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53F5583622315783004115F3 = { + CreatedOnToolsVersion = 10.2; + }; + }; + }; + buildConfigurationList = 53F5583222315783004115F3 /* Build configuration list for PBXProject "DynamicContainer" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53F5582E22315783004115F3; + productRefGroup = 53F5583822315783004115F3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53F5583622315783004115F3 /* DynamicContainer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53F5583522315783004115F3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53F5584522315784004115F3 /* LaunchScreen.storyboard in Resources */, + 53F5584222315784004115F3 /* Assets.xcassets in Resources */, + 53F5584022315783004115F3 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53F5583322315783004115F3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53F5585522316DBB004115F3 /* SegueHandler.swift in Sources */, + 53F5584F2231669B004115F3 /* LibraryContainerViewController.swift in Sources */, + 53F5583B22315783004115F3 /* AppDelegate.swift in Sources */, + 53F5585122316C99004115F3 /* MessageViewController.swift in Sources */, + 53F5585322316D55004115F3 /* Book.swift in Sources */, + 53F5584D22316574004115F3 /* BookListTableViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53F5583E22315783004115F3 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53F5583F22315783004115F3 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53F5584322315784004115F3 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53F5584422315784004115F3 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53F5584722315784004115F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53F5584822315784004115F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53F5584A22315784004115F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DynamicContainer/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DynamicContainer; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53F5584B22315784004115F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DynamicContainer/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DynamicContainer; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53F5583222315783004115F3 /* Build configuration list for PBXProject "DynamicContainer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53F5584722315784004115F3 /* Debug */, + 53F5584822315784004115F3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53F5584922315784004115F3 /* Build configuration list for PBXNativeTarget "DynamicContainer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53F5584A22315784004115F3 /* Debug */, + 53F5584B22315784004115F3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53F5582F22315783004115F3 /* Project object */; +} diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/AppDelegate.swift b/DynamicContainer/DynamicContainer-v1/DynamicContainer/AppDelegate.swift new file mode 100644 index 0000000..ed2c55b --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/AppDelegate.swift @@ -0,0 +1,34 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/Assets.xcassets/AppIcon.appiconset/Contents.json b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/Assets.xcassets/Contents.json b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/Base.lproj/LaunchScreen.storyboard b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/Base.lproj/Main.storyboard b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Base.lproj/Main.storyboard new file mode 100644 index 0000000..15fb128 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Base.lproj/Main.storyboard @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/Book.swift b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Book.swift new file mode 100644 index 0000000..0a01297 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Book.swift @@ -0,0 +1,35 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +struct Book { + let title: String + let author: String + let firstLine: String +} diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/BookListTableViewController.swift b/DynamicContainer/DynamicContainer-v1/DynamicContainer/BookListTableViewController.swift new file mode 100644 index 0000000..d69493d --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/BookListTableViewController.swift @@ -0,0 +1,59 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol BookListDelegate: AnyObject { + func didSelect(index: Int) +} + +final class BookListTableViewController: UITableViewController { + + var list: [Book] = [] { + didSet { + tableView.reloadData() + } + } + + weak var delegate: BookListDelegate? + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "Subtitle", for: indexPath) + cell.textLabel?.text = list[indexPath.row].title + cell.detailTextLabel?.text = list[indexPath.row].author + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + delegate?.didSelect(index: indexPath.row) + } +} diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/Info.plist b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/LibraryContainerViewController.swift b/DynamicContainer/DynamicContainer-v1/DynamicContainer/LibraryContainerViewController.swift new file mode 100644 index 0000000..7ce2804 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/LibraryContainerViewController.swift @@ -0,0 +1,84 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LibraryContainerViewController: UIViewController { + + private let library = [ + Book(title: "Alice's Adventures in Wonderland", author: "Lewis Caroll", firstLine: "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, ‘and what is the use of a book,’ thought Alice ‘without pictures or conversations?’"), + Book(title: "Emma", author: "Jane Austen", firstLine: "Emma Woodhouse, handsome, clever, and rich, with a comfortable home and happy disposition, seemed to unite some of the best blessings of existence; and had lived nearly twenty-one years in the world with very little to distress or vex her."), + Book(title: "Great Expectations", author: "Charles Dickens", firstLine: "My father's family name being Pirrip, and my Christian name Philip, my infant tongue could make of both names nothing longer or more explicit than Pip."), + Book(title: "Metamorphosis", author: "Franz Kafka", firstLine: "One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin."), + Book(title: "Peter Pan", author: "James M. Barrie", firstLine: "All children, except one, grow up.") + ] + + @IBOutlet private var messageHeightConstraint: NSLayoutConstraint? + + private var previewController: MessageViewController? + private var listTableViewController: BookListTableViewController? + + override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) { + super.preferredContentSizeDidChange(forChildContentContainer: container) + if (container as? MessageViewController) != nil { + messageHeightConstraint?.constant = container.preferredContentSize.height + } + } +} + +extension LibraryContainerViewController: SegueHandler { + + enum SegueIdentifier: String { + case embedList + case embedPreview + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + switch segueIdentifier(for: segue) { + case .embedList: + guard let childController = segue.destination as? BookListTableViewController else { + fatalError("Missing ListTableViewController") + } + listTableViewController = childController + listTableViewController?.list = library + listTableViewController?.delegate = self + case .embedPreview: + guard let childController = segue.destination as? MessageViewController else { + fatalError("Missing MessageViewController") + } + previewController = childController + previewController?.message = "Choose a book..." + } + } +} + +extension LibraryContainerViewController: BookListDelegate { + func didSelect(index: Int) { + previewController?.message = library[index].firstLine + } +} diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/MessageViewController.swift b/DynamicContainer/DynamicContainer-v1/DynamicContainer/MessageViewController.swift new file mode 100644 index 0000000..fc1ac10 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/MessageViewController.swift @@ -0,0 +1,60 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class MessageViewController: UIViewController { + + @IBOutlet private var contentView: UIView! + @IBOutlet private var messageLabel: UILabel! + + var message: String? { + didSet { + updateMessage() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + updateMessage() + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + calculatePreferredSize() + } + + private func calculatePreferredSize() { + let targetSize = CGSize(width: view.bounds.width, height: UIView.layoutFittingCompressedSize.height) + preferredContentSize = contentView.systemLayoutSizeFitting(targetSize) + } + + private func updateMessage() { + messageLabel?.text = message + } +} diff --git a/DynamicContainer/DynamicContainer-v1/DynamicContainer/SegueHandler.swift b/DynamicContainer/DynamicContainer-v1/DynamicContainer/SegueHandler.swift new file mode 100644 index 0000000..bb2be2b --- /dev/null +++ b/DynamicContainer/DynamicContainer-v1/DynamicContainer/SegueHandler.swift @@ -0,0 +1,48 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol SegueHandler { + associatedtype SegueIdentifier: RawRepresentable +} + +extension SegueHandler where Self: UIViewController, SegueIdentifier.RawValue == String { + + func performSegue(withIdentifier segueIdentifier: SegueIdentifier, sender: AnyObject?) { + performSegue(withIdentifier: segueIdentifier.rawValue, sender:sender) + } + + func segueIdentifier(for segue: UIStoryboardSegue) -> SegueIdentifier { + guard let identifier = segue.identifier, + let segueIdentifier = SegueIdentifier(rawValue: identifier) else { + fatalError("Unknown Segue Identifier") + } + return segueIdentifier + } +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer.xcodeproj/project.pbxproj b/DynamicContainer/DynamicContainer-v2/DynamicContainer.xcodeproj/project.pbxproj new file mode 100644 index 0000000..a0a3c72 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer.xcodeproj/project.pbxproj @@ -0,0 +1,357 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 53F5583B22315783004115F3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5583A22315783004115F3 /* AppDelegate.swift */; }; + 53F5584022315783004115F3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F5583E22315783004115F3 /* Main.storyboard */; }; + 53F5584222315784004115F3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53F5584122315784004115F3 /* Assets.xcassets */; }; + 53F5584522315784004115F3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F5584322315784004115F3 /* LaunchScreen.storyboard */; }; + 53F5584D22316574004115F3 /* BookListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5584C22316574004115F3 /* BookListTableViewController.swift */; }; + 53F5584F2231669B004115F3 /* LibraryContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5584E2231669B004115F3 /* LibraryContainerViewController.swift */; }; + 53F5585122316C99004115F3 /* MessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5585022316C99004115F3 /* MessageViewController.swift */; }; + 53F5585322316D55004115F3 /* Book.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5585222316D55004115F3 /* Book.swift */; }; + 53F5585522316DBB004115F3 /* SegueHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F5585422316DBB004115F3 /* SegueHandler.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53F5583722315783004115F3 /* DynamicContainer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DynamicContainer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53F5583A22315783004115F3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53F5583F22315783004115F3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53F5584122315784004115F3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53F5584422315784004115F3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53F5584622315784004115F3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53F5584C22316574004115F3 /* BookListTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookListTableViewController.swift; sourceTree = ""; }; + 53F5584E2231669B004115F3 /* LibraryContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryContainerViewController.swift; sourceTree = ""; }; + 53F5585022316C99004115F3 /* MessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageViewController.swift; sourceTree = ""; }; + 53F5585222316D55004115F3 /* Book.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Book.swift; sourceTree = ""; }; + 53F5585422316DBB004115F3 /* SegueHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegueHandler.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53F5583422315783004115F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53F5582E22315783004115F3 = { + isa = PBXGroup; + children = ( + 53F5583922315783004115F3 /* DynamicContainer */, + 53F5583822315783004115F3 /* Products */, + ); + sourceTree = ""; + }; + 53F5583822315783004115F3 /* Products */ = { + isa = PBXGroup; + children = ( + 53F5583722315783004115F3 /* DynamicContainer.app */, + ); + name = Products; + sourceTree = ""; + }; + 53F5583922315783004115F3 /* DynamicContainer */ = { + isa = PBXGroup; + children = ( + 53F5583A22315783004115F3 /* AppDelegate.swift */, + 53F5584E2231669B004115F3 /* LibraryContainerViewController.swift */, + 53F5584C22316574004115F3 /* BookListTableViewController.swift */, + 53F5585022316C99004115F3 /* MessageViewController.swift */, + 53F5585422316DBB004115F3 /* SegueHandler.swift */, + 53F5585222316D55004115F3 /* Book.swift */, + 53F5583E22315783004115F3 /* Main.storyboard */, + 53F5584122315784004115F3 /* Assets.xcassets */, + 53F5584322315784004115F3 /* LaunchScreen.storyboard */, + 53F5584622315784004115F3 /* Info.plist */, + ); + path = DynamicContainer; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53F5583622315783004115F3 /* DynamicContainer */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53F5584922315784004115F3 /* Build configuration list for PBXNativeTarget "DynamicContainer" */; + buildPhases = ( + 53F5583322315783004115F3 /* Sources */, + 53F5583422315783004115F3 /* Frameworks */, + 53F5583522315783004115F3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DynamicContainer; + productName = DynamicContainer; + productReference = 53F5583722315783004115F3 /* DynamicContainer.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53F5582F22315783004115F3 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1020; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53F5583622315783004115F3 = { + CreatedOnToolsVersion = 10.2; + }; + }; + }; + buildConfigurationList = 53F5583222315783004115F3 /* Build configuration list for PBXProject "DynamicContainer" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53F5582E22315783004115F3; + productRefGroup = 53F5583822315783004115F3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53F5583622315783004115F3 /* DynamicContainer */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53F5583522315783004115F3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53F5584522315784004115F3 /* LaunchScreen.storyboard in Resources */, + 53F5584222315784004115F3 /* Assets.xcassets in Resources */, + 53F5584022315783004115F3 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53F5583322315783004115F3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53F5585522316DBB004115F3 /* SegueHandler.swift in Sources */, + 53F5584F2231669B004115F3 /* LibraryContainerViewController.swift in Sources */, + 53F5583B22315783004115F3 /* AppDelegate.swift in Sources */, + 53F5585122316C99004115F3 /* MessageViewController.swift in Sources */, + 53F5585322316D55004115F3 /* Book.swift in Sources */, + 53F5584D22316574004115F3 /* BookListTableViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53F5583E22315783004115F3 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53F5583F22315783004115F3 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53F5584322315784004115F3 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53F5584422315784004115F3 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53F5584722315784004115F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53F5584822315784004115F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53F5584A22315784004115F3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DynamicContainer/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DynamicContainer; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53F5584B22315784004115F3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DynamicContainer/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DynamicContainer; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53F5583222315783004115F3 /* Build configuration list for PBXProject "DynamicContainer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53F5584722315784004115F3 /* Debug */, + 53F5584822315784004115F3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53F5584922315784004115F3 /* Build configuration list for PBXNativeTarget "DynamicContainer" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53F5584A22315784004115F3 /* Debug */, + 53F5584B22315784004115F3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53F5582F22315783004115F3 /* Project object */; +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/AppDelegate.swift b/DynamicContainer/DynamicContainer-v2/DynamicContainer/AppDelegate.swift new file mode 100644 index 0000000..ed2c55b --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/AppDelegate.swift @@ -0,0 +1,34 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/Assets.xcassets/AppIcon.appiconset/Contents.json b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/Assets.xcassets/Contents.json b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/Base.lproj/LaunchScreen.storyboard b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/Base.lproj/Main.storyboard b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Base.lproj/Main.storyboard new file mode 100644 index 0000000..a06232e --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Base.lproj/Main.storyboard @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/Book.swift b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Book.swift new file mode 100644 index 0000000..0a01297 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Book.swift @@ -0,0 +1,35 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +struct Book { + let title: String + let author: String + let firstLine: String +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/BookListTableViewController.swift b/DynamicContainer/DynamicContainer-v2/DynamicContainer/BookListTableViewController.swift new file mode 100644 index 0000000..d69493d --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/BookListTableViewController.swift @@ -0,0 +1,59 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol BookListDelegate: AnyObject { + func didSelect(index: Int) +} + +final class BookListTableViewController: UITableViewController { + + var list: [Book] = [] { + didSet { + tableView.reloadData() + } + } + + weak var delegate: BookListDelegate? + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "Subtitle", for: indexPath) + cell.textLabel?.text = list[indexPath.row].title + cell.detailTextLabel?.text = list[indexPath.row].author + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + delegate?.didSelect(index: indexPath.row) + } +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/Info.plist b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/LibraryContainerViewController.swift b/DynamicContainer/DynamicContainer-v2/DynamicContainer/LibraryContainerViewController.swift new file mode 100644 index 0000000..8f30cb1 --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/LibraryContainerViewController.swift @@ -0,0 +1,76 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class LibraryContainerViewController: UIViewController { + + private let library = [ + Book(title: "Alice's Adventures in Wonderland", author: "Lewis Caroll", firstLine: "Alice was beginning to get very tired of sitting by her sister on the bank, and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, ‘and what is the use of a book,’ thought Alice ‘without pictures or conversations?’"), + Book(title: "Emma", author: "Jane Austen", firstLine: "Emma Woodhouse, handsome, clever, and rich, with a comfortable home and happy disposition, seemed to unite some of the best blessings of existence; and had lived nearly twenty-one years in the world with very little to distress or vex her."), + Book(title: "Great Expectations", author: "Charles Dickens", firstLine: "My father's family name being Pirrip, and my Christian name Philip, my infant tongue could make of both names nothing longer or more explicit than Pip."), + Book(title: "Metamorphosis", author: "Franz Kafka", firstLine: "One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin."), + Book(title: "Peter Pan", author: "James M. Barrie", firstLine: "All children, except one, grow up.") + ] + + private var previewController: MessageViewController? + private var listTableViewController: BookListTableViewController? +} + +extension LibraryContainerViewController: SegueHandler { + + enum SegueIdentifier: String { + case embedList + case embedPreview + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + switch segueIdentifier(for: segue) { + case .embedList: + guard let childController = segue.destination as? BookListTableViewController else { + fatalError("Missing ListTableViewController") + } + listTableViewController = childController + listTableViewController?.list = library + listTableViewController?.delegate = self + case .embedPreview: + guard let childController = segue.destination as? MessageViewController else { + fatalError("Missing MessageViewController") + } + previewController = childController + previewController?.message = "Choose a book..." + previewController?.view.translatesAutoresizingMaskIntoConstraints = false + } + } +} + +extension LibraryContainerViewController: BookListDelegate { + func didSelect(index: Int) { + previewController?.message = library[index].firstLine + } +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/MessageViewController.swift b/DynamicContainer/DynamicContainer-v2/DynamicContainer/MessageViewController.swift new file mode 100644 index 0000000..4301e5e --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/MessageViewController.swift @@ -0,0 +1,50 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class MessageViewController: UIViewController { + + @IBOutlet private var contentView: UIView! + @IBOutlet private var messageLabel: UILabel! + + var message: String? { + didSet { + updateMessage() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + updateMessage() + } + + private func updateMessage() { + messageLabel?.text = message + } +} diff --git a/DynamicContainer/DynamicContainer-v2/DynamicContainer/SegueHandler.swift b/DynamicContainer/DynamicContainer-v2/DynamicContainer/SegueHandler.swift new file mode 100644 index 0000000..bb2be2b --- /dev/null +++ b/DynamicContainer/DynamicContainer-v2/DynamicContainer/SegueHandler.swift @@ -0,0 +1,48 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol SegueHandler { + associatedtype SegueIdentifier: RawRepresentable +} + +extension SegueHandler where Self: UIViewController, SegueIdentifier.RawValue == String { + + func performSegue(withIdentifier segueIdentifier: SegueIdentifier, sender: AnyObject?) { + performSegue(withIdentifier: segueIdentifier.rawValue, sender:sender) + } + + func segueIdentifier(for segue: UIStoryboardSegue) -> SegueIdentifier { + guard let identifier = segue.identifier, + let segueIdentifier = SegueIdentifier(rawValue: identifier) else { + fatalError("Unknown Segue Identifier") + } + return segueIdentifier + } +} diff --git a/DynamicContainer/README.md b/DynamicContainer/README.md new file mode 100644 index 0000000..9ce1e8b --- /dev/null +++ b/DynamicContainer/README.md @@ -0,0 +1,9 @@ +# Self-sizing Child Views + +This project is an example of using the `UIContentContainer` protocol to allow a child view controller to tell its parent its preferred content size. + +See the following blog post for more details: + +[Self-sizing Child Views](https://useyourloaf.com/blog/self-sizing-child-views/) + +See the second example in the folder `DynamicContainer-v2` for an example of how to achieve the same effect without using the preferred content size. diff --git a/DynamicText/DynamicText.xcodeproj/project.pbxproj b/DynamicText/DynamicText.xcodeproj/project.pbxproj index 47eceeb..8707dce 100644 --- a/DynamicText/DynamicText.xcodeproj/project.pbxproj +++ b/DynamicText/DynamicText.xcodeproj/project.pbxproj @@ -3,11 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ 531B320A1861EFB6005F2332 /* UYLScaledTextStyleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 531B32091861EFB6005F2332 /* UYLScaledTextStyleViewController.m */; }; + 53615D2F1F41B67900C7D904 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53615D2D1F41B67900C7D904 /* LaunchScreen.storyboard */; }; 5393B52E17F83CB600AD2292 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5393B52D17F83CB600AD2292 /* Foundation.framework */; }; 5393B53017F83CB600AD2292 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5393B52F17F83CB600AD2292 /* CoreGraphics.framework */; }; 5393B53217F83CB600AD2292 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5393B53117F83CB600AD2292 /* UIKit.framework */; }; @@ -16,29 +17,15 @@ 5393B53E17F83CB600AD2292 /* UYLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5393B53D17F83CB600AD2292 /* UYLAppDelegate.m */; }; 5393B54117F83CB600AD2292 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5393B53F17F83CB600AD2292 /* Main.storyboard */; }; 5393B54617F83CB600AD2292 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5393B54517F83CB600AD2292 /* Images.xcassets */; }; - 5393B54D17F83CB600AD2292 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5393B54C17F83CB600AD2292 /* XCTest.framework */; }; - 5393B54E17F83CB600AD2292 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5393B52D17F83CB600AD2292 /* Foundation.framework */; }; - 5393B54F17F83CB600AD2292 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5393B53117F83CB600AD2292 /* UIKit.framework */; }; - 5393B55717F83CB600AD2292 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5393B55517F83CB600AD2292 /* InfoPlist.strings */; }; - 5393B55917F83CB600AD2292 /* DynamicTextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5393B55817F83CB600AD2292 /* DynamicTextTests.m */; }; 5393B56417F83DB000AD2292 /* UYLTextStyleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5393B56317F83DB000AD2292 /* UYLTextStyleViewController.m */; }; 53FE524C1871CDB700DE5F24 /* UIFont+UYLScaledFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 53FE524B1871CDB700DE5F24 /* UIFont+UYLScaledFont.m */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 5393B55017F83CB600AD2292 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5393B52217F83CB600AD2292 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5393B52917F83CB600AD2292; - remoteInfo = DynamicText; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXFileReference section */ 531B32081861EFB6005F2332 /* UYLScaledTextStyleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLScaledTextStyleViewController.h; sourceTree = ""; }; 531B32091861EFB6005F2332 /* UYLScaledTextStyleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLScaledTextStyleViewController.m; sourceTree = ""; }; - 5325F8AD18020B0B0000A32A /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; + 5325F8AD18020B0B0000A32A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53615D2E1F41B67900C7D904 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 5393B52A17F83CB600AD2292 /* DynamicText.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DynamicText.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5393B52D17F83CB600AD2292 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 5393B52F17F83CB600AD2292 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -51,11 +38,7 @@ 5393B53D17F83CB600AD2292 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 5393B54017F83CB600AD2292 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 5393B54517F83CB600AD2292 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 5393B54B17F83CB600AD2292 /* DynamicTextTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DynamicTextTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5393B54C17F83CB600AD2292 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; - 5393B55417F83CB600AD2292 /* DynamicTextTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DynamicTextTests-Info.plist"; sourceTree = ""; }; - 5393B55617F83CB600AD2292 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 5393B55817F83CB600AD2292 /* DynamicTextTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DynamicTextTests.m; sourceTree = ""; }; 5393B56217F83DB000AD2292 /* UYLTextStyleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLTextStyleViewController.h; sourceTree = ""; }; 5393B56317F83DB000AD2292 /* UYLTextStyleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLTextStyleViewController.m; sourceTree = ""; }; 53FE524A1871CDB700DE5F24 /* UIFont+UYLScaledFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+UYLScaledFont.h"; sourceTree = ""; }; @@ -73,25 +56,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5393B54817F83CB600AD2292 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5393B54D17F83CB600AD2292 /* XCTest.framework in Frameworks */, - 5393B54F17F83CB600AD2292 /* UIKit.framework in Frameworks */, - 5393B54E17F83CB600AD2292 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 5393B52117F83CB600AD2292 = { isa = PBXGroup; children = ( - 5325F8AD18020B0B0000A32A /* README */, + 5325F8AD18020B0B0000A32A /* README.md */, 5393B53317F83CB600AD2292 /* DynamicText */, - 5393B55217F83CB600AD2292 /* DynamicTextTests */, 5393B52C17F83CB600AD2292 /* Frameworks */, 5393B52B17F83CB600AD2292 /* Products */, ); @@ -101,7 +73,6 @@ isa = PBXGroup; children = ( 5393B52A17F83CB600AD2292 /* DynamicText.app */, - 5393B54B17F83CB600AD2292 /* DynamicTextTests.xctest */, ); name = Products; sourceTree = ""; @@ -129,6 +100,7 @@ 53FE524A1871CDB700DE5F24 /* UIFont+UYLScaledFont.h */, 53FE524B1871CDB700DE5F24 /* UIFont+UYLScaledFont.m */, 5393B53F17F83CB600AD2292 /* Main.storyboard */, + 53615D2D1F41B67900C7D904 /* LaunchScreen.storyboard */, 5393B54517F83CB600AD2292 /* Images.xcassets */, 5393B53417F83CB600AD2292 /* Supporting Files */, ); @@ -146,24 +118,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 5393B55217F83CB600AD2292 /* DynamicTextTests */ = { - isa = PBXGroup; - children = ( - 5393B55817F83CB600AD2292 /* DynamicTextTests.m */, - 5393B55317F83CB600AD2292 /* Supporting Files */, - ); - path = DynamicTextTests; - sourceTree = ""; - }; - 5393B55317F83CB600AD2292 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 5393B55417F83CB600AD2292 /* DynamicTextTests-Info.plist */, - 5393B55517F83CB600AD2292 /* InfoPlist.strings */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -184,24 +138,6 @@ productReference = 5393B52A17F83CB600AD2292 /* DynamicText.app */; productType = "com.apple.product-type.application"; }; - 5393B54A17F83CB600AD2292 /* DynamicTextTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5393B55F17F83CB600AD2292 /* Build configuration list for PBXNativeTarget "DynamicTextTests" */; - buildPhases = ( - 5393B54717F83CB600AD2292 /* Sources */, - 5393B54817F83CB600AD2292 /* Frameworks */, - 5393B54917F83CB600AD2292 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 5393B55117F83CB600AD2292 /* PBXTargetDependency */, - ); - name = DynamicTextTests; - productName = DynamicTextTests; - productReference = 5393B54B17F83CB600AD2292 /* DynamicTextTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -209,17 +145,12 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0510; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; - TargetAttributes = { - 5393B54A17F83CB600AD2292 = { - TestTargetID = 5393B52917F83CB600AD2292; - }; - }; }; buildConfigurationList = 5393B52517F83CB600AD2292 /* Build configuration list for PBXProject "DynamicText" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -231,7 +162,6 @@ projectRoot = ""; targets = ( 5393B52917F83CB600AD2292 /* DynamicText */, - 5393B54A17F83CB600AD2292 /* DynamicTextTests */, ); }; /* End PBXProject section */ @@ -242,19 +172,12 @@ buildActionMask = 2147483647; files = ( 5393B54617F83CB600AD2292 /* Images.xcassets in Resources */, + 53615D2F1F41B67900C7D904 /* LaunchScreen.storyboard in Resources */, 5393B53817F83CB600AD2292 /* InfoPlist.strings in Resources */, 5393B54117F83CB600AD2292 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5393B54917F83CB600AD2292 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5393B55717F83CB600AD2292 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -270,25 +193,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5393B54717F83CB600AD2292 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5393B55917F83CB600AD2292 /* DynamicTextTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 5393B55117F83CB600AD2292 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5393B52917F83CB600AD2292 /* DynamicText */; - targetProxy = 5393B55017F83CB600AD2292 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin PBXVariantGroup section */ + 53615D2D1F41B67900C7D904 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53615D2E1F41B67900C7D904 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; 5393B53617F83CB600AD2292 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -305,14 +220,6 @@ name = Main.storyboard; sourceTree = ""; }; - 5393B55517F83CB600AD2292 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 5393B55617F83CB600AD2292 /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -320,22 +227,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -348,7 +270,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -358,29 +280,43 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -390,11 +326,15 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CURRENT_PROJECT_VERSION = 1.3; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DynamicText/DynamicText-Prefix.pch"; INFOPLIST_FILE = "DynamicText/DynamicText-Info.plist"; + MARKETING_VERSION = 1.3; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -403,55 +343,19 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CURRENT_PROJECT_VERSION = 1.3; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "DynamicText/DynamicText-Prefix.pch"; INFOPLIST_FILE = "DynamicText/DynamicText-Info.plist"; + MARKETING_VERSION = 1.3; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Release; }; - 5393B56017F83CB600AD2292 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DynamicText.app/DynamicText"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "DynamicText/DynamicText-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = "DynamicTextTests/DynamicTextTests-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUNDLE_LOADER)"; - WRAPPER_EXTENSION = xctest; - }; - name = Debug; - }; - 5393B56117F83CB600AD2292 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DynamicText.app/DynamicText"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - "$(DEVELOPER_FRAMEWORKS_DIR)", - ); - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "DynamicText/DynamicText-Prefix.pch"; - INFOPLIST_FILE = "DynamicTextTests/DynamicTextTests-Info.plist"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUNDLE_LOADER)"; - WRAPPER_EXTENSION = xctest; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -473,15 +377,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5393B55F17F83CB600AD2292 /* Build configuration list for PBXNativeTarget "DynamicTextTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5393B56017F83CB600AD2292 /* Debug */, - 5393B56117F83CB600AD2292 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 5393B52217F83CB600AD2292 /* Project object */; diff --git a/DynamicText/DynamicText/Base.lproj/LaunchScreen.storyboard b/DynamicText/DynamicText/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f746012 --- /dev/null +++ b/DynamicText/DynamicText/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicText/DynamicText/Base.lproj/Main.storyboard b/DynamicText/DynamicText/Base.lproj/Main.storyboard index ff01357..f069627 100644 --- a/DynamicText/DynamicText/Base.lproj/Main.storyboard +++ b/DynamicText/DynamicText/Base.lproj/Main.storyboard @@ -1,10 +1,13 @@ - - + + + - + + + - + @@ -13,59 +16,52 @@ - + - + @@ -103,9 +99,9 @@ - + - + @@ -114,60 +110,53 @@ - + - + @@ -205,7 +194,7 @@ - + @@ -214,8 +203,9 @@ + - + @@ -224,16 +214,11 @@ - + - - - - - - \ No newline at end of file + diff --git a/DynamicText/DynamicText/DynamicText-Info.plist b/DynamicText/DynamicText/DynamicText-Info.plist index 79bd7f0..2348c0a 100644 --- a/DynamicText/DynamicText/DynamicText-Info.plist +++ b/DynamicText/DynamicText/DynamicText-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -17,13 +17,15 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 1.0 + $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities @@ -35,6 +37,7 @@ UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/Contents.json b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/Contents.json index fb4b75f..1120389 100644 --- a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,22 +1,112 @@ { "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon-40.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon-60.png", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", "filename" : "icon-29@2x.png", "scale" : "2x" }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "icon-29@3x.png", + "scale" : "3x" + }, { "size" : "40x40", "idiom" : "iphone", "filename" : "icon-40@2x.png", "scale" : "2x" }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "icon-120.png", + "scale" : "3x" + }, { "size" : "60x60", "idiom" : "iphone", "filename" : "icon-60@2x.png", "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon-180.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon-20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon-41.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "icon-29.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "icon-29@2x-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "icon-42.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "icon-40@2x-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon-76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon-76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "icon-167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "icon-1024.png", + "scale" : "1x" } ], "info" : { diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-1024.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000..4a1a9de Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-1024.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-120.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-120.png new file mode 100644 index 0000000..d4b42eb Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-120.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-167.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-167.png new file mode 100644 index 0000000..0a5ec66 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-167.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-180.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-180.png new file mode 100644 index 0000000..e943cc3 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-180.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-20.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-20.png new file mode 100644 index 0000000..3c16adf Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-20.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29.png new file mode 100644 index 0000000..b918cea Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29@2x-1.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29@2x-1.png new file mode 100644 index 0000000..3c599a5 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29@2x-1.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29@3x.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29@3x.png new file mode 100644 index 0000000..f32646a Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-29@3x.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-40.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-40.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-40.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-40@2x-1.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-40@2x-1.png new file mode 100644 index 0000000..afcf538 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-40@2x-1.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-41.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-41.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-41.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-42.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-42.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-42.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-60.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-60.png new file mode 100644 index 0000000..fd2eff6 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-60.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-76.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-76.png new file mode 100644 index 0000000..90d600a Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-76.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-76@2x.png b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-76@2x.png new file mode 100644 index 0000000..6b529b8 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/AppIcon.appiconset/icon-76@2x.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/Contents.json b/DynamicText/DynamicText/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/DynamicText/DynamicText/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DynamicText/DynamicText/Images.xcassets/LaunchImage.launchimage/Contents.json b/DynamicText/DynamicText/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index dfb911d..0000000 --- a/DynamicText/DynamicText/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "subtype" : "retina4", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "subtype" : "retina4", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/Contents.json b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/Contents.json index a345b09..f7afaee 100644 --- a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/Contents.json +++ b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/Contents.json @@ -2,13 +2,18 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x", - "filename" : "first.png" + "filename" : "first30.png", + "scale" : "1x" }, { "idiom" : "universal", - "scale" : "2x", - "filename" : "first@2x.png" + "filename" : "first60.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "first90.png", + "scale" : "3x" } ], "info" : { diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first30.png b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first30.png new file mode 100644 index 0000000..e7f0902 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first30.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first60.png b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first60.png new file mode 100644 index 0000000..975a75f Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first60.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first90.png b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first90.png new file mode 100644 index 0000000..92341c2 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/Tab Bar/First.imageset/first90.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/Contents.json b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/Contents.json index 2136402..fd58914 100644 --- a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/Contents.json +++ b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/Contents.json @@ -2,13 +2,18 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x", - "filename" : "second.png" + "filename" : "second30.png", + "scale" : "1x" }, { "idiom" : "universal", - "scale" : "2x", - "filename" : "second@2x.png" + "filename" : "second60.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "second90.png", + "scale" : "3x" } ], "info" : { diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second30.png b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second30.png new file mode 100644 index 0000000..728d7f6 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second30.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second60.png b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second60.png new file mode 100644 index 0000000..9cd7cb3 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second60.png differ diff --git a/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second90.png b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second90.png new file mode 100644 index 0000000..6170461 Binary files /dev/null and b/DynamicText/DynamicText/Images.xcassets/Tab Bar/Second.imageset/second90.png differ diff --git a/DynamicText/DynamicText/UYLTextStyleViewController.m b/DynamicText/DynamicText/UYLTextStyleViewController.m index 1e3d0ab..6871248 100644 --- a/DynamicText/DynamicText/UYLTextStyleViewController.m +++ b/DynamicText/DynamicText/UYLTextStyleViewController.m @@ -54,11 +54,6 @@ - (void)viewDidAppear:(BOOL)animated [self configureView]; } -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - - (void)configureView { self.textSizeLabel.text = [[UIApplication sharedApplication] preferredContentSizeCategory]; diff --git a/DynamicText/DynamicTextTests/DynamicTextTests.m b/DynamicText/DynamicTextTests/DynamicTextTests.m deleted file mode 100644 index 88a0617..0000000 --- a/DynamicText/DynamicTextTests/DynamicTextTests.m +++ /dev/null @@ -1,34 +0,0 @@ -// -// DynamicTextTests.m -// DynamicTextTests -// -// Created by Keith Harrison on 29/09/2013. -// Copyright (c) 2013 Keith Harrison. All rights reserved. -// - -#import - -@interface DynamicTextTests : XCTestCase - -@end - -@implementation DynamicTextTests - -- (void)setUp -{ - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown -{ - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testExample -{ - XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); -} - -@end diff --git a/DynamicText/README b/DynamicText/README deleted file mode 100644 index 5f71f7f..0000000 --- a/DynamicText/README +++ /dev/null @@ -1,26 +0,0 @@ -======================================================================= -DynamicText - Responding to text size changes - -Version 1.0 06 October 2013 Initial version. -Version 1.1 30 December 2013 Added UYLScaledTextViewController -======================================================================= - -This is a example project showing how to respond to the user changing -the preferred text size. - - -The UYLTextStyleViewController shows the standard way to listen for -and respond to changes to the users preferred text size using the -built-in UIFont Text Styles. - -For further details see the following blog post: -http://useyourloaf.com/blog/2013/12/17/supporting-dynamic-type.html - - -The UYLScaledTextStyleViewController extends the basic approach by -showing how to scale the preferred fonts using a UIFontDescriptor. -A convenience method to return the scaled font is added as a -category of UIFont for this purpose. - -For further details see the following blog post: -http://useyourloaf.com/blog/2013/12/30/scaling-dynamic-type-with-font-descriptors.html diff --git a/DynamicText/README.md b/DynamicText/README.md new file mode 100644 index 0000000..14c9d11 --- /dev/null +++ b/DynamicText/README.md @@ -0,0 +1,32 @@ +# DynamicText + +## Responding to text size changes + +This is a example project showing how to respond to the user changing +the preferred text size. + +**Minimum deployment target is now iOS 9.0 using Xcode 11** + +The `UYLTextStyleViewController` shows the standard way to listen for +and respond to changes to the users preferred text size using the +built-in `UIFont` Text Styles. + +For further details see the following blog post: + ++ [Supporting Dynamic Type](https://useyourloaf.com/blog/supporting-dynamic-type/) + +The `UYLScaledTextStyleViewController` extends the basic approach by +showing how to scale the preferred fonts using a `UIFontDescriptor`. +A convenience method to return the scaled font is added as a +category of `UIFont` for this purpose. + +For further details see the following blog post: + ++ [Scaling Synamic Type With Font Descriptors](https://useyourloaf.com/blog/scaling-dynamic-type-with-font-descriptors/) + +## History + +Version 1.3 11 January 2020 Updated for Xcode 11 +Version 1.2 14 August 2017 Updated for Xcode 8 and iOS 10 +Version 1.1 30 December 2013 Added UYLScaledTextViewController +Version 1.0 06 October 2013 Initial version. diff --git a/DynamicWebKit/DynamicWebKit.xcodeproj/project.pbxproj b/DynamicWebKit/DynamicWebKit.xcodeproj/project.pbxproj new file mode 100644 index 0000000..995fc45 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit.xcodeproj/project.pbxproj @@ -0,0 +1,366 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 53A2B53B1F94DBE500095FAD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A2B53A1F94DBE500095FAD /* AppDelegate.swift */; }; + 53A2B53D1F94DBE500095FAD /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A2B53C1F94DBE500095FAD /* WebViewController.swift */; }; + 53A2B5401F94DBE500095FAD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B53E1F94DBE500095FAD /* Main.storyboard */; }; + 53A2B5421F94DBE500095FAD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B5411F94DBE500095FAD /* Assets.xcassets */; }; + 53A2B5451F94DBE500095FAD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B5431F94DBE500095FAD /* LaunchScreen.storyboard */; }; + 53A2B54D1F94DC9700095FAD /* default.html in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B54C1F94DC9700095FAD /* default.html */; }; + 53A2B54F1F94DD8200095FAD /* stylesheet.css in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B54E1F94DD8200095FAD /* stylesheet.css */; }; + 53E34E032403D85700EE575E /* 001-dark.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E34E022403D67600EE575E /* 001-dark.png */; }; + 53E34E042403D85A00EE575E /* 001-dark@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E34DFF2403D67600EE575E /* 001-dark@2x.png */; }; + 53E34E052403D85E00EE575E /* 001.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E34E012403D67600EE575E /* 001.png */; }; + 53E34E062403D86100EE575E /* 001@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53E34E002403D67600EE575E /* 001@2x.png */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53A2B5371F94DBE500095FAD /* DynamicWebKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DynamicWebKit.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53A2B53A1F94DBE500095FAD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53A2B53C1F94DBE500095FAD /* WebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = ""; }; + 53A2B53F1F94DBE500095FAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53A2B5411F94DBE500095FAD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53A2B5441F94DBE500095FAD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53A2B5461F94DBE500095FAD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53A2B54C1F94DC9700095FAD /* default.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = default.html; sourceTree = ""; }; + 53A2B54E1F94DD8200095FAD /* stylesheet.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = stylesheet.css; sourceTree = ""; }; + 53A2B5501F94F14800095FAD /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53E34DFF2403D67600EE575E /* 001-dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "001-dark@2x.png"; sourceTree = ""; }; + 53E34E002403D67600EE575E /* 001@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "001@2x.png"; sourceTree = ""; }; + 53E34E012403D67600EE575E /* 001.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 001.png; sourceTree = ""; }; + 53E34E022403D67600EE575E /* 001-dark.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "001-dark.png"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53A2B5341F94DBE500095FAD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53A2B52E1F94DBE500095FAD = { + isa = PBXGroup; + children = ( + 53A2B5501F94F14800095FAD /* README.md */, + 53A2B5391F94DBE500095FAD /* DynamicWebKit */, + 53A2B5381F94DBE500095FAD /* Products */, + ); + sourceTree = ""; + }; + 53A2B5381F94DBE500095FAD /* Products */ = { + isa = PBXGroup; + children = ( + 53A2B5371F94DBE500095FAD /* DynamicWebKit.app */, + ); + name = Products; + sourceTree = ""; + }; + 53A2B5391F94DBE500095FAD /* DynamicWebKit */ = { + isa = PBXGroup; + children = ( + 53A2B53A1F94DBE500095FAD /* AppDelegate.swift */, + 53A2B53C1F94DBE500095FAD /* WebViewController.swift */, + 53E34DFE2403D58400EE575E /* HTML */, + 53A2B53E1F94DBE500095FAD /* Main.storyboard */, + 53A2B5411F94DBE500095FAD /* Assets.xcassets */, + 53A2B5431F94DBE500095FAD /* LaunchScreen.storyboard */, + 53A2B5461F94DBE500095FAD /* Info.plist */, + ); + path = DynamicWebKit; + sourceTree = ""; + }; + 53E34DFE2403D58400EE575E /* HTML */ = { + isa = PBXGroup; + children = ( + 53A2B54C1F94DC9700095FAD /* default.html */, + 53E34E022403D67600EE575E /* 001-dark.png */, + 53E34DFF2403D67600EE575E /* 001-dark@2x.png */, + 53E34E012403D67600EE575E /* 001.png */, + 53E34E002403D67600EE575E /* 001@2x.png */, + 53A2B54E1F94DD8200095FAD /* stylesheet.css */, + ); + path = HTML; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53A2B5361F94DBE500095FAD /* DynamicWebKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53A2B5491F94DBE500095FAD /* Build configuration list for PBXNativeTarget "DynamicWebKit" */; + buildPhases = ( + 53A2B5331F94DBE500095FAD /* Sources */, + 53A2B5341F94DBE500095FAD /* Frameworks */, + 53A2B5351F94DBE500095FAD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DynamicWebKit; + productName = DynamicWebKit; + productReference = 53A2B5371F94DBE500095FAD /* DynamicWebKit.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53A2B52F1F94DBE500095FAD /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0900; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53A2B5361F94DBE500095FAD = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 1120; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 53A2B5321F94DBE500095FAD /* Build configuration list for PBXProject "DynamicWebKit" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53A2B52E1F94DBE500095FAD; + productRefGroup = 53A2B5381F94DBE500095FAD /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53A2B5361F94DBE500095FAD /* DynamicWebKit */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53A2B5351F94DBE500095FAD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E34E042403D85A00EE575E /* 001-dark@2x.png in Resources */, + 53A2B54D1F94DC9700095FAD /* default.html in Resources */, + 53A2B54F1F94DD8200095FAD /* stylesheet.css in Resources */, + 53E34E052403D85E00EE575E /* 001.png in Resources */, + 53A2B5451F94DBE500095FAD /* LaunchScreen.storyboard in Resources */, + 53E34E032403D85700EE575E /* 001-dark.png in Resources */, + 53A2B5421F94DBE500095FAD /* Assets.xcassets in Resources */, + 53E34E062403D86100EE575E /* 001@2x.png in Resources */, + 53A2B5401F94DBE500095FAD /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53A2B5331F94DBE500095FAD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53A2B53D1F94DBE500095FAD /* WebViewController.swift in Sources */, + 53A2B53B1F94DBE500095FAD /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53A2B53E1F94DBE500095FAD /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53A2B53F1F94DBE500095FAD /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53A2B5431F94DBE500095FAD /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53A2B5441F94DBE500095FAD /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53A2B5471F94DBE500095FAD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53A2B5481F94DBE500095FAD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53A2B54A1F94DBE500095FAD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DynamicWebKit/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DynamicWebKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53A2B54B1F94DBE500095FAD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = DynamicWebKit/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.DynamicWebKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53A2B5321F94DBE500095FAD /* Build configuration list for PBXProject "DynamicWebKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53A2B5471F94DBE500095FAD /* Debug */, + 53A2B5481F94DBE500095FAD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53A2B5491F94DBE500095FAD /* Build configuration list for PBXNativeTarget "DynamicWebKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53A2B54A1F94DBE500095FAD /* Debug */, + 53A2B54B1F94DBE500095FAD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53A2B52F1F94DBE500095FAD /* Project object */; +} diff --git a/DynamicWebKit/DynamicWebKit/AppDelegate.swift b/DynamicWebKit/DynamicWebKit/AppDelegate.swift new file mode 100644 index 0000000..6420758 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/AppDelegate.swift @@ -0,0 +1,35 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/DynamicWebKit/DynamicWebKit/Assets.xcassets/AppIcon.appiconset/Contents.json b/DynamicWebKit/DynamicWebKit/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DynamicWebKit/DynamicWebKit/Base.lproj/LaunchScreen.storyboard b/DynamicWebKit/DynamicWebKit/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f83f6fd --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicWebKit/DynamicWebKit/Base.lproj/Main.storyboard b/DynamicWebKit/DynamicWebKit/Base.lproj/Main.storyboard new file mode 100644 index 0000000..c0a6762 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/Base.lproj/Main.storyboard @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DynamicWebKit/DynamicWebKit/HTML/001-dark.png b/DynamicWebKit/DynamicWebKit/HTML/001-dark.png new file mode 100644 index 0000000..98e7b46 Binary files /dev/null and b/DynamicWebKit/DynamicWebKit/HTML/001-dark.png differ diff --git a/DynamicWebKit/DynamicWebKit/HTML/001-dark@2x.png b/DynamicWebKit/DynamicWebKit/HTML/001-dark@2x.png new file mode 100644 index 0000000..867a616 Binary files /dev/null and b/DynamicWebKit/DynamicWebKit/HTML/001-dark@2x.png differ diff --git a/DynamicWebKit/DynamicWebKit/HTML/001.png b/DynamicWebKit/DynamicWebKit/HTML/001.png new file mode 100644 index 0000000..1d96a9a Binary files /dev/null and b/DynamicWebKit/DynamicWebKit/HTML/001.png differ diff --git a/DynamicWebKit/DynamicWebKit/HTML/001@2x.png b/DynamicWebKit/DynamicWebKit/HTML/001@2x.png new file mode 100644 index 0000000..15688c5 Binary files /dev/null and b/DynamicWebKit/DynamicWebKit/HTML/001@2x.png differ diff --git a/DynamicWebKit/DynamicWebKit/HTML/default.html b/DynamicWebKit/DynamicWebKit/HTML/default.html new file mode 100644 index 0000000..96c14f7 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/HTML/default.html @@ -0,0 +1,21 @@ + + + + + + +User Guide + + +

Dynamic Type With WebKit

+

Getting Started

+

An example of using dynamic type fonts with HTML content displayed in a WKWebView. Changing the text size in Settings should also change the text in this web view.

+

Handling Images

+

An example of an image with a dark mode variation

+ + +Xcode source editor + + + + diff --git a/DynamicWebKit/DynamicWebKit/HTML/stylesheet.css b/DynamicWebKit/DynamicWebKit/HTML/stylesheet.css new file mode 100644 index 0000000..00998a7 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/HTML/stylesheet.css @@ -0,0 +1,40 @@ +:root { + color-scheme: light dark; + --title-color: red; + --subhead-color: green; + --link-color: blue; +} + +@media screen and (prefers-color-scheme: dark) { + :root { + --title-color: #ff8080; + --subhead-color: #80ff80; + --link-color: #93d5ff; + } +} + +body { + font: -apple-system-body; +} + +h1 { + font: -apple-system-headline; + color: var(--title-color); +} + +h2 { + font: -apple-system-subheadline; + color: var(--subhead-color); +} + +footer { + font: -apple-system-footnote; +} + +a { + color: var(--link-color); +} + +img { + max-width: 100%; +} diff --git a/DynamicWebKit/DynamicWebKit/Info.plist b/DynamicWebKit/DynamicWebKit/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/DynamicWebKit/DynamicWebKit/WebViewController.swift b/DynamicWebKit/DynamicWebKit/WebViewController.swift new file mode 100644 index 0000000..90b5382 --- /dev/null +++ b/DynamicWebKit/DynamicWebKit/WebViewController.swift @@ -0,0 +1,63 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017-2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +import WebKit + +final class WebViewController: UIViewController { + var html: String = "default" { + didSet { + loadHTML(html) + } + } + + private lazy var webView: WKWebView = { + let preferences = WKPreferences() + preferences.javaScriptEnabled = false + let configuration = WKWebViewConfiguration() + configuration.preferences = preferences + return WKWebView(frame: .zero, configuration: configuration) + }() + + override func loadView() { + view = webView + loadHTML(html) + NotificationCenter.default.addObserver(self, selector: #selector(contentSizeDidChange(_:)), name: UIContentSizeCategory.didChangeNotification, object: nil) + } + + @objc private func contentSizeDidChange(_ notification: Notification) { + webView.reload() + } + + private func loadHTML(_ name: String) { + if let url = Bundle.main.url(forResource: name, withExtension: "html") { + webView.loadFileURL(url, allowingReadAccessTo: url) + } + } +} diff --git a/DynamicWebKit/README.md b/DynamicWebKit/README.md new file mode 100644 index 0000000..3f59978 --- /dev/null +++ b/DynamicWebKit/README.md @@ -0,0 +1,14 @@ +# Using Dynamic Type With Web Views + +An example of how to use the Apple system fonts in a CSS stylesheet so static HTML content in a web view respects the user's choice of content size. + +## Adding Support For Dark Mode + +I've updated this project to support dark mode (requires iOS 13). + +## Further Details + +For further details see the following blog posts: + ++ [Using Dynamic Type With Web Views](https://useyourloaf.com/blog/using-dynamic-type-with-web-views/) ++ [Supporting Dark Mode In WkWebView](https://useyourloaf.com/blog/supporting-dark-mode-in-wkwebview/) diff --git a/Encode/encode.xcodeproj/project.pbxproj b/Encode/encode.xcodeproj/project.pbxproj index d1f32bb..90a9c65 100644 --- a/Encode/encode.xcodeproj/project.pbxproj +++ b/Encode/encode.xcodeproj/project.pbxproj @@ -195,11 +195,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53BE6B291C356461001C8FC9 = { CreatedOnToolsVersion = 7.2; + DevelopmentTeam = LCC2J94N44; }; 53BE6B3D1C356462001C8FC9 = { CreatedOnToolsVersion = 7.2; @@ -213,7 +214,7 @@ }; buildConfigurationList = 53BE6B251C356461001C8FC9 /* Build configuration list for PBXProject "encode" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -326,17 +327,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -363,6 +375,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -371,17 +384,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -400,6 +424,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -409,6 +435,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = encode/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.encode; @@ -420,6 +447,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = encode/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.encode; diff --git a/Encode/encode/Assets.xcassets/AppIcon.appiconset/Contents.json b/Encode/encode/Assets.xcassets/AppIcon.appiconset/Contents.json index eeea76c..d8db8d6 100644 --- a/Encode/encode/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Encode/encode/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -64,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Encode/encode/Base.lproj/Main.storyboard b/Encode/encode/Base.lproj/Main.storyboard index 7ec14df..d39fa46 100644 --- a/Encode/encode/Base.lproj/Main.storyboard +++ b/Encode/encode/Base.lproj/Main.storyboard @@ -1,97 +1,93 @@ - - + + + - - + + + + - + - - - - - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - + + + + + + @@ -101,7 +97,25 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/Encode/encode/String+URLEncode.swift b/Encode/encode/String+URLEncode.swift index 2d9e9e2..45a1157 100644 --- a/Encode/encode/String+URLEncode.swift +++ b/Encode/encode/String+URLEncode.swift @@ -58,9 +58,9 @@ extension String { public func stringByAddingPercentEncodingForRFC3986() -> String? { let unreserved = "-._~/?" - let allowedCharacterSet = NSMutableCharacterSet.alphanumericCharacterSet() - allowedCharacterSet.addCharactersInString(unreserved) - return stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacterSet) + let allowedCharacterSet = NSMutableCharacterSet.alphanumeric() + allowedCharacterSet.addCharacters(in: unreserved) + return addingPercentEncoding(withAllowedCharacters: allowedCharacterSet as CharacterSet) } /** @@ -83,16 +83,16 @@ extension String { public func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? { let unreserved = "*-._" - let allowedCharacterSet = NSMutableCharacterSet.alphanumericCharacterSet() - allowedCharacterSet.addCharactersInString(unreserved) + let allowedCharacterSet = NSMutableCharacterSet.alphanumeric() + allowedCharacterSet.addCharacters(in: unreserved) if plusForSpace { - allowedCharacterSet.addCharactersInString(" ") + allowedCharacterSet.addCharacters(in: " ") } - var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacterSet) + var encoded = addingPercentEncoding(withAllowedCharacters: allowedCharacterSet as CharacterSet) if plusForSpace { - encoded = encoded?.stringByReplacingOccurrencesOfString(" ", withString: "+") + encoded = encoded?.replacingOccurrences(of: " ", with: "+") } return encoded } diff --git a/Encode/encode/ViewController.swift b/Encode/encode/ViewController.swift index 720ca8b..462c88c 100644 --- a/Encode/encode/ViewController.swift +++ b/Encode/encode/ViewController.swift @@ -2,8 +2,8 @@ // ViewController.swift // encode // -// Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2016 Keith Harrison. All rights reserved. +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2016-2020 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -46,14 +46,14 @@ class ViewController: UIViewController { func updateOutputLabels() { let input = textInput.text - let usePlusForSpace = plusSwitch.on + let usePlusForSpace = plusSwitch.isOn rfc3986Output.text = input?.stringByAddingPercentEncodingForRFC3986() - formOutput.text = input?.stringByAddingPercentEncodingForFormData(usePlusForSpace) + formOutput.text = input?.stringByAddingPercentEncodingForFormData(plusForSpace: usePlusForSpace) } } extension ViewController: UITextFieldDelegate { - func textFieldShouldReturn(textField: UITextField) -> Bool { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { updateOutputLabels() return true } diff --git a/Encode/encodeTests/String+URLEncodeTest.swift b/Encode/encodeTests/String+URLEncodeTest.swift index 4da757f..14af416 100644 --- a/Encode/encodeTests/String+URLEncodeTest.swift +++ b/Encode/encodeTests/String+URLEncodeTest.swift @@ -1,8 +1,8 @@ // // String+URLEncodeTest.swift // -// Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2016 Keith Harrison. All rights reserved. +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2016-2020 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -92,14 +92,14 @@ class URLEncodeTest: XCTestCase { func testFormSpacePlusEncoded() { let input = "one two" - let output = input.stringByAddingPercentEncodingForFormData(true) + let output = input.stringByAddingPercentEncodingForFormData(plusForSpace: true) let expected = "one+two" XCTAssertEqual(expected, output) } func testFormPlusIsPercentEncoded() { let input = "one+two" - let output = input.stringByAddingPercentEncodingForFormData(true) + let output = input.stringByAddingPercentEncodingForFormData(plusForSpace: true) let expected = "one%2Btwo" XCTAssertEqual(expected, output) } diff --git a/Encode/encodeUITests/encodeUITests.swift b/Encode/encodeUITests/encodeUITests.swift index 9a3a44a..8abdde3 100644 --- a/Encode/encodeUITests/encodeUITests.swift +++ b/Encode/encodeUITests/encodeUITests.swift @@ -2,8 +2,8 @@ // encodeUITests.swift // encodeUITests // -// Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2016 Keith Harrison. All rights reserved. +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2016-2020 Keith Harrison. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -63,7 +63,7 @@ class encodeUITests: XCTestCase { let input = "one two" let expectedRFC3986 = input.stringByAddingPercentEncodingForRFC3986() let expectedForm = input.stringByAddingPercentEncodingForFormData() - let expectedPlusForm = input.stringByAddingPercentEncodingForFormData(true) + let expectedPlusForm = input.stringByAddingPercentEncodingForFormData(plusForSpace: true) let textToEncodeTextField = app.textFields["InputText"] textToEncodeTextField.tap() diff --git a/GridView/GridView.xcodeproj/project.pbxproj b/GridView/GridView.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8324803 --- /dev/null +++ b/GridView/GridView.xcodeproj/project.pbxproj @@ -0,0 +1,480 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 531CCB8B1EAA45D2008349F4 /* GridViewUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 531CCB891EAA45D2008349F4 /* GridViewUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 531CCB8F1EAA475A008349F4 /* GridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5366BC771EA8E15E006A06E5 /* GridView.swift */; }; + 5366BC661EA8DF80006A06E5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5366BC651EA8DF80006A06E5 /* AppDelegate.swift */; }; + 5366BC6B1EA8DF80006A06E5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5366BC691EA8DF80006A06E5 /* Main.storyboard */; }; + 5366BC6D1EA8DF80006A06E5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5366BC6C1EA8DF80006A06E5 /* Assets.xcassets */; }; + 5366BC701EA8DF80006A06E5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5366BC6E1EA8DF80006A06E5 /* LaunchScreen.storyboard */; }; + 5366BC781EA8E15E006A06E5 /* GridView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5366BC771EA8E15E006A06E5 /* GridView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 531CCB871EAA45D2008349F4 /* GridViewUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = GridViewUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 531CCB891EAA45D2008349F4 /* GridViewUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GridViewUI.h; sourceTree = ""; }; + 531CCB8A1EAA45D2008349F4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5366BC621EA8DF80006A06E5 /* GridView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GridView.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5366BC651EA8DF80006A06E5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5366BC6A1EA8DF80006A06E5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5366BC6C1EA8DF80006A06E5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5366BC6F1EA8DF80006A06E5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5366BC711EA8DF80006A06E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5366BC771EA8E15E006A06E5 /* GridView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GridView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 531CCB831EAA45D2008349F4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5366BC5F1EA8DF80006A06E5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 531CCB881EAA45D2008349F4 /* GridViewUI */ = { + isa = PBXGroup; + children = ( + 531CCB891EAA45D2008349F4 /* GridViewUI.h */, + 531CCB8A1EAA45D2008349F4 /* Info.plist */, + ); + path = GridViewUI; + sourceTree = ""; + }; + 5366BC591EA8DF80006A06E5 = { + isa = PBXGroup; + children = ( + 5366BC641EA8DF80006A06E5 /* GridView */, + 531CCB881EAA45D2008349F4 /* GridViewUI */, + 5366BC631EA8DF80006A06E5 /* Products */, + ); + sourceTree = ""; + }; + 5366BC631EA8DF80006A06E5 /* Products */ = { + isa = PBXGroup; + children = ( + 5366BC621EA8DF80006A06E5 /* GridView.app */, + 531CCB871EAA45D2008349F4 /* GridViewUI.framework */, + ); + name = Products; + sourceTree = ""; + }; + 5366BC641EA8DF80006A06E5 /* GridView */ = { + isa = PBXGroup; + children = ( + 5366BC651EA8DF80006A06E5 /* AppDelegate.swift */, + 5366BC691EA8DF80006A06E5 /* Main.storyboard */, + 5366BC771EA8E15E006A06E5 /* GridView.swift */, + 5366BC6C1EA8DF80006A06E5 /* Assets.xcassets */, + 5366BC6E1EA8DF80006A06E5 /* LaunchScreen.storyboard */, + 5366BC711EA8DF80006A06E5 /* Info.plist */, + ); + path = GridView; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 531CCB841EAA45D2008349F4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 531CCB8B1EAA45D2008349F4 /* GridViewUI.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 531CCB861EAA45D2008349F4 /* GridViewUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 531CCB8E1EAA45D2008349F4 /* Build configuration list for PBXNativeTarget "GridViewUI" */; + buildPhases = ( + 531CCB821EAA45D2008349F4 /* Sources */, + 531CCB831EAA45D2008349F4 /* Frameworks */, + 531CCB841EAA45D2008349F4 /* Headers */, + 531CCB851EAA45D2008349F4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GridViewUI; + productName = GridViewUI; + productReference = 531CCB871EAA45D2008349F4 /* GridViewUI.framework */; + productType = "com.apple.product-type.framework"; + }; + 5366BC611EA8DF80006A06E5 /* GridView */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5366BC741EA8DF80006A06E5 /* Build configuration list for PBXNativeTarget "GridView" */; + buildPhases = ( + 5366BC5E1EA8DF80006A06E5 /* Sources */, + 5366BC5F1EA8DF80006A06E5 /* Frameworks */, + 5366BC601EA8DF80006A06E5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = GridView; + productName = GridView; + productReference = 5366BC621EA8DF80006A06E5 /* GridView.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5366BC5A1EA8DF80006A06E5 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 531CCB861EAA45D2008349F4 = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1120; + ProvisioningStyle = Automatic; + }; + 5366BC611EA8DF80006A06E5 = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1120; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5366BC5D1EA8DF80006A06E5 /* Build configuration list for PBXProject "GridView" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5366BC591EA8DF80006A06E5; + productRefGroup = 5366BC631EA8DF80006A06E5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5366BC611EA8DF80006A06E5 /* GridView */, + 531CCB861EAA45D2008349F4 /* GridViewUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 531CCB851EAA45D2008349F4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5366BC601EA8DF80006A06E5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5366BC701EA8DF80006A06E5 /* LaunchScreen.storyboard in Resources */, + 5366BC6D1EA8DF80006A06E5 /* Assets.xcassets in Resources */, + 5366BC6B1EA8DF80006A06E5 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 531CCB821EAA45D2008349F4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 531CCB8F1EAA475A008349F4 /* GridView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5366BC5E1EA8DF80006A06E5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5366BC781EA8E15E006A06E5 /* GridView.swift in Sources */, + 5366BC661EA8DF80006A06E5 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5366BC691EA8DF80006A06E5 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5366BC6A1EA8DF80006A06E5 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5366BC6E1EA8DF80006A06E5 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5366BC6F1EA8DF80006A06E5 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 531CCB8C1EAA45D2008349F4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = LCC2J94N44; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = GridViewUI/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.GridViewUI; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 531CCB8D1EAA45D2008349F4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = LCC2J94N44; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = GridViewUI/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.GridViewUI; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 5366BC721EA8DF80006A06E5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5366BC731EA8DF80006A06E5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5366BC751EA8DF80006A06E5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = GridView/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.GridView; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5366BC761EA8DF80006A06E5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = GridView/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.GridView; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 531CCB8E1EAA45D2008349F4 /* Build configuration list for PBXNativeTarget "GridViewUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 531CCB8C1EAA45D2008349F4 /* Debug */, + 531CCB8D1EAA45D2008349F4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5366BC5D1EA8DF80006A06E5 /* Build configuration list for PBXProject "GridView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5366BC721EA8DF80006A06E5 /* Debug */, + 5366BC731EA8DF80006A06E5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5366BC741EA8DF80006A06E5 /* Build configuration list for PBXNativeTarget "GridView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5366BC751EA8DF80006A06E5 /* Debug */, + 5366BC761EA8DF80006A06E5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5366BC5A1EA8DF80006A06E5 /* Project object */; +} diff --git a/GridView/GridView.xcworkspace/contents.xcworkspacedata b/GridView/GridView.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..8a969d2 --- /dev/null +++ b/GridView/GridView.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/GridView/GridView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/GridView/GridView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/GridView/GridView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/GridView/GridView/AppDelegate.swift b/GridView/GridView/AppDelegate.swift new file mode 100644 index 0000000..e757b1f --- /dev/null +++ b/GridView/GridView/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// GridView +// +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/GridView/GridView/Assets.xcassets/AppIcon.appiconset/Contents.json b/GridView/GridView/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/GridView/GridView/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GridView/GridView/Base.lproj/LaunchScreen.storyboard b/GridView/GridView/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..0295d5f --- /dev/null +++ b/GridView/GridView/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GridView/GridView/Base.lproj/Main.storyboard b/GridView/GridView/Base.lproj/Main.storyboard new file mode 100644 index 0000000..2bb0240 --- /dev/null +++ b/GridView/GridView/Base.lproj/Main.storyboard @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GridView/GridView/GridView.swift b/GridView/GridView/GridView.swift new file mode 100644 index 0000000..ad3349d --- /dev/null +++ b/GridView/GridView/GridView.swift @@ -0,0 +1,92 @@ +// GridView.swift +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +/// `GridView` is a custom `UIView` subclass that draws +/// a grid of evenly spaced lines in the bounds of the view. +/// Attention: You probably want to set the `contentMode` to `.redraw`. + +@IBDesignable +public class GridView: UIView { + /// The number of horizontal rows - default is 1. + @IBInspectable public var rowCount: Int = 1 { didSet { setNeedsDisplay() } } + + /// The number of vertical columns - default is 1. + @IBInspectable public var columnCount: Int = 1 { didSet { setNeedsDisplay() } } + + /// The grid line color - default is red. + @IBInspectable public var lineColor: UIColor = .red { didSet { setNeedsDisplay() } } + + /// The grid line width - default is 1 point. + @IBInspectable public var lineWidth: CGFloat = 1.0 { didSet { setNeedsDisplay() } } + + public override func draw(_ rect: CGRect) { + lineColor.set() + rowPath?.stroke() + columnPath?.stroke() + } + + private var rowPath: UIBezierPath? { + guard rowCount > 0 else { + return nil + } + + let rowPath = UIBezierPath() + rowPath.lineWidth = lineWidth + let rowHeight = bounds.size.height / CGFloat(rowCount + 1) + for row in 1...rowCount { + let y = rowHeight * CGFloat(row) + let startPoint = CGPoint(x: bounds.minX, y: y) + let endPoint = CGPoint(x: bounds.maxX, y: y) + rowPath.move(to: startPoint) + rowPath.addLine(to: endPoint) + } + return rowPath + } + + private var columnPath: UIBezierPath? { + guard columnCount > 0 else { + return nil + } + + let columnPath = UIBezierPath() + columnPath.lineWidth = lineWidth + let columnWidth = bounds.size.width / CGFloat(columnCount + 1) + for row in 1...columnCount { + let x = columnWidth * CGFloat(row) + let startPoint = CGPoint(x: x, y: bounds.minY) + let endPoint = CGPoint(x: x, y: bounds.maxY) + columnPath.move(to: startPoint) + columnPath.addLine(to: endPoint) + } + return columnPath + } +} diff --git a/GridView/GridView/Info.plist b/GridView/GridView/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/GridView/GridView/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/GridView/GridViewUI/GridViewUI.h b/GridView/GridViewUI/GridViewUI.h new file mode 100644 index 0000000..d02e371 --- /dev/null +++ b/GridView/GridViewUI/GridViewUI.h @@ -0,0 +1,19 @@ +// +// GridViewUI.h +// GridViewUI +// +// Created by Keith Harrison on 21/04/2017. +// Copyright © 2017 Keith Harrison. All rights reserved. +// + +#import + +//! Project version number for GridViewUI. +FOUNDATION_EXPORT double GridViewUIVersionNumber; + +//! Project version string for GridViewUI. +FOUNDATION_EXPORT const unsigned char GridViewUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/DynamicText/DynamicTextTests/DynamicTextTests-Info.plist b/GridView/GridViewUI/Info.plist similarity index 65% rename from DynamicText/DynamicTextTests/DynamicTextTests-Info.plist rename to GridView/GridViewUI/Info.plist index 6dd5353..fbe1e6b 100644 --- a/DynamicText/DynamicTextTests/DynamicTextTests-Info.plist +++ b/GridView/GridViewUI/Info.plist @@ -5,18 +5,20 @@ CFBundleDevelopmentRegion en CFBundleExecutable - ${EXECUTABLE_NAME} + $(EXECUTABLE_NAME) CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 + CFBundleName + $(PRODUCT_NAME) CFBundlePackageType - BNDL + FMWK CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + diff --git a/GridView/README.md b/GridView/README.md new file mode 100644 index 0000000..73c2a51 --- /dev/null +++ b/GridView/README.md @@ -0,0 +1,9 @@ +### Adding a Playground to an Xcode Project + +Example setup of a workspace containing a playground and project. The resources +in the project that need to be accessible from the playground are added to a +framework. + +See the following blog post for a step-by-step guide to creating this setup + ++ [Adding playgrounds to Xcode projects](https://useyourloaf.com/blog/adding-playgrounds-to-xcode-projects/) diff --git a/GridView/UIPlayground.playground/Contents.swift b/GridView/UIPlayground.playground/Contents.swift new file mode 100644 index 0000000..b9594ed --- /dev/null +++ b/GridView/UIPlayground.playground/Contents.swift @@ -0,0 +1,16 @@ +//: PlaygroundUI +import UIKit +import GridViewUI +import PlaygroundSupport + +//: Demo using the grid view +let grid = GridView() +grid.backgroundColor = .lightGray +grid.rowCount = 3 +grid.columnCount = 3 +grid.lineColor = .blue +grid.lineWidth = 5 + +//: Show in live view +grid.frame = CGRect(x: 0, y: 0, width: 200, height: 300) +PlaygroundPage.current.liveView = grid \ No newline at end of file diff --git a/Playgrounds/String.playground/contents.xcplayground b/GridView/UIPlayground.playground/contents.xcplayground similarity index 100% rename from Playgrounds/String.playground/contents.xcplayground rename to GridView/UIPlayground.playground/contents.xcplayground diff --git a/GridView/UIPlayground.playground/timeline.xctimeline b/GridView/UIPlayground.playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/GridView/UIPlayground.playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + + diff --git a/Huckleberry/Huckleberry.xcodeproj/project.pbxproj b/Huckleberry/Huckleberry.xcodeproj/project.pbxproj index 539e4c2..cb5ed1a 100644 --- a/Huckleberry/Huckleberry.xcodeproj/project.pbxproj +++ b/Huckleberry/Huckleberry.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ + 5325894623C911B9008ABE63 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5325894823C911B9008ABE63 /* LaunchScreen.storyboard */; }; 53512CFC18AC3A0300A74F57 /* UYLTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53512CFB18AC3A0300A74F57 /* UYLTableViewController.m */; }; 535C803818AD71750039A2B3 /* SourceData.plist in Resources */ = {isa = PBXBuildFile; fileRef = 535C803718AD71750039A2B3 /* SourceData.plist */; }; 5363F6D618AADBF6001CBD3A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5363F6D518AADBF6001CBD3A /* Foundation.framework */; }; @@ -21,10 +22,11 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5325894723C911B9008ABE63 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53512CFA18AC3A0300A74F57 /* UYLTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLTableViewController.h; sourceTree = ""; }; 53512CFB18AC3A0300A74F57 /* UYLTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLTableViewController.m; sourceTree = ""; }; 535C803718AD71750039A2B3 /* SourceData.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SourceData.plist; sourceTree = ""; }; - 535C803918AD8AE50039A2B3 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 536259D91F41DEFD00616356 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 5363F6D218AADBF6001CBD3A /* Huckleberry.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Huckleberry.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5363F6D518AADBF6001CBD3A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 5363F6D718AADBF6001CBD3A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -32,7 +34,6 @@ 5363F6DD18AADBF6001CBD3A /* Huckleberry-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Huckleberry-Info.plist"; sourceTree = ""; }; 5363F6DF18AADBF6001CBD3A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 5363F6E118AADBF6001CBD3A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 5363F6E318AADBF6001CBD3A /* Huckleberry-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Huckleberry-Prefix.pch"; sourceTree = ""; }; 5363F6E418AADBF6001CBD3A /* UYLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 5363F6E518AADBF6001CBD3A /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 5363F6E818AADBF6001CBD3A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -59,7 +60,7 @@ 5363F6C918AADBF6001CBD3A = { isa = PBXGroup; children = ( - 535C803918AD8AE50039A2B3 /* README */, + 536259D91F41DEFD00616356 /* README.md */, 5363F6DB18AADBF6001CBD3A /* Huckleberry */, 5363F6D418AADBF6001CBD3A /* Frameworks */, 5363F6D318AADBF6001CBD3A /* Products */, @@ -95,6 +96,7 @@ 53512CFA18AC3A0300A74F57 /* UYLTableViewController.h */, 53512CFB18AC3A0300A74F57 /* UYLTableViewController.m */, 5363F6E718AADBF6001CBD3A /* Main.storyboard */, + 5325894823C911B9008ABE63 /* LaunchScreen.storyboard */, 5363F6ED18AADBF6001CBD3A /* Images.xcassets */, 5363F6DC18AADBF6001CBD3A /* Supporting Files */, ); @@ -108,7 +110,6 @@ 5363F6DD18AADBF6001CBD3A /* Huckleberry-Info.plist */, 5363F6DE18AADBF6001CBD3A /* InfoPlist.strings */, 5363F6E118AADBF6001CBD3A /* main.m */, - 5363F6E318AADBF6001CBD3A /* Huckleberry-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; @@ -140,12 +141,12 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0510; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; }; buildConfigurationList = 5363F6CD18AADBF6001CBD3A /* Build configuration list for PBXProject "Huckleberry" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -169,6 +170,7 @@ 5363F6EE18AADBF6001CBD3A /* Images.xcassets in Resources */, 535C803818AD71750039A2B3 /* SourceData.plist in Resources */, 5363F6E018AADBF6001CBD3A /* InfoPlist.strings in Resources */, + 5325894623C911B9008ABE63 /* LaunchScreen.storyboard in Resources */, 5363F6E918AADBF6001CBD3A /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -190,6 +192,14 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + 5325894823C911B9008ABE63 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5325894723C911B9008ABE63 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; 5363F6DE18AADBF6001CBD3A /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -217,18 +227,32 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -241,7 +265,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -255,25 +279,38 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -283,10 +320,9 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Huckleberry/Huckleberry-Prefix.pch"; INFOPLIST_FILE = "Huckleberry/Huckleberry-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -296,10 +332,9 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Huckleberry/Huckleberry-Prefix.pch"; INFOPLIST_FILE = "Huckleberry/Huckleberry-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Huckleberry/Huckleberry/Base.lproj/LaunchScreen.storyboard b/Huckleberry/Huckleberry/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..867027e --- /dev/null +++ b/Huckleberry/Huckleberry/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Huckleberry/Huckleberry/Huckleberry-Info.plist b/Huckleberry/Huckleberry/Huckleberry-Info.plist index 79bd7f0..3f28fd9 100644 --- a/Huckleberry/Huckleberry/Huckleberry-Info.plist +++ b/Huckleberry/Huckleberry/Huckleberry-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +24,8 @@ 1.0 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities diff --git a/Huckleberry/Huckleberry/Huckleberry-Prefix.pch b/Huckleberry/Huckleberry/Huckleberry-Prefix.pch deleted file mode 100644 index 82a2bb4..0000000 --- a/Huckleberry/Huckleberry/Huckleberry-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header -// -// The contents of this file are implicitly included at the beginning of every source file. -// - -#import - -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/Huckleberry/Huckleberry/Images.xcassets/AppIcon.appiconset/Contents.json b/Huckleberry/Huckleberry/Images.xcassets/AppIcon.appiconset/Contents.json index a396706..19882d5 100644 --- a/Huckleberry/Huckleberry/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Huckleberry/Huckleberry/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,19 +1,49 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Huckleberry/Huckleberry/Images.xcassets/Contents.json b/Huckleberry/Huckleberry/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Huckleberry/Huckleberry/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Huckleberry/Huckleberry/Images.xcassets/LaunchImage.launchimage/Contents.json b/Huckleberry/Huckleberry/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index c79ebd3..0000000 --- a/Huckleberry/Huckleberry/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Huckleberry/README b/Huckleberry/README.md similarity index 52% rename from Huckleberry/README rename to Huckleberry/README.md index cfd4d93..cd6fab6 100644 --- a/Huckleberry/README +++ b/Huckleberry/README.md @@ -1,9 +1,8 @@ -======================================================================= -Huckleberry - Auto layout table view cells with varying row heights -Version 1.2 17 March 2014 Fix device rotation -Version 1.1 12 March 2014 Added Quick Look Debug -Version 1.0 14 February 2014 Initial version. -======================================================================= +# Huckleberry + +**This project is of historical interest only. I recommend using a self-sizing table view instead of the prototype cell approach used in this project.** + +## Auto layout table view cells with varying row heights Example of how to implement table view cells with varying row heights using auto layout constraints and a dummy prototype cell. @@ -17,10 +16,17 @@ of Huckleberry Finn as found on Project Gutenberg. This gives nearly 2000 rows of data. For further details see the following blog post: -http://useyourloaf.com/blog/2014/02/14/table-view-cells-with-varying-row-heights.html + ++ [Table View Cells with Varying Row Heights](https://useyourloaf.com/blog/table-view-cells-with-varying-row-heights/) The custom table view class (UYLTextCell) includes an implementation of debugQuickLookObject to support Quick Look view of the cell in the Xcode debugger (requires Xcode 5.1). See the following post for details: -http://useyourloaf.com/blog/2014/03/12/xcode-debugger-quick-look.html \ No newline at end of file ++ [Xcode Debugger Quick Look](https://useyourloaf.com/blog/xcode-debugger-quick-look/) + +## History + +Version 1.2 17 March 2014 Fix device rotation +Version 1.1 12 March 2014 Added Quick Look Debug +Version 1.0 14 February 2014 Initial version. diff --git a/KeyCommand/KeyCommand.xcodeproj/project.pbxproj b/KeyCommand/KeyCommand.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bef861b --- /dev/null +++ b/KeyCommand/KeyCommand.xcodeproj/project.pbxproj @@ -0,0 +1,527 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + 532005211DD516C300EEFEE6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 532005201DD516C300EEFEE6 /* main.m */; }; + 532005241DD516C300EEFEE6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 532005231DD516C300EEFEE6 /* AppDelegate.m */; }; + 532005361DD517AF00EEFEE6 /* OptionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 532005351DD517AF00EEFEE6 /* OptionViewController.m */; }; + 532005391DD517C000EEFEE6 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 532005381DD517C000EEFEE6 /* DetailViewController.m */; }; + 5320053C1DD518F900EEFEE6 /* UYLPriority.m in Sources */ = {isa = PBXBuildFile; fileRef = 5320053B1DD518F900EEFEE6 /* UYLPriority.m */; }; + 5334D07B1DD3B6250032CB00 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5334D07A1DD3B6250032CB00 /* AppDelegate.swift */; }; + 5334D0801DD3B6250032CB00 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5334D07E1DD3B6250032CB00 /* Main.storyboard */; }; + 5334D0821DD3B6250032CB00 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5334D0811DD3B6250032CB00 /* Assets.xcassets */; }; + 5334D0851DD3B6250032CB00 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5334D0831DD3B6250032CB00 /* LaunchScreen.storyboard */; }; + 5334D08D1DD3B82E0032CB00 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5334D08C1DD3B82E0032CB00 /* DetailViewController.swift */; }; + 5334D08F1DD3B8630032CB00 /* OptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5334D08E1DD3B8630032CB00 /* OptionViewController.swift */; }; + 5334D0911DD3BAC80032CB00 /* UYLPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5334D0901DD3BAC80032CB00 /* UYLPriority.swift */; }; + 5334D0931DD3BDAB0032CB00 /* SegueHandlerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5334D0921DD3BDAB0032CB00 /* SegueHandlerType.swift */; }; + 53376AB41DD77247002C287F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5334D0811DD3B6250032CB00 /* Assets.xcassets */; }; + 53376AB61DD772CB002C287F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5334D0831DD3B6250032CB00 /* LaunchScreen.storyboard */; }; + 53376AB81DD77736002C287F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 532005281DD516C300EEFEE6 /* Main.storyboard */; }; + 53376ABC1DD7789F002C287F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53376ABF1DD7789F002C287F /* Localizable.strings */; }; + 53376ABD1DD7789F002C287F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53376ABF1DD7789F002C287F /* Localizable.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 5320051D1DD516C300EEFEE6 /* KeyCommandObjC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeyCommandObjC.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 532005201DD516C300EEFEE6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 532005221DD516C300EEFEE6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 532005231DD516C300EEFEE6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 532005291DD516C300EEFEE6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 532005301DD516C300EEFEE6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 532005341DD517AF00EEFEE6 /* OptionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionViewController.h; sourceTree = ""; }; + 532005351DD517AF00EEFEE6 /* OptionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OptionViewController.m; sourceTree = ""; }; + 532005371DD517C000EEFEE6 /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; + 532005381DD517C000EEFEE6 /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; + 5320053A1DD518F900EEFEE6 /* UYLPriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLPriority.h; sourceTree = ""; }; + 5320053B1DD518F900EEFEE6 /* UYLPriority.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLPriority.m; sourceTree = ""; }; + 5334D0771DD3B6250032CB00 /* KeyCommand.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeyCommand.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5334D07A1DD3B6250032CB00 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5334D07F1DD3B6250032CB00 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5334D0811DD3B6250032CB00 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = KeyCommand/Assets.xcassets; sourceTree = ""; }; + 5334D0841DD3B6250032CB00 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5334D0861DD3B6250032CB00 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5334D08C1DD3B82E0032CB00 /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; + 5334D08E1DD3B8630032CB00 /* OptionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionViewController.swift; sourceTree = ""; }; + 5334D0901DD3BAC80032CB00 /* UYLPriority.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UYLPriority.swift; sourceTree = ""; }; + 5334D0921DD3BDAB0032CB00 /* SegueHandlerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SegueHandlerType.swift; sourceTree = ""; }; + 53376ABE1DD7789F002C287F /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + 53376AC01DD77B74002C287F /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5320051A1DD516C300EEFEE6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5334D0741DD3B6250032CB00 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5320051E1DD516C300EEFEE6 /* KeyCommandObjC */ = { + isa = PBXGroup; + children = ( + 532005221DD516C300EEFEE6 /* AppDelegate.h */, + 532005231DD516C300EEFEE6 /* AppDelegate.m */, + 532005341DD517AF00EEFEE6 /* OptionViewController.h */, + 532005351DD517AF00EEFEE6 /* OptionViewController.m */, + 532005371DD517C000EEFEE6 /* DetailViewController.h */, + 532005381DD517C000EEFEE6 /* DetailViewController.m */, + 5320053A1DD518F900EEFEE6 /* UYLPriority.h */, + 5320053B1DD518F900EEFEE6 /* UYLPriority.m */, + 532005281DD516C300EEFEE6 /* Main.storyboard */, + 532005301DD516C300EEFEE6 /* Info.plist */, + 5320051F1DD516C300EEFEE6 /* Supporting Files */, + ); + path = KeyCommandObjC; + sourceTree = ""; + }; + 5320051F1DD516C300EEFEE6 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 532005201DD516C300EEFEE6 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5334D06E1DD3B6250032CB00 = { + isa = PBXGroup; + children = ( + 53376AC01DD77B74002C287F /* README.md */, + 53376AB51DD77255002C287F /* Shared Resources */, + 5334D0791DD3B6250032CB00 /* KeyCommand */, + 5320051E1DD516C300EEFEE6 /* KeyCommandObjC */, + 5334D0781DD3B6250032CB00 /* Products */, + ); + sourceTree = ""; + }; + 5334D0781DD3B6250032CB00 /* Products */ = { + isa = PBXGroup; + children = ( + 5334D0771DD3B6250032CB00 /* KeyCommand.app */, + 5320051D1DD516C300EEFEE6 /* KeyCommandObjC.app */, + ); + name = Products; + sourceTree = ""; + }; + 5334D0791DD3B6250032CB00 /* KeyCommand */ = { + isa = PBXGroup; + children = ( + 5334D08E1DD3B8630032CB00 /* OptionViewController.swift */, + 5334D08C1DD3B82E0032CB00 /* DetailViewController.swift */, + 5334D07A1DD3B6250032CB00 /* AppDelegate.swift */, + 5334D07E1DD3B6250032CB00 /* Main.storyboard */, + 5334D0861DD3B6250032CB00 /* Info.plist */, + 5334D0901DD3BAC80032CB00 /* UYLPriority.swift */, + 5334D0921DD3BDAB0032CB00 /* SegueHandlerType.swift */, + ); + path = KeyCommand; + sourceTree = ""; + }; + 53376AB51DD77255002C287F /* Shared Resources */ = { + isa = PBXGroup; + children = ( + 5334D0811DD3B6250032CB00 /* Assets.xcassets */, + 5334D0831DD3B6250032CB00 /* LaunchScreen.storyboard */, + 53376ABF1DD7789F002C287F /* Localizable.strings */, + ); + name = "Shared Resources"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5320051C1DD516C300EEFEE6 /* KeyCommandObjC */ = { + isa = PBXNativeTarget; + buildConfigurationList = 532005331DD516C300EEFEE6 /* Build configuration list for PBXNativeTarget "KeyCommandObjC" */; + buildPhases = ( + 532005191DD516C300EEFEE6 /* Sources */, + 5320051A1DD516C300EEFEE6 /* Frameworks */, + 5320051B1DD516C300EEFEE6 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KeyCommandObjC; + productName = KeyCommandObjC; + productReference = 5320051D1DD516C300EEFEE6 /* KeyCommandObjC.app */; + productType = "com.apple.product-type.application"; + }; + 5334D0761DD3B6250032CB00 /* KeyCommand */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5334D0891DD3B6250032CB00 /* Build configuration list for PBXNativeTarget "KeyCommand" */; + buildPhases = ( + 5334D0731DD3B6250032CB00 /* Sources */, + 5334D0741DD3B6250032CB00 /* Frameworks */, + 5334D0751DD3B6250032CB00 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KeyCommand; + productName = KeyCommand; + productReference = 5334D0771DD3B6250032CB00 /* KeyCommand.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5334D06F1DD3B6250032CB00 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0810; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 5320051C1DD516C300EEFEE6 = { + CreatedOnToolsVersion = 8.1; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + 5334D0761DD3B6250032CB00 = { + CreatedOnToolsVersion = 8.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1120; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5334D0721DD3B6250032CB00 /* Build configuration list for PBXProject "KeyCommand" */; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5334D06E1DD3B6250032CB00; + productRefGroup = 5334D0781DD3B6250032CB00 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5334D0761DD3B6250032CB00 /* KeyCommand */, + 5320051C1DD516C300EEFEE6 /* KeyCommandObjC */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5320051B1DD516C300EEFEE6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53376AB81DD77736002C287F /* Main.storyboard in Resources */, + 53376ABD1DD7789F002C287F /* Localizable.strings in Resources */, + 53376AB61DD772CB002C287F /* LaunchScreen.storyboard in Resources */, + 53376AB41DD77247002C287F /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5334D0751DD3B6250032CB00 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5334D0851DD3B6250032CB00 /* LaunchScreen.storyboard in Resources */, + 53376ABC1DD7789F002C287F /* Localizable.strings in Resources */, + 5334D0821DD3B6250032CB00 /* Assets.xcassets in Resources */, + 5334D0801DD3B6250032CB00 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 532005191DD516C300EEFEE6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 532005361DD517AF00EEFEE6 /* OptionViewController.m in Sources */, + 5320053C1DD518F900EEFEE6 /* UYLPriority.m in Sources */, + 532005241DD516C300EEFEE6 /* AppDelegate.m in Sources */, + 532005211DD516C300EEFEE6 /* main.m in Sources */, + 532005391DD517C000EEFEE6 /* DetailViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5334D0731DD3B6250032CB00 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5334D07B1DD3B6250032CB00 /* AppDelegate.swift in Sources */, + 5334D0911DD3BAC80032CB00 /* UYLPriority.swift in Sources */, + 5334D08D1DD3B82E0032CB00 /* DetailViewController.swift in Sources */, + 5334D0931DD3BDAB0032CB00 /* SegueHandlerType.swift in Sources */, + 5334D08F1DD3B8630032CB00 /* OptionViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 532005281DD516C300EEFEE6 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 532005291DD516C300EEFEE6 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5334D07E1DD3B6250032CB00 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5334D07F1DD3B6250032CB00 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5334D0831DD3B6250032CB00 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5334D0841DD3B6250032CB00 /* Base */, + ); + name = LaunchScreen.storyboard; + path = KeyCommand; + sourceTree = ""; + }; + 53376ABF1DD7789F002C287F /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 53376ABE1DD7789F002C287F /* Base */, + ); + name = Localizable.strings; + path = KeyCommand; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 532005311DD516C300EEFEE6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = KeyCommandObjC/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.KeyCommandObjC; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 532005321DD516C300EEFEE6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = KeyCommandObjC/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.KeyCommandObjC; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 5334D0871DD3B6250032CB00 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Debug; + }; + 5334D0881DD3B6250032CB00 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = 2; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5334D08A1DD3B6250032CB00 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = KeyCommand/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.2; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.KeyCommand; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 5334D08B1DD3B6250032CB00 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = KeyCommand/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.2; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.KeyCommand; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 532005331DD516C300EEFEE6 /* Build configuration list for PBXNativeTarget "KeyCommandObjC" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 532005311DD516C300EEFEE6 /* Debug */, + 532005321DD516C300EEFEE6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5334D0721DD3B6250032CB00 /* Build configuration list for PBXProject "KeyCommand" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5334D0871DD3B6250032CB00 /* Debug */, + 5334D0881DD3B6250032CB00 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5334D0891DD3B6250032CB00 /* Build configuration list for PBXNativeTarget "KeyCommand" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5334D08A1DD3B6250032CB00 /* Debug */, + 5334D08B1DD3B6250032CB00 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5334D06F1DD3B6250032CB00 /* Project object */; +} diff --git a/KeyCommand/KeyCommand/AppDelegate.swift b/KeyCommand/KeyCommand/AppDelegate.swift new file mode 100644 index 0000000..f665964 --- /dev/null +++ b/KeyCommand/KeyCommand/AppDelegate.swift @@ -0,0 +1,40 @@ +// +// AppDelegate.swift +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} + diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/Contents.json b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..4590729 --- /dev/null +++ b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "cmd20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "cmd40-1.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "cmd29.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "cmd58.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "cmd40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "cmd80.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "cmd76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "cmd152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "cmd167.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "cmd1024.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd1024.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd1024.png new file mode 100644 index 0000000..1b94956 Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd1024.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd152.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd152.png new file mode 100644 index 0000000..e191ab0 Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd152.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd167.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd167.png new file mode 100644 index 0000000..82d08f8 Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd167.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd20.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd20.png new file mode 100644 index 0000000..81d0307 Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd20.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd29.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd29.png new file mode 100644 index 0000000..bf52f66 Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd29.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd40-1.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd40-1.png new file mode 100644 index 0000000..b24189c Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd40-1.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd40.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd40.png new file mode 100644 index 0000000..b24189c Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd40.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd58.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd58.png new file mode 100644 index 0000000..5ecbf1d Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd58.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd76.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd76.png new file mode 100644 index 0000000..1cc5239 Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd76.png differ diff --git a/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd80.png b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd80.png new file mode 100644 index 0000000..df540ac Binary files /dev/null and b/KeyCommand/KeyCommand/Assets.xcassets/AppIcon.appiconset/cmd80.png differ diff --git a/KeyCommand/KeyCommand/Base.lproj/LaunchScreen.storyboard b/KeyCommand/KeyCommand/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..48cf7b7 --- /dev/null +++ b/KeyCommand/KeyCommand/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeyCommand/KeyCommand/Base.lproj/Localizable.strings b/KeyCommand/KeyCommand/Base.lproj/Localizable.strings new file mode 100644 index 0000000..05a6c0a --- /dev/null +++ b/KeyCommand/KeyCommand/Base.lproj/Localizable.strings @@ -0,0 +1,43 @@ +// +// Localizable.strings +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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. + +"LowPriority" = "Low priority"; +"MediumPriority" = "Medium priority"; +"HighPriority" = "High priority"; + +"CloseWindow" = "Close window"; + +"none" = "None"; +"low" = "Low"; +"medium" = "Medium"; +"high" = "High"; diff --git a/KeyCommand/KeyCommand/Base.lproj/Main.storyboard b/KeyCommand/KeyCommand/Base.lproj/Main.storyboard new file mode 100644 index 0000000..8d88e33 --- /dev/null +++ b/KeyCommand/KeyCommand/Base.lproj/Main.storyboard @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeyCommand/KeyCommand/DetailViewController.swift b/KeyCommand/KeyCommand/DetailViewController.swift new file mode 100644 index 0000000..1caece9 --- /dev/null +++ b/KeyCommand/KeyCommand/DetailViewController.swift @@ -0,0 +1,69 @@ +// +// DetailViewController.swift +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class DetailViewController: UIViewController { + var priority = UYLPriority.none { + didSet { + configureView() + } + } + + override var keyCommands: [UIKeyCommand]? { + return [ + UIKeyCommand(input: UIKeyCommand.inputEscape, + modifierFlags: [], + action: #selector(DetailViewController.dismissAction), + discoverabilityTitle: NSLocalizedString("CloseWindow", comment: "Close window")) + ] + } + + override var canBecomeFirstResponder: Bool { + return true + } + + @IBAction func dismissAction() { + dismiss(animated: true, completion: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + configureView() + } + + private func configureView() { + title = priority.label() + view.backgroundColor = priority.color() + } +} diff --git a/KeyCommand/KeyCommand/Info.plist b/KeyCommand/KeyCommand/Info.plist new file mode 100644 index 0000000..5e08258 --- /dev/null +++ b/KeyCommand/KeyCommand/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/KeyCommand/KeyCommand/OptionViewController.swift b/KeyCommand/KeyCommand/OptionViewController.swift new file mode 100644 index 0000000..6e2df84 --- /dev/null +++ b/KeyCommand/KeyCommand/OptionViewController.swift @@ -0,0 +1,123 @@ +// +// OptionViewController.swift +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class OptionViewController: UIViewController { + private enum InputKey: String { + case low = "1" + case medium = "2" + case high = "3" + } + + // Override keyCommands and return the three + // key commands for this view controller. + + override var keyCommands: [UIKeyCommand]? { + return [ + UIKeyCommand(input: InputKey.low.rawValue, + modifierFlags: .command, + action: #selector(OptionViewController.performCommand(sender:)), + discoverabilityTitle: NSLocalizedString("LowPriority", comment: "Low priority")), + + UIKeyCommand(input: InputKey.medium.rawValue, + modifierFlags: .command, + action: #selector(OptionViewController.performCommand(sender:)), + discoverabilityTitle: NSLocalizedString("MediumPriority", comment: "Medium priority")), + + UIKeyCommand(input: InputKey.high.rawValue, + modifierFlags: .command, + action: #selector(OptionViewController.performCommand(sender:)), + discoverabilityTitle: NSLocalizedString("HighPriority", comment: "High priority")) + ] + } + + @objc func performCommand(sender: UIKeyCommand) { + guard let key = InputKey(rawValue: sender.input!) else { + return + } + switch key { + case .low: performSegue(withIdentifier: .low, sender: self) + case .medium: performSegue(withIdentifier: .medium, sender: self) + case .high: performSegue(withIdentifier: .high, sender: self) + } + } + + // You can also add key commands without overriding the + // keyCommands property. For example you could call the + // following function from viewDidLoad: + +// private func setupCommands() { +// let lowCommand = UIKeyCommand(input: InputKey.low.rawValue, +// modifierFlags: .command, +// action: #selector(OptionViewController.performCommand(sender:)), +// discoverabilityTitle: NSLocalizedString("LowPriority", comment: "Low priority")) +// addKeyCommand(lowCommand) +// +// let mediumCommand = UIKeyCommand(input: InputKey.medium.rawValue, +// modifierFlags: .command, +// action: #selector(OptionViewController.performCommand(sender:)), +// discoverabilityTitle: NSLocalizedString("MediumPriority", comment: "Medium priority")) +// addKeyCommand(mediumCommand) +// +// let highCommand = UIKeyCommand(input: InputKey.high.rawValue, +// modifierFlags: .command, +// action: #selector(OptionViewController.performCommand(sender:)), +// discoverabilityTitle: NSLocalizedString("HighPriority", comment: "High priority")) +// addKeyCommand(highCommand) +// } +} + +extension OptionViewController: SegueHandlerType { + enum SegueIdentifier: String { + case low + case medium + case high + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + guard let navController = segue.destination as? UINavigationController, + let viewController = navController.topViewController as? DetailViewController else { + fatalError("Expected embedded DetailViewController") + } + + switch segueIdentifierForSegue(segue: segue) { + case .low: + viewController.priority = .low + case .medium: + viewController.priority = .medium + case .high: + viewController.priority = .high + } + } +} diff --git a/KeyCommand/KeyCommand/SegueHandlerType.swift b/KeyCommand/KeyCommand/SegueHandlerType.swift new file mode 100644 index 0000000..26f1f97 --- /dev/null +++ b/KeyCommand/KeyCommand/SegueHandlerType.swift @@ -0,0 +1,51 @@ +// +// SegueHandlerType.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol SegueHandlerType { + associatedtype SegueIdentifier: RawRepresentable +} + +extension SegueHandlerType where Self: UIViewController, SegueIdentifier.RawValue == String { + func performSegue(withIdentifier segueIdentifier: SegueIdentifier, sender: AnyObject?) { + performSegue(withIdentifier: segueIdentifier.rawValue, sender: sender) + } + + func segueIdentifierForSegue(segue: UIStoryboardSegue) -> SegueIdentifier { + guard let identifier = segue.identifier, + let segueIdentifier = SegueIdentifier(rawValue: identifier) else { + fatalError("Unknown Segue Identifier \(segue.identifier ?? "Missing")") + } + return segueIdentifier + } +} diff --git a/KeyCommand/KeyCommand/UYLPriority.swift b/KeyCommand/KeyCommand/UYLPriority.swift new file mode 100644 index 0000000..67e2eae --- /dev/null +++ b/KeyCommand/KeyCommand/UYLPriority.swift @@ -0,0 +1,54 @@ +// +// UYLOption.swift +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +enum UYLPriority: String { + case none + case low + case medium + case high + + func label() -> String { + return NSLocalizedString(self.rawValue, comment: "Priority") + } + + func color() -> UIColor { + switch self { + case .none: return .white + case .low: return .green + case .medium: return .yellow + case .high: return .red + } + } +} diff --git a/KeyCommand/KeyCommandObjC/AppDelegate.h b/KeyCommand/KeyCommandObjC/AppDelegate.h new file mode 100644 index 0000000..99bf474 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/AppDelegate.h @@ -0,0 +1,43 @@ +// +// AppDelegate.h +// KeyCommandObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/KeyCommand/KeyCommandObjC/AppDelegate.m b/KeyCommand/KeyCommandObjC/AppDelegate.m new file mode 100644 index 0000000..b329e8f --- /dev/null +++ b/KeyCommand/KeyCommandObjC/AppDelegate.m @@ -0,0 +1,37 @@ +// +// AppDelegate.m +// KeyCommandObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/KeyCommand/KeyCommandObjC/Base.lproj/Main.storyboard b/KeyCommand/KeyCommandObjC/Base.lproj/Main.storyboard new file mode 100644 index 0000000..8fecc05 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/Base.lproj/Main.storyboard @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeyCommand/KeyCommandObjC/DetailViewController.h b/KeyCommand/KeyCommandObjC/DetailViewController.h new file mode 100644 index 0000000..b1c85da --- /dev/null +++ b/KeyCommand/KeyCommandObjC/DetailViewController.h @@ -0,0 +1,40 @@ +// +// DetailViewController.h +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +#import "UYLPriority.h" + +@interface DetailViewController : UIViewController +@property (nonatomic,assign) UYLPriorityLevel priority; +@end diff --git a/KeyCommand/KeyCommandObjC/DetailViewController.m b/KeyCommand/KeyCommandObjC/DetailViewController.m new file mode 100644 index 0000000..e8bee98 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/DetailViewController.m @@ -0,0 +1,71 @@ +// +// DetailViewController.m +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "DetailViewController.h" +#import "UYLPriority.h" + +@implementation DetailViewController + +- (NSArray *)keyCommands { + return @[ + [UIKeyCommand keyCommandWithInput:UIKeyInputEscape + modifierFlags:0 + action:@selector(dismissAction) + discoverabilityTitle:NSLocalizedString(@"CloseWindow", @"Close window")] + ]; +} + +- (BOOL)canBecomeFirstResponder { + return YES; +} + +- (void)setPriority:(UYLPriorityLevel)priority { + _priority = priority; + [self configureView]; +} + +- (IBAction)dismissAction { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self configureView]; +} + +- (void)configureView { + self.title = [UYLPriority labelForPriorityLevel:self.priority]; + self.view.backgroundColor = [UYLPriority colorForPriorityLevel:self.priority]; +} + +@end diff --git a/KeyCommand/KeyCommandObjC/Info.plist b/KeyCommand/KeyCommandObjC/Info.plist new file mode 100644 index 0000000..cf92535 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.1 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/KeyCommand/KeyCommandObjC/OptionViewController.h b/KeyCommand/KeyCommandObjC/OptionViewController.h new file mode 100644 index 0000000..525c775 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/OptionViewController.h @@ -0,0 +1,39 @@ +// +// OptionViewController.h +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface OptionViewController : UIViewController + +@end diff --git a/KeyCommand/KeyCommandObjC/OptionViewController.m b/KeyCommand/KeyCommandObjC/OptionViewController.m new file mode 100644 index 0000000..24857e5 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/OptionViewController.m @@ -0,0 +1,109 @@ +// +// OptionViewController.m +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "OptionViewController.h" +#import "DetailViewController.h" +#import "UYLPriority.h" + +@implementation OptionViewController + +// Override keyCommands and return the three +// key commands for this view controller. + +static NSString *inputKeyLow = @"1"; +static NSString *inputKeyMedium = @"2"; +static NSString *inputKeyHigh = @"3"; + +- (NSArray *)keyCommands { + return @[ + [UIKeyCommand keyCommandWithInput:inputKeyLow + modifierFlags:UIKeyModifierCommand + action:@selector(performCommand:) + discoverabilityTitle:NSLocalizedString(@"LowPriority", @"Low priority")], + [UIKeyCommand keyCommandWithInput:inputKeyMedium + modifierFlags:UIKeyModifierCommand + action:@selector(performCommand:) + discoverabilityTitle:NSLocalizedString(@"MediumPriority", @"Medium priority")], + [UIKeyCommand keyCommandWithInput:inputKeyHigh + modifierFlags:UIKeyModifierCommand + action:@selector(performCommand:) + discoverabilityTitle:NSLocalizedString(@"HighPriority", @"High priority")] + ]; +} + +- (void)performCommand:(UIKeyCommand *)sender { + NSString *key = sender.input; + if ([key isEqualToString:inputKeyLow]) { + [self performSegueWithIdentifier:UYLPriorityIdentifierLow sender:self]; + } else if ([key isEqualToString:inputKeyMedium]) { + [self performSegueWithIdentifier:UYLPriorityIdentifierMedium sender:self]; + } else if ([key isEqualToString:inputKeyHigh]) { + [self performSegueWithIdentifier:UYLPriorityIdentifierHigh sender:self]; + } +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + + if ([segue.destinationViewController isKindOfClass:[UINavigationController class]]) { + UINavigationController *navController = segue.destinationViewController; + + if ([navController.topViewController isKindOfClass:[DetailViewController class]]) { + DetailViewController *viewController = (DetailViewController *)navController.topViewController; + viewController.priority = [UYLPriority priorityLevelForIdentifier:segue.identifier]; + } + } +} + +// You can also add key commands without overriding the +// keyCommands property. For example you could call the +// following function from viewDidLoad: + +//- (void)setupCommands { +// UIKeyCommand *lowCommand = [UIKeyCommand keyCommandWithInput:inputKeyLow +// modifierFlags:UIKeyModifierCommand +// action:@selector(performCommand:) +// discoverabilityTitle:NSLocalizedString(@"LowPriority", @"Low priority")]; +// [self addKeyCommand:lowCommand]; +// +// UIKeyCommand *mediumCommand = [UIKeyCommand keyCommandWithInput:inputKeyMedium +// modifierFlags:UIKeyModifierCommand +// action:@selector(performCommand:) discoverabilityTitle:NSLocalizedString(@"MediumPriority", @"Medium priority")]; +// [self addKeyCommand:mediumCommand]; +// +// UIKeyCommand *highCommand = [UIKeyCommand keyCommandWithInput:inputKeyHigh +// modifierFlags:UIKeyModifierCommand +// action:@selector(performCommand:) discoverabilityTitle:NSLocalizedString(@"HighPriority", @"High priority")]; +// [self addKeyCommand:highCommand]; +//} + +@end diff --git a/KeyCommand/KeyCommandObjC/UYLPriority.h b/KeyCommand/KeyCommandObjC/UYLPriority.h new file mode 100644 index 0000000..2c568d8 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/UYLPriority.h @@ -0,0 +1,55 @@ +// +// UYLPriority.h +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +typedef NS_ENUM(NSInteger, UYLPriorityLevel) { + UYLPriorityNone, + UYLPriorityLow, + UYLPriorityMedium, + UYLPriorityHigh +}; + +@interface UYLPriority : NSObject + +extern NSString *UYLPriorityIdentifierNone; +extern NSString *UYLPriorityIdentifierLow; +extern NSString *UYLPriorityIdentifierMedium; +extern NSString *UYLPriorityIdentifierHigh; + ++ (NSString *)labelForPriorityLevel:(UYLPriorityLevel)level; ++ (UYLPriorityLevel)priorityLevelForIdentifier:(NSString *)identifier; ++ (UIColor *)colorForPriorityLevel:(UYLPriorityLevel)level; + +@end diff --git a/KeyCommand/KeyCommandObjC/UYLPriority.m b/KeyCommand/KeyCommandObjC/UYLPriority.m new file mode 100644 index 0000000..fd94ba3 --- /dev/null +++ b/KeyCommand/KeyCommandObjC/UYLPriority.m @@ -0,0 +1,80 @@ +// +// UYLPriority.m +// KeyCommand +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "UYLPriority.h" + +@implementation UYLPriority + +NSString *UYLPriorityIdentifierNone = @"none"; +NSString *UYLPriorityIdentifierLow = @"low"; +NSString *UYLPriorityIdentifierMedium = @"medium"; +NSString *UYLPriorityIdentifierHigh = @"high"; + ++ (NSString *)labelForPriorityLevel:(UYLPriorityLevel)level { + + switch (level) { + case UYLPriorityNone: + return NSLocalizedString(UYLPriorityIdentifierNone, @"No Priority"); + case UYLPriorityLow: + return NSLocalizedString(UYLPriorityIdentifierLow, @"Low Priority"); + case UYLPriorityMedium: + return NSLocalizedString(UYLPriorityIdentifierMedium, @"Medium Priority"); + case UYLPriorityHigh: + return NSLocalizedString(UYLPriorityIdentifierHigh, @"High Priority"); + } +} + ++ (UYLPriorityLevel)priorityLevelForIdentifier:(NSString *)identifier { + if ([identifier isEqualToString:UYLPriorityIdentifierLow]) { + return UYLPriorityLow; + } + if ([identifier isEqualToString:UYLPriorityIdentifierMedium]) { + return UYLPriorityMedium; + } + if ([identifier isEqualToString:UYLPriorityIdentifierHigh]) { + return UYLPriorityHigh; + } + return UYLPriorityNone; +} + ++ (UIColor *)colorForPriorityLevel:(UYLPriorityLevel)level { + + switch (level) { + case UYLPriorityNone: return UIColor.whiteColor; + case UYLPriorityLow: return UIColor.greenColor; + case UYLPriorityMedium: return UIColor.yellowColor; + case UYLPriorityHigh: return UIColor.redColor; + } +} + +@end diff --git a/KeyCommand/KeyCommandObjC/main.m b/KeyCommand/KeyCommandObjC/main.m new file mode 100644 index 0000000..b91692d --- /dev/null +++ b/KeyCommand/KeyCommandObjC/main.m @@ -0,0 +1,41 @@ +// +// main.m +// KeyCommandObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/KeyCommand/README.md b/KeyCommand/README.md new file mode 100644 index 0000000..fea205c --- /dev/null +++ b/KeyCommand/README.md @@ -0,0 +1,16 @@ +### Adding Hardware Keyboard Shortcuts + +An example showing how to add hardware keyboard shortcuts to an +App by overriding the `keyCommands` property of a view controller. + +This Xcode project contains both Swift and Objective-C targets. + +See the following blog post for further details: + ++ [Adding Hardware Keyboard Support](https://useyourloaf.com/blog/adding-hardware-keyboard-shortcuts/) + +#### Version History + ++ Version 1.2 01 Jan 2020 Updated for Xcode 11 ++ Version 1.1 26 Oct 2017 Updated for Xcode 9 and Swift 4 ++ Version 1.0 12 Nov 2016 Initial Version diff --git a/Margins/Margins.playground/Contents.swift b/Margins/Margins.playground/Contents.swift new file mode 100644 index 0000000..330e633 --- /dev/null +++ b/Margins/Margins.playground/Contents.swift @@ -0,0 +1,14 @@ +import UIKit +import PlaygroundSupport + +let viewController = MarginViewController() +viewController.view.backgroundColor = .white +viewController.view.frame = CGRect(x: 0, y: 0, width: 320, height: 640) +PlaygroundPage.current.liveView = viewController.view + +viewController.redView.preservesSuperviewLayoutMargins = true + +viewController.stackView.preservesSuperviewLayoutMargins = true +viewController.stackView.isLayoutMarginsRelativeArrangement = true + +viewController.stackView.layoutMargins = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) diff --git a/Margins/Margins.playground/Sources/MarginViewController.swift b/Margins/Margins.playground/Sources/MarginViewController.swift new file mode 100644 index 0000000..892fbba --- /dev/null +++ b/Margins/Margins.playground/Sources/MarginViewController.swift @@ -0,0 +1,95 @@ +// +// MarginViewController.swift +// Margins +// +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +public class MarginViewController: UIViewController { + + override public func viewDidLoad() { + super.viewDidLoad() + setupViews() + } + + public lazy var redView: UIView = { + return self.simpleView(color: .red) + }() + + public lazy var stackView: UIStackView = { + return UIStackView() + }() + + private func setupViews() { + view.addSubview(redView) + NSLayoutConstraint.activate([ + redView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + redView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + redView.trailingAnchor.constraint(equalTo: view.trailingAnchor) + ]) + + let yellowView = simpleView(color: .yellow) + redView.addSubview(yellowView) + let redMargins = redView.layoutMarginsGuide + NSLayoutConstraint.activate([ + yellowView.leadingAnchor.constraint(equalTo: redMargins.leadingAnchor), + yellowView.trailingAnchor.constraint(equalTo: redMargins.trailingAnchor), + yellowView.topAnchor.constraint(equalTo: redMargins.topAnchor), + yellowView.bottomAnchor.constraint(equalTo: redMargins.bottomAnchor) + ]) + + let blueView = simpleView(color: .blue) + stackView.addArrangedSubview(blueView) + let greenView = simpleView(color: .green) + stackView.addArrangedSubview(greenView) + stackView.spacing = 8.0 + stackView.distribution = .fillEqually + stackView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(stackView) + + NSLayoutConstraint.activate([ + stackView.topAnchor.constraint(equalTo: redView.bottomAnchor), + stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + + stackView.heightAnchor.constraint(equalTo: redView.heightAnchor) + ]) + } + + private func simpleView(color: UIColor) -> UIView { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = color + return view + } +} + diff --git a/Margins/Margins.playground/contents.xcplayground b/Margins/Margins.playground/contents.xcplayground new file mode 100644 index 0000000..5da2641 --- /dev/null +++ b/Margins/Margins.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Margins/Margins.playground/timeline.xctimeline b/Margins/Margins.playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/Margins/Margins.playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + + diff --git a/Margins/Margins.xcodeproj/project.pbxproj b/Margins/Margins.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d330e67 --- /dev/null +++ b/Margins/Margins.xcodeproj/project.pbxproj @@ -0,0 +1,328 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 53E307761EB33A650055FFCB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E307751EB33A650055FFCB /* AppDelegate.swift */; }; + 53E3077B1EB33A650055FFCB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53E307791EB33A650055FFCB /* Main.storyboard */; }; + 53E3077D1EB33A650055FFCB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53E3077C1EB33A650055FFCB /* Assets.xcassets */; }; + 53E307801EB33A650055FFCB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53E3077E1EB33A650055FFCB /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53E307721EB33A650055FFCB /* Margins.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Margins.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53E307751EB33A650055FFCB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53E3077A1EB33A650055FFCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53E3077C1EB33A650055FFCB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53E3077F1EB33A650055FFCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53E307811EB33A650055FFCB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53FE21E91EB7487400DAC6C2 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53E3076F1EB33A650055FFCB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53E307691EB33A650055FFCB = { + isa = PBXGroup; + children = ( + 53FE21E91EB7487400DAC6C2 /* README.md */, + 53E307741EB33A650055FFCB /* Margins */, + 53E307731EB33A650055FFCB /* Products */, + ); + sourceTree = ""; + }; + 53E307731EB33A650055FFCB /* Products */ = { + isa = PBXGroup; + children = ( + 53E307721EB33A650055FFCB /* Margins.app */, + ); + name = Products; + sourceTree = ""; + }; + 53E307741EB33A650055FFCB /* Margins */ = { + isa = PBXGroup; + children = ( + 53E307751EB33A650055FFCB /* AppDelegate.swift */, + 53E307791EB33A650055FFCB /* Main.storyboard */, + 53E3077C1EB33A650055FFCB /* Assets.xcassets */, + 53E3077E1EB33A650055FFCB /* LaunchScreen.storyboard */, + 53E307811EB33A650055FFCB /* Info.plist */, + ); + path = Margins; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53E307711EB33A650055FFCB /* Margins */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53E307841EB33A650055FFCB /* Build configuration list for PBXNativeTarget "Margins" */; + buildPhases = ( + 53E3076E1EB33A650055FFCB /* Sources */, + 53E3076F1EB33A650055FFCB /* Frameworks */, + 53E307701EB33A650055FFCB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Margins; + productName = Margins; + productReference = 53E307721EB33A650055FFCB /* Margins.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53E3076A1EB33A650055FFCB /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 1030; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53E307711EB33A650055FFCB = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 53E3076D1EB33A650055FFCB /* Build configuration list for PBXProject "Margins" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53E307691EB33A650055FFCB; + productRefGroup = 53E307731EB33A650055FFCB /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53E307711EB33A650055FFCB /* Margins */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53E307701EB33A650055FFCB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E307801EB33A650055FFCB /* LaunchScreen.storyboard in Resources */, + 53E3077D1EB33A650055FFCB /* Assets.xcassets in Resources */, + 53E3077B1EB33A650055FFCB /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53E3076E1EB33A650055FFCB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53E307761EB33A650055FFCB /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53E307791EB33A650055FFCB /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53E3077A1EB33A650055FFCB /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53E3077E1EB33A650055FFCB /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53E3077F1EB33A650055FFCB /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53E307821EB33A650055FFCB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53E307831EB33A650055FFCB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53E307851EB33A650055FFCB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Margins/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Margins; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 53E307861EB33A650055FFCB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Margins/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Margins; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53E3076D1EB33A650055FFCB /* Build configuration list for PBXProject "Margins" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53E307821EB33A650055FFCB /* Debug */, + 53E307831EB33A650055FFCB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53E307841EB33A650055FFCB /* Build configuration list for PBXNativeTarget "Margins" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53E307851EB33A650055FFCB /* Debug */, + 53E307861EB33A650055FFCB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53E3076A1EB33A650055FFCB /* Project object */; +} diff --git a/Margins/Margins.xcworkspace/contents.xcworkspacedata b/Margins/Margins.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b988434 --- /dev/null +++ b/Margins/Margins.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Margins/Margins.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Margins/Margins.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Margins/Margins.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Margins/Margins/AppDelegate.swift b/Margins/Margins/AppDelegate.swift new file mode 100644 index 0000000..de79b3d --- /dev/null +++ b/Margins/Margins/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// Margins +// +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/Margins/Margins/Assets.xcassets/AppIcon.appiconset/Contents.json b/Margins/Margins/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/Margins/Margins/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Margins/Margins/Base.lproj/LaunchScreen.storyboard b/Margins/Margins/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/Margins/Margins/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Margins/Margins/Base.lproj/Main.storyboard b/Margins/Margins/Base.lproj/Main.storyboard new file mode 100644 index 0000000..17351d7 --- /dev/null +++ b/Margins/Margins/Base.lproj/Main.storyboard @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Margins/Margins/Info.plist b/Margins/Margins/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/Margins/Margins/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Margins/README.md b/Margins/README.md new file mode 100644 index 0000000..74ee017 --- /dev/null +++ b/Margins/README.md @@ -0,0 +1,7 @@ +### Preserving Superview Margins + +Example of how to use `preservesSuperviewLayoutMargins`. + +See the following blog post: + ++ [Preserves Superview Layout Margins](https://useyourloaf.com/blog/preserves-superview-layout-margins/) \ No newline at end of file diff --git a/MasterSlide/MasterSlide/MainWindow.xib b/MasterSlide/MasterSlide/MainWindow.xib deleted file mode 100644 index de12c87..0000000 --- a/MasterSlide/MasterSlide/MainWindow.xib +++ /dev/null @@ -1,337 +0,0 @@ - - - - 1280 - 11C74 - 1938 - 1138.23 - 567.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 - - - IBProxyObject - IBUINavigationController - IBUIViewController - IBUICustomObject - IBUISplitViewController - IBUIWindow - IBUITableViewController - IBUINavigationItem - IBUINavigationBar - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - IBIPadFramework - - - - 1316 - - {768, 1024} - - - - - 1 - MSAxIDEAA - - NO - NO - - 2 - - IBIPadFramework - YES - - - - - 2 - - - 3 - 3 - - IBIPadFramework - YES - - - - 2 - - - 1 - 1 - - IBIPadFramework - NO - - - 256 - {0, 0} - _NS:839 - YES - YES - IBIPadFramework - - - - Master - - Master - IBIPadFramework - - - UYLMasterViewController - - 2 - - - 1 - 1 - - IBIPadFramework - NO - NO - - - - - Detail - - - UYLDetailViewController - - 1 - 1 - - IBIPadFramework - NO - - - - - - - - delegate - - - - 5 - - - - window - - - - 14 - - - - splitViewController - - - - 13 - - - - detailViewController - - - - 35 - - - - - - 0 - - - - - - 2 - - - - - -1 - - - File's Owner - - - 4 - - - App Delegate - - - -2 - - - - - 6 - - - - - - - - - 15 - - - - - - 8 - - - - - - - - - 10 - - - - - - - - 11 - - - - - 9 - - - - - - - UIApplication - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UYLMasterViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UYLDetailViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UYLAppDelegate - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 35 - - - - - UYLAppDelegate - UIResponder - - UISplitViewController - UIWindow - - - - splitViewController - UISplitViewController - - - window - UIWindow - - - - IBProjectSource - ./Classes/UYLAppDelegate.h - - - - UYLDetailViewController - UIViewController - - detailDescriptionLabel - UILabel - - - detailDescriptionLabel - - detailDescriptionLabel - UILabel - - - - IBProjectSource - ./Classes/UYLDetailViewController.h - - - - UYLMasterViewController - UITableViewController - - detailViewController - UYLDetailViewController - - - detailViewController - - detailViewController - UYLDetailViewController - - - - IBProjectSource - ./Classes/UYLMasterViewController.h - - - - - 0 - IBIPadFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - 3 - 933 - - diff --git a/MasterSlide/MasterSlide/en.lproj/UYLDetailViewController.xib b/MasterSlide/MasterSlide/en.lproj/UYLDetailViewController.xib deleted file mode 100644 index 0e8a58b..0000000 --- a/MasterSlide/MasterSlide/en.lproj/UYLDetailViewController.xib +++ /dev/null @@ -1,410 +0,0 @@ - - - - 1280 - 11C74 - 1938 - 1138.23 - 567.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 - - - IBUISwipeGestureRecognizer - IBUITapGestureRecognizer - IBUIToolbar - IBUIView - IBUILabel - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - - 274 - - - - 290 - {768, 44} - - - - _NS:372 - NO - NO - IBIPadFramework - - - - - 292 - {{363, 11}, {42, 21}} - - - - _NS:345 - NO - YES - 7 - NO - IBIPadFramework - Detail - - 1 - MCAwIDAAA - - - 1 - 10 - - 1 - 17 - - - Helvetica - 17 - 16 - - - - - 274 - - - - 298 - {{20, 470}, {728, 21}} - - - - - 3 - MQA - - YES - - NO - IBIPadFramework - Select an item - - - 1 - 10 - 1 - - 1 - 4 - - - Helvetica - 14 - 16 - - - - {{0, 44}, {768, 960}} - - - _NS:212 - - 3 - MQA - - 2 - - - - IBIPadFramework - - - {{0, 20}, {768, 1004}} - - - - - YES - - - 2 - - - IBUISplitViewDetailSimulatedSizeMetrics - - YES - - - - - - {768, 1024} - {703, 768} - - - IBIPadFramework - Detail - IBUISplitViewController - - IBUISplitViewControllerContentSizeLocation - IBUISplitViewControllerContentSizeLocationDetail - - - IBIPadFramework - - - - 2 - - - - - - - - view - - - - 12 - - - - toolbar - - - - 72 - - - - detailTitle - - - - 74 - - - - detailDescriptionLabel - - - - 66 - - - - handleTap: - - - - 97 - - - - handleSwipeRight: - - - - 98 - - - - handleSwipeLeft: - - - - 102 - - - - gestureRecognizers - - - NSArray - YES - - 111 - - - - gestureRecognizers - - - NSArray - YES - - 112 - - - - gestureRecognizers - - - NSArray - YES - - 113 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 8 - - - - - - - - - - 67 - - - - - - 73 - - - - - 110 - - - - - - - - 45 - - - - - 79 - - - - - 81 - - - - - 75 - - - - - - - UYLDetailViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 113 - - - - - UYLDetailViewController - UIViewController - - UISwipeGestureRecognizer - UISwipeGestureRecognizer - UITapGestureRecognizer - - - - handleSwipeLeft: - UISwipeGestureRecognizer - - - handleSwipeRight: - UISwipeGestureRecognizer - - - handleTap: - UITapGestureRecognizer - - - - UILabel - UILabel - UIToolbar - - - - detailDescriptionLabel - UILabel - - - detailTitle - UILabel - - - toolbar - UIToolbar - - - - IBProjectSource - ./Classes/UYLDetailViewController.h - - - - - 0 - IBIPadFramework - YES - 3 - 933 - - diff --git a/MasterSlide/MasterSlide/en.lproj/UYLMasterViewController.xib b/MasterSlide/MasterSlide/en.lproj/UYLMasterViewController.xib deleted file mode 100644 index aac88df..0000000 --- a/MasterSlide/MasterSlide/en.lproj/UYLMasterViewController.xib +++ /dev/null @@ -1,140 +0,0 @@ - - - - 1280 - 11C74 - 1938 - 1138.23 - 567.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 - - - IBProxyObject - IBUITableView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - - 274 - {320, 852} - - - - _NS:408 - - 3 - MQA - - YES - IBIPadFramework - YES - 1 - 0 - YES - 44 - 22 - 22 - - - - - - - view - - - - 11 - - - - delegate - - - - 10 - - - - dataSource - - - - 9 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 7 - - - - - - - UYLMasterViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 11 - - - - - UYLMasterViewController - UIViewController - - IBProjectSource - ./Classes/UYLMasterViewController.h - - - - - 0 - IBIPadFramework - YES - 3 - 933 - - diff --git a/Motion/Motion.xcodeproj/project.pbxproj b/Motion/Motion.xcodeproj/project.pbxproj index 15ed68b..928742d 100644 --- a/Motion/Motion.xcodeproj/project.pbxproj +++ b/Motion/Motion.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ + 530D9CF223C928930087DFA0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 530D9CF123C928930087DFA0 /* LaunchScreen.storyboard */; }; 5365E38B1875D15500466DA8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5365E38A1875D15500466DA8 /* Foundation.framework */; }; 5365E38D1875D15500466DA8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5365E38C1875D15500466DA8 /* CoreGraphics.framework */; }; 5365E38F1875D15500466DA8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5365E38E1875D15500466DA8 /* UIKit.framework */; }; @@ -19,6 +20,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 530D9CF123C928930087DFA0 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 5365E3871875D15500466DA8 /* Motion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Motion.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5365E38A1875D15500466DA8 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 5365E38C1875D15500466DA8 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -26,7 +28,6 @@ 5365E3921875D15500466DA8 /* Motion-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Motion-Info.plist"; sourceTree = ""; }; 5365E3941875D15500466DA8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 5365E3961875D15500466DA8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 5365E3981875D15500466DA8 /* Motion-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Motion-Prefix.pch"; sourceTree = ""; }; 5365E3991875D15500466DA8 /* UYLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 5365E39A1875D15500466DA8 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 5365E39D1875D15500466DA8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -86,6 +87,7 @@ 5365E3991875D15500466DA8 /* UYLAppDelegate.h */, 5365E39A1875D15500466DA8 /* UYLAppDelegate.m */, 5365E39C1875D15500466DA8 /* Main.storyboard */, + 530D9CF123C928930087DFA0 /* LaunchScreen.storyboard */, 5365E39F1875D15500466DA8 /* UYLViewController.h */, 5365E3A01875D15500466DA8 /* UYLViewController.m */, 5365E3A21875D15500466DA8 /* Images.xcassets */, @@ -100,7 +102,6 @@ 5365E3921875D15500466DA8 /* Motion-Info.plist */, 5365E3931875D15500466DA8 /* InfoPlist.strings */, 5365E3961875D15500466DA8 /* main.m */, - 5365E3981875D15500466DA8 /* Motion-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; @@ -132,12 +133,12 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0500; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; }; buildConfigurationList = 5365E3821875D15500466DA8 /* Build configuration list for PBXProject "Motion" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -159,6 +160,7 @@ buildActionMask = 2147483647; files = ( 5365E3A31875D15500466DA8 /* Images.xcassets in Resources */, + 530D9CF223C928930087DFA0 /* LaunchScreen.storyboard in Resources */, 5365E3951875D15500466DA8 /* InfoPlist.strings in Resources */, 5365E39E1875D15500466DA8 /* Main.storyboard in Resources */, ); @@ -203,23 +205,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -232,7 +248,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -242,30 +258,43 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -275,11 +304,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Motion/Motion-Prefix.pch"; INFOPLIST_FILE = "Motion/Motion-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -288,11 +318,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Motion/Motion-Prefix.pch"; INFOPLIST_FILE = "Motion/Motion-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/Motion/Motion/Base.lproj/Main.storyboard b/Motion/Motion/Base.lproj/Main.storyboard index db8b053..60e9d60 100644 --- a/Motion/Motion/Base.lproj/Main.storyboard +++ b/Motion/Motion/Base.lproj/Main.storyboard @@ -1,7 +1,10 @@ - - + + + - + + + @@ -13,39 +16,33 @@ - + - - + - - - - - + - + @@ -54,7 +51,7 @@ - + @@ -63,7 +60,7 @@ - + @@ -72,7 +69,7 @@ - + @@ -83,12 +80,11 @@ - + - @@ -99,11 +95,7 @@ + - - - - - - \ No newline at end of file + diff --git a/Motion/Motion/Images.xcassets/AppIcon.appiconset/Contents.json b/Motion/Motion/Images.xcassets/AppIcon.appiconset/Contents.json index a396706..19882d5 100644 --- a/Motion/Motion/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Motion/Motion/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,19 +1,49 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Motion/Motion/Images.xcassets/Contents.json b/Motion/Motion/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Motion/Motion/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Motion/Motion/Images.xcassets/LaunchImage.launchimage/Contents.json b/Motion/Motion/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index c79ebd3..0000000 --- a/Motion/Motion/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Motion/Motion/Images.xcassets/grid.imageset/Contents.json b/Motion/Motion/Images.xcassets/grid.imageset/Contents.json index 453044d..72e7291 100644 --- a/Motion/Motion/Images.xcassets/grid.imageset/Contents.json +++ b/Motion/Motion/Images.xcassets/grid.imageset/Contents.json @@ -2,13 +2,17 @@ "images" : [ { "idiom" : "universal", - "scale" : "1x", - "filename" : "grid.png" + "filename" : "grid.png", + "scale" : "1x" }, { "idiom" : "universal", - "scale" : "2x", - "filename" : "grid@2x.png" + "filename" : "grid@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" } ], "info" : { diff --git a/Motion/Motion/LaunchScreen.storyboard b/Motion/Motion/LaunchScreen.storyboard new file mode 100644 index 0000000..8235141 --- /dev/null +++ b/Motion/Motion/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Motion/Motion/Motion-Info.plist b/Motion/Motion/Motion-Info.plist index 79bd7f0..bcdaf3d 100644 --- a/Motion/Motion/Motion-Info.plist +++ b/Motion/Motion/Motion-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +24,8 @@ 1.0 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities @@ -35,6 +37,7 @@ UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown diff --git a/Motion/Motion/Motion-Prefix.pch b/Motion/Motion/Motion-Prefix.pch deleted file mode 100644 index 82a2bb4..0000000 --- a/Motion/Motion/Motion-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header -// -// The contents of this file are implicitly included at the beginning of every source file. -// - -#import - -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/Motion/README b/Motion/README index 8fae223..3ae9ee8 100644 --- a/Motion/README +++ b/Motion/README @@ -7,4 +7,4 @@ This is a example project showing how to add motion effects to a view to create a sense of depth. For further details see the following blog post: -http://useyourloaf.com/blog/2014/01/03/motion-effects.html +https://useyourloaf.com/blog/motion-effects/ diff --git a/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift index 24abc4e..59fec2d 100644 --- a/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/Contents.swift @@ -1,5 +1,5 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Bottom @@ -7,9 +7,9 @@ import XCPlayground or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .Bottom +myView.starImageView.contentMode = .bottom myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline index f4e4340..161eebd 100644 --- a/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/Bottom.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift index 1bb2c89..fc978bb 100644 --- a/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/Contents.swift @@ -1,14 +1,14 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Bottom Left Fix the position of the content. Does not scale or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .BottomLeft +myView.starImageView.contentMode = .bottomLeft myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline index 750a3a3..917c692 100644 --- a/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/BottomLeft.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift index f3442e5..0446b00 100644 --- a/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/Contents.swift @@ -1,14 +1,13 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Bottom Right Fix the position of the content. Does not scale or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .BottomRight +myView.starImageView.contentMode = .bottomRight myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) -//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline index e2347be..f0fc782 100644 --- a/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/BottomRight.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift index a7cbc6e..0dd5c94 100644 --- a/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/Contents.swift @@ -1,5 +1,5 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Center @@ -7,9 +7,9 @@ import XCPlayground or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .Center +myView.starImageView.contentMode = .center myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline index 5e04c90..2bc0857 100644 --- a/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/Center.xcplaygroundpage/timeline.xctimeline @@ -3,17 +3,17 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift index 4844811..42e640e 100644 --- a/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/Contents.swift @@ -1,14 +1,14 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Left Fix the position of the content. Does not scale or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .Left +myView.starImageView.contentMode = .left myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline index da653f9..66dffd5 100644 --- a/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/Left.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift index 8486cfd..7449f2c 100644 --- a/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/Contents.swift @@ -1,5 +1,5 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Redraw @@ -9,10 +9,10 @@ import XCPlayground calling drawRect. */ let myView = CircleView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.backgroundColor = .whiteColor() -myView.contentMode = .Redraw +myView.backgroundColor = .white +myView.contentMode = .redraw myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) -//: [Next](@next) \ No newline at end of file +//: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline index c8b56ae..f2256a4 100644 --- a/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/Redraw.xcplaygroundpage/timeline.xctimeline @@ -3,17 +3,17 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift index e87045f..d0b78f7 100644 --- a/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/Contents.swift @@ -1,14 +1,14 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Right Fix the position of the content. Does not scale or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .Right +myView.starImageView.contentMode = .right myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline index 52f2979..ba59fd8 100644 --- a/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/Right.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift index 8788d5e..59f558d 100644 --- a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/Contents.swift @@ -1,18 +1,18 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Scale Aspect Fill `ScaleAspectFill` scales the content to totally fill the view maintaining the aspect ratio. This can result in the content being larger than the bounds of the view. */ let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) -containerView.backgroundColor = .redColor() +containerView.backgroundColor = .red let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) containerView.addSubview(myView) myView.center = CGPoint(x: 200, y: 200) -myView.starImageView.contentMode = .ScaleAspectFill +myView.starImageView.contentMode = .scaleAspectFill /*: #### clipToBounds You will most likely want to have the superview set to clip subviews @@ -24,7 +24,7 @@ myView.starImageView.contentMode = .ScaleAspectFill myView.clipsToBounds = true containerView -XCPlaygroundPage.currentPage.liveView = containerView +PlaygroundPage.current.liveView = containerView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline index ec83354..9b06466 100644 --- a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFill.xcplaygroundpage/timeline.xctimeline @@ -3,12 +3,12 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift index daae1d1..e3ffcf6 100644 --- a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/Contents.swift @@ -1,14 +1,14 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Scale Aspect Fit `ScaleAspectFit` scales the content to fit the view but maintains the aspect ratio. Any part of the view bounds that is not filled with content is transparent. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .ScaleAspectFit +myView.starImageView.contentMode = .scaleAspectFit myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline index 61b3e15..d7f00b2 100644 --- a/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/ScaleAspectFit.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift index 5e6608e..02b1df7 100644 --- a/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/Contents.swift @@ -1,5 +1,5 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Scale To Fill @@ -9,9 +9,9 @@ import XCPlayground aspect ratio of the image is not maintained. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .ScaleToFill +myView.starImageView.contentMode = .scaleToFill myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline index 07c1389..542aa26 100644 --- a/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/ScaleToFill.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift index e96706e..0be4c20 100644 --- a/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/Contents.swift @@ -1,5 +1,5 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Top @@ -7,9 +7,9 @@ import XCPlayground or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .Top +myView.starImageView.contentMode = .top myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline index 0e86698..41b8111 100644 --- a/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/Top.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift index 5fdbfd4..edfb1fe 100644 --- a/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/Contents.swift @@ -1,14 +1,14 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Top Left Fix the position of the content. Does not scale or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .TopLeft +myView.starImageView.contentMode = .topLeft myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline index bfa3c3c..7be4241 100644 --- a/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/TopLeft.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift index 330506c..23c2625 100644 --- a/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift +++ b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/Contents.swift @@ -1,14 +1,14 @@ import UIKit -import XCPlayground +import PlaygroundSupport /*: ### Top Right Fix the position of the content. Does not scale or stretch the content. */ let myView = StarView(frame: CGRect(x: 0, y: 0, width:200, height:350)) -myView.starImageView.contentMode = .TopRight +myView.starImageView.contentMode = .topRight myView -XCPlaygroundPage.currentPage.liveView = myView +PlaygroundPage.current.liveView = myView //: [Previous](@previous) //: [Index](contentMode) //: [Next](@next) diff --git a/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline index 5490561..4bdbe79 100644 --- a/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline +++ b/Playgrounds/ContentMode.playground/Pages/TopRight.xcplaygroundpage/timeline.xctimeline @@ -3,7 +3,7 @@ version = "3.0"> diff --git a/Playgrounds/ContentMode.playground/Sources/CircleView.swift b/Playgrounds/ContentMode.playground/Sources/CircleView.swift index 9ca1165..fd5c22b 100644 --- a/Playgrounds/ContentMode.playground/Sources/CircleView.swift +++ b/Playgrounds/ContentMode.playground/Sources/CircleView.swift @@ -6,15 +6,15 @@ public class CircleView: UIView { didSet { setNeedsDisplay() } } - var color: UIColor = .redColor() { + var color: UIColor = .red { didSet { setNeedsDisplay() } } - - public override func drawRect(rect: CGRect) { + + public override func draw(_ rect: CGRect) { - let circleCenter = convertPoint(center, fromView: superview) + let circleCenter = convert(center, from: superview) let circleRadius = min(bounds.size.width,bounds.size.height)/2 * 0.80 - let circlePath = UIBezierPath(arcCenter: circleCenter, radius: circleRadius, startAngle: 0, endAngle: CGFloat(2*M_PI), clockwise: true) + let circlePath = UIBezierPath(arcCenter: circleCenter, radius: circleRadius, startAngle: 0, endAngle: CGFloat(2*Double.pi), clockwise: true) circlePath.lineWidth = lineWidth color.set() circlePath.stroke() diff --git a/Playgrounds/ContentMode.playground/Sources/StarView.swift b/Playgrounds/ContentMode.playground/Sources/StarView.swift index d1bc0fe..0fb8775 100644 --- a/Playgrounds/ContentMode.playground/Sources/StarView.swift +++ b/Playgrounds/ContentMode.playground/Sources/StarView.swift @@ -10,7 +10,7 @@ public class StarView: UIView { super.init(frame: frame) addSubview(starImageView) - backgroundColor = .greenColor() + backgroundColor = .green starImageView.frame = bounds } diff --git a/Playgrounds/ContentMode.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Playgrounds/ContentMode.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Playgrounds/ContentMode.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Playgrounds/ContentMode.zip b/Playgrounds/ContentMode.zip deleted file mode 100644 index 464fa32..0000000 Binary files a/Playgrounds/ContentMode.zip and /dev/null differ diff --git a/Playgrounds/String.playground/Contents.swift b/Playgrounds/String.playground/Contents.swift deleted file mode 100644 index 5293ca6..0000000 --- a/Playgrounds/String.playground/Contents.swift +++ /dev/null @@ -1,296 +0,0 @@ -// Swift Standard Librray - String -// Keith Harrison http://useyourloaf.com - -// Import Foundation if you want to bridge to NSString -import Foundation - -// ==== -// Initializing a String -// ==== - -var emptyString = "" // Empty String -var stillEmpty = String() // Another empty String -let helloWorld = "Hello World!" // String inferred - -let a = String(true) // from boolean: "true" -let b: Character = "A" // Explicit type required to create a Character -let c = String(b) // from character "A" -let d = String(3.14) // from Double "3.14" -let e = String(1000) // from Int "1000" -let f = "Result = \(d)" // Interpolation "Result = 3.14" -let g = "\u{2126}" // Unicode Ohm sign Ω -let h = String(count:3, repeatedValue:b) // Repeated character "AAA" - -// === -// Strings are Value Types -// === - -// Strings are value types that are copied when assigned -// or passed to a function. The copy is performed lazily -// on mutation. - -var aString = "Hello" -var bString = aString -bString += " World!" -print("\(aString)") // "Hello\n" - -// === -// Testing for empty String -// === - -emptyString.isEmpty // true - -// === -// Testing for equality -// === - -// Swift is Unicode correct so the equality operator -// (“==”) checks for Unicode canonical equivalence. -// This means that two Strings that are composed from -// different Unicode scalars will be considered equal -// if they have the same linguistic meaning and appearance: - -let spain = "España" -let tilde = "\u{303}" -let country = "Espan" + "\(tilde)" + "a" -if country == spain { - print("Matched!") // "Matched!\n" -} - -// Order -if "aaa" < "bbb" { - print("aaa is less than bbb") -} - -// === -// Testing for suffix/prefix -// === - -let line = "0001 Some test data here %%%%" -line.hasPrefix("0001") // true -line.hasSuffix("%%%%") // true - -// === -// Converting to upper/lower case -// === - -let mixedCase = "AbcDef" -let upper = mixedCase.uppercaseString // "ABCDEF" -let lower = mixedCase.lowercaseString // "abcdef" - -// === -// Views -// === - -// Strings are not collections of anything but do provide -// collection views for different representations accessed -// through the appropriate property: - -country.characters // characters -country.unicodeScalars // Unicode scalar 21-bit codes -country.utf16 // UTF-16 encoding -country.utf8 // UTF-8 encoding - -// === -// Counting -// == - -// String does not directly have a property to return a count -// as it only has meaning for a particular representation. -// So count is implemented on each of the collection views: - -// spain = "España" -print("\(spain.characters.count)") // 6 -print("\(spain.unicodeScalars.count)") // 6 -print("\(spain.utf16.count)") // 6 -print("\(spain.utf8.count)") // 7 - -// === -// Using Index to traverse a collection -// === - -// Each of the collection views has an Index -// that you use to traverse the collection. -// This is maybe one of the big causes of pain -// when getting to grips with String. You cannot -// randomly access an element in a string using -// a subscript (e.g. string[5]). - -// To iterate over all items in a collection -// with a for..in loop: - -var sentence = "Never odd or even" -for character in sentence.characters { - print(character) -} - -// Each collection has two instance properties you -// can use as subscripts to index into the collection: -// startIndex: the position of the first element if -// non-empty, else identical to endIndex. -// endIndex: the position just “past the end” of the string. -// -// Note the choice for endIndex means you cannot use it -// directly as a subscript as it is out of range. - -let cafe = "café" -cafe.startIndex // 0 -cafe.endIndex // 4 - after last char - -// The startIndex and endIndex properties become more -// useful when modified with the following methods: -// successor() to get the next element -// predecessor() to get the previous element -// advancedBy(n) to jump forward/backward by n elements -// -// Some examples, note that you can chain operations if required: - -cafe[cafe.startIndex] // "c" -cafe[cafe.startIndex.successor()] // "a" -cafe[cafe.startIndex.successor().successor()] // "f" -// Note that cafe[endIndex] is a run time error -cafe[cafe.endIndex.predecessor()] // "é" -cafe[cafe.startIndex.advancedBy(2)] // "f" - -// The indices property returns a range for all elements -// in a String that can be useful for iterating through -// the collection: - -for index in cafe.characters.indices { - print(cafe[index]) -} - -// You cannot use an index from one String to access a -// different string. You can convert an index to an integer -// value with the distanceTo method: - -let word1 = "ABCDEF" -let word2 = "012345" -let indexC = word1.startIndex.advancedBy(2) -let distance = word1.startIndex.distanceTo(indexC) // 2 -let digit = word2[word2.startIndex.advancedBy(distance)] // "2" - -// === -// Using a range -// === - -// To identify a range of elements in a String collection -// use a range. A range is just a start and end index: - -let fqdn = "useyourloaf.com" -let rangeOfTLD = Range(start: fqdn.endIndex.advancedBy(-3), end: fqdn.endIndex) -let tld = fqdn[rangeOfTLD] // "com" - -// Alternate creation of range (... or ..< syntax) -let rangeOfDomain = fqdn.startIndex.. - - - - diff --git a/Playgrounds/String.playground/timeline.xctimeline b/Playgrounds/String.playground/timeline.xctimeline deleted file mode 100644 index e920154..0000000 --- a/Playgrounds/String.playground/timeline.xctimeline +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - diff --git a/Playgrounds/String.zip b/Playgrounds/String.zip deleted file mode 100644 index 64cb3fc..0000000 Binary files a/Playgrounds/String.zip and /dev/null differ diff --git a/QReader/QReader.xcodeproj/project.pbxproj b/QReader/QReader.xcodeproj/project.pbxproj index 4c81bae..a29ccae 100644 --- a/QReader/QReader.xcodeproj/project.pbxproj +++ b/QReader/QReader.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -21,6 +21,7 @@ 5344A5B218DF769400C61776 /* UYLTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5344A5B118DF769400C61776 /* UYLTableViewController.m */; }; 5344A5B418DF769400C61776 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5344A5B318DF769400C61776 /* Images.xcassets */; }; 537EB39F18E231FE006B6FF5 /* UYLWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 537EB39E18E231FE006B6FF5 /* UYLWebViewController.m */; }; + 53B2CD6523C8ED8C007FF91F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53B2CD6723C8ED8C007FF91F /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -37,7 +38,6 @@ 5344A5A018DF769400C61776 /* QReader-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QReader-Info.plist"; sourceTree = ""; }; 5344A5A218DF769400C61776 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 5344A5A418DF769400C61776 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 5344A5A618DF769400C61776 /* QReader-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QReader-Prefix.pch"; sourceTree = ""; }; 5344A5A718DF769400C61776 /* UYLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 5344A5A818DF769400C61776 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 5344A5AB18DF769400C61776 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; @@ -48,6 +48,7 @@ 5344A5BA18DF769400C61776 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 537EB39D18E231FE006B6FF5 /* UYLWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLWebViewController.h; sourceTree = ""; }; 537EB39E18E231FE006B6FF5 /* UYLWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLWebViewController.m; sourceTree = ""; }; + 53B2CD6623C8ED8C007FF91F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -131,12 +132,12 @@ 5344A59F18DF769400C61776 /* Supporting Files */ = { isa = PBXGroup; children = ( + 53B2CD6723C8ED8C007FF91F /* LaunchScreen.storyboard */, 5344A5A718DF769400C61776 /* UYLAppDelegate.h */, 5344A5A818DF769400C61776 /* UYLAppDelegate.m */, 5344A5A018DF769400C61776 /* QReader-Info.plist */, 5344A5A118DF769400C61776 /* InfoPlist.strings */, 5344A5A418DF769400C61776 /* main.m */, - 5344A5A618DF769400C61776 /* QReader-Prefix.pch */, 53249C0219AF6D8400EA1639 /* Localizable.strings */, ); name = "Supporting Files"; @@ -169,7 +170,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0510; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 5344A59418DF769400C61776 = { @@ -178,8 +179,8 @@ }; }; buildConfigurationList = 5344A59018DF769400C61776 /* Build configuration list for PBXProject "QReader" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -203,6 +204,7 @@ 53249C0419AF6D8400EA1639 /* Localizable.strings in Resources */, 5344A5AF18DF769400C61776 /* Main_iPad.storyboard in Resources */, 5344A5B418DF769400C61776 /* Images.xcassets in Resources */, + 53B2CD6523C8ED8C007FF91F /* LaunchScreen.storyboard in Resources */, 5344A5AC18DF769400C61776 /* Main_iPhone.storyboard in Resources */, 5344A5A318DF769400C61776 /* InfoPlist.strings in Resources */, ); @@ -259,6 +261,14 @@ name = Main_iPad.storyboard; sourceTree = ""; }; + 53B2CD6723C8ED8C007FF91F /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53B2CD6623C8ED8C007FF91F /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -266,22 +276,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -294,7 +319,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -305,29 +330,43 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -338,11 +377,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "QReader/QReader-Prefix.pch"; INFOPLIST_FILE = "QReader/QReader-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -352,11 +390,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "QReader/QReader-Prefix.pch"; INFOPLIST_FILE = "QReader/QReader-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/QReader/QReader/Base.lproj/LaunchScreen.storyboard b/QReader/QReader/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..8b40a2e --- /dev/null +++ b/QReader/QReader/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/Contents.json b/QReader/QReader/Images.xcassets/AppIcon.appiconset/Contents.json index 9f52deb..d74362b 100644 --- a/QReader/QReader/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/QReader/QReader/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,58 +1,112 @@ { "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "qr-40.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "qr-60.png", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", - "filename" : "icon-29@2x.png", + "filename" : "qr-58.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "qr-87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "qr-80.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", - "filename" : "icon-40@2x-1.png", + "filename" : "qr-120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "qr-121.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", - "filename" : "icon-60@2x.png", + "filename" : "qr-180.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "qr-20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "qr-41.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", - "filename" : "icon-29.png", + "filename" : "qr-29.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", - "filename" : "icon-29@2x-1.png", + "filename" : "qr-59.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", - "filename" : "icon-40.png", + "filename" : "qr-42.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", - "filename" : "icon-40@2x.png", + "filename" : "qr-81.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", - "filename" : "icon-76.png", + "filename" : "qr-76.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", - "filename" : "icon-76@2x.png", + "filename" : "qr-152.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "qr-167.png", "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "qr-1024.png", + "scale" : "1x" } ], "info" : { diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29.png deleted file mode 100644 index dd6e8a5..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29@2x-1.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29@2x-1.png deleted file mode 100644 index 75e77ea..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29@2x-1.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29@2x.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29@2x.png deleted file mode 100644 index 75e77ea..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-29@2x.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40.png deleted file mode 100644 index a9be214..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40@2x-1.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40@2x-1.png deleted file mode 100644 index 2a7ea0f..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40@2x-1.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40@2x.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40@2x.png deleted file mode 100644 index 2a7ea0f..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-40@2x.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-60@2x.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-60@2x.png deleted file mode 100644 index 414e7fe..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-60@2x.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-76.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-76.png deleted file mode 100644 index 4b1ede6..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-76.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-76@2x.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-76@2x.png deleted file mode 100644 index f3b1901..0000000 Binary files a/QReader/QReader/Images.xcassets/AppIcon.appiconset/icon-76@2x.png and /dev/null differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-1024.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-1024.png new file mode 100644 index 0000000..9196262 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-1024.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-120.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-120.png new file mode 100644 index 0000000..2975ebb Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-120.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-121.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-121.png new file mode 100644 index 0000000..2975ebb Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-121.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-152.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-152.png new file mode 100644 index 0000000..4f80346 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-152.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-167.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-167.png new file mode 100644 index 0000000..5e0c3f0 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-167.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-180.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-180.png new file mode 100644 index 0000000..58e642c Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-180.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-20.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-20.png new file mode 100644 index 0000000..6f09da7 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-20.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-29.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-29.png new file mode 100644 index 0000000..6f66886 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-29.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-40.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-40.png new file mode 100644 index 0000000..24450d2 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-40.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-41.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-41.png new file mode 100644 index 0000000..24450d2 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-41.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-42.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-42.png new file mode 100644 index 0000000..24450d2 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-42.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-58.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-58.png new file mode 100644 index 0000000..c87ee92 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-58.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-59.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-59.png new file mode 100644 index 0000000..c87ee92 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-59.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-60.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-60.png new file mode 100644 index 0000000..12e7aa6 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-60.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-76.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-76.png new file mode 100644 index 0000000..628cac9 Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-76.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-80.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-80.png new file mode 100644 index 0000000..ed0910e Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-80.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-81.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-81.png new file mode 100644 index 0000000..ed0910e Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-81.png differ diff --git a/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-87.png b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-87.png new file mode 100644 index 0000000..4052f3d Binary files /dev/null and b/QReader/QReader/Images.xcassets/AppIcon.appiconset/qr-87.png differ diff --git a/QReader/QReader/Images.xcassets/Contents.json b/QReader/QReader/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/QReader/QReader/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/QReader/QReader/Images.xcassets/LaunchImage.launchimage/Contents.json b/QReader/QReader/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index 6f870a4..0000000 --- a/QReader/QReader/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/QReader/QReader/QReader-Info.plist b/QReader/QReader/QReader-Info.plist index 283cb28..b63c730 100644 --- a/QReader/QReader/QReader-Info.plist +++ b/QReader/QReader/QReader-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -26,14 +26,18 @@ NSCameraUsageDescription The camera is used to capture QR codes. + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile - Main_iPhone + Main_iPad UIMainStoryboardFile~ipad Main_iPad UIRequiredDeviceCapabilities armv7 + UIRequiresFullScreen + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait diff --git a/QReader/QReader/QReader-Prefix.pch b/QReader/QReader/QReader-Prefix.pch deleted file mode 100644 index 82a2bb4..0000000 --- a/QReader/QReader/QReader-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header -// -// The contents of this file are implicitly included at the beginning of every source file. -// - -#import - -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/QReader/README b/QReader/README index 4b19816..71a1a9b 100644 --- a/QReader/README +++ b/QReader/README @@ -6,9 +6,9 @@ Version 1.0 12 May 2014 Initial version. Example of how to use AVFoundation to capture QR codes. See the following post for details: -http://useyourloaf.com/blog/2014/05/13/reading-qr-codes.html +https://useyourloaf.com/blog/reading-qr-codes/ For details on adding an alert view to warn the user when the camera cannot be accessed and directly launch the settings (requires iOS 8) see the following post: -http://useyourloaf.com/blog/2014/08/28/open-settings-url.html \ No newline at end of file +https://useyourloaf.com/blog/open-settings-url/ diff --git a/README.md b/README.md index 9d178aa..b6d5e16 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,3 @@ ### Code Examples Repository -See [useyourloaf.com](http://useyourloaf.com) for details. - -### Index - -|Project|Comment| -|-------|-------| -|AdaptivePopover|Adapting a popover presentation (iOS 9, Swift) -|AirPrinter|Example of how to print from iOS -|AlertView|Demo iOS 5 changes to UIAlertView -|AlertController|UIAlertController changes in iOS 8 -|AllVisible|A split view controller template -|AnimatedConstraints|Animating Autolayout changes -|AutoLayout|AutoLayout examples -|Collection|Simple collection view with popovers -|Designable|IBDESIGNABLE/IB_Inspectable custom views -|Encode|Percent encoding of URL query string -|DynamicText|Supporting dynamic text size changes -|Huckleberry|Auto layout table view cells with varying row heights -|MasterSlide|Implementing a mail app style split view controller -|Motion|Adding motion effects to views -|NibCollection|Example use of IBOutletCollection -|QReader|Capturing and decoding QR Codes -|Refresh|Using a UIRefreshControl in a table view controller -|RemindMe|Scheduling local notifications with UILocaNotification -|Restorer|State Preservation and Restoration -|SelfSize|iOS 8 Self Sizing Table View Cells (Huckleberry updated) -|SpeakEasy|Text to speech synthesis -|Stacks|Using UIStackView -|StaticTable|Using a storyboard to implement static table views -|Stepper|Example use of UIStepper control -|Styles|Using UIAppearance proxy to style UIKit controls -|SyncMe|Example use of iCloud Key-value Storage -|TaskTimer|Example of UIAccessibility Support -|TCNibLoad|Example use of UINib class -|TwitterSearch|Example of using NSURLConnection to query Twitter API -|WorldFacts|Both iOS 8 and OS X Core Data example +See [useyourloaf.com](https://useyourloaf.com) for details. diff --git a/Refresh/README.md b/Refresh/README.md index cacfa6c..793948c 100644 --- a/Refresh/README.md +++ b/Refresh/README.md @@ -1,53 +1,18 @@ ## Refresh - Pull-to-refresh control for a table view controller + Version 1.2 11 Jan 2020 Update for Xcode 11 + Version 1.1 25 Nov 2016 Update for Xcode 8 and general clean-up. Version 1.0 18 June 2013 Initial Version ### Summary This Xcode project demonstrates how to implement the pull-to-refresh -control for table views by adding a UIRefreshControl to the table -view controller. +control for table views by adding a UIRefreshControl to a table +view controller using Interface Builder. -This example project was created with Xcode 4.6.2 and tested on iOS 6.1. - -### Known Bug - -It seems that there is a bug, ([rdar://14178445](http://openradar.appspot.com/14178445)) -that prevents the target-action method from being called when the -UIRefreshControl is added to the table view controller in a storyboard. -As a manual workaround you can add the action to the refresh control in the -viewDidLoad method of the table view controller. +This project uses Objective-C and has been updated for compatibility +with Xcode 11. For further details see the following post: -[useyourloaf.com/blog/2013/06/18/uirefreshcontrol-fun-and-games.html](http://useyourloaf.com/blog/2013/06/18/uirefreshcontrol-fun-and-games.html) - -### Small Print - -Created by Keith Harrison http://useyourloaf.com -Copyright (c) 2013 Keith Harrison. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -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. - -Neither the name of Keith Harrison nor the names of its contributors -may be used to endorse or promote products derived from this software -without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''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 HOLDER 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. ++ [UIRefreshControl Fun and Games](https://useyourloaf.com/blog/uirefreshcontrol-fun-and-games/) diff --git a/Refresh/Refresh.xcodeproj/project.pbxproj b/Refresh/Refresh.xcodeproj/project.pbxproj index 6b0fea0..a6839d5 100644 --- a/Refresh/Refresh.xcodeproj/project.pbxproj +++ b/Refresh/Refresh.xcodeproj/project.pbxproj @@ -3,22 +3,20 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ 530A6031176F8FBF004F85D9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 530A6030176F8FBF004F85D9 /* UIKit.framework */; }; 530A6033176F8FBF004F85D9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 530A6032176F8FBF004F85D9 /* Foundation.framework */; }; 530A6035176F8FBF004F85D9 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 530A6034176F8FBF004F85D9 /* CoreGraphics.framework */; }; - 530A603B176F8FBF004F85D9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 530A6039176F8FBF004F85D9 /* InfoPlist.strings */; }; 530A603D176F8FBF004F85D9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 530A603C176F8FBF004F85D9 /* main.m */; }; 530A6041176F8FBF004F85D9 /* UYLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 530A6040176F8FBF004F85D9 /* UYLAppDelegate.m */; }; - 530A6043176F8FBF004F85D9 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 530A6042176F8FBF004F85D9 /* Default.png */; }; - 530A6045176F8FBF004F85D9 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 530A6044176F8FBF004F85D9 /* Default@2x.png */; }; - 530A6047176F8FBF004F85D9 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 530A6046176F8FBF004F85D9 /* Default-568h@2x.png */; }; 530A604A176F8FBF004F85D9 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 530A6048176F8FBF004F85D9 /* MainStoryboard.storyboard */; }; 530A6058176F9081004F85D9 /* UYLTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 530A6057176F9081004F85D9 /* UYLTableViewController.m */; }; - 5332463F177104D400BED81A /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 5332463E177104D400BED81A /* README.md */; }; + 53F2D5A21DE8A0CA001851C9 /* DeckDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 53F2D5A11DE8A0CA001851C9 /* DeckDataSource.m */; }; + 53F2D5A91DE8D815001851C9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F2D5AB1DE8D815001851C9 /* LaunchScreen.storyboard */; }; + 53F2D5AD1DE8D86D001851C9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53F2D5AC1DE8D86D001851C9 /* Images.xcassets */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -27,18 +25,17 @@ 530A6032176F8FBF004F85D9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 530A6034176F8FBF004F85D9 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 530A6038176F8FBF004F85D9 /* Refresh-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Refresh-Info.plist"; sourceTree = ""; }; - 530A603A176F8FBF004F85D9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 530A603C176F8FBF004F85D9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 530A603E176F8FBF004F85D9 /* Refresh-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Refresh-Prefix.pch"; sourceTree = ""; }; 530A603F176F8FBF004F85D9 /* UYLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 530A6040176F8FBF004F85D9 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; - 530A6042176F8FBF004F85D9 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - 530A6044176F8FBF004F85D9 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; - 530A6046176F8FBF004F85D9 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - 530A6049176F8FBF004F85D9 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = ""; }; 530A6056176F9081004F85D9 /* UYLTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLTableViewController.h; sourceTree = ""; }; 530A6057176F9081004F85D9 /* UYLTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLTableViewController.m; sourceTree = ""; }; 5332463E177104D400BED81A /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + 53F2D5A01DE8A0CA001851C9 /* DeckDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeckDataSource.h; sourceTree = ""; }; + 53F2D5A11DE8A0CA001851C9 /* DeckDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeckDataSource.m; sourceTree = ""; }; + 53F2D5A61DE8D715001851C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainStoryboard.storyboard; sourceTree = ""; }; + 53F2D5AA1DE8D815001851C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53F2D5AC1DE8D86D001851C9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -90,7 +87,11 @@ 530A6057176F9081004F85D9 /* UYLTableViewController.m */, 530A603F176F8FBF004F85D9 /* UYLAppDelegate.h */, 530A6040176F8FBF004F85D9 /* UYLAppDelegate.m */, + 53F2D5A01DE8A0CA001851C9 /* DeckDataSource.h */, + 53F2D5A11DE8A0CA001851C9 /* DeckDataSource.m */, 530A6048176F8FBF004F85D9 /* MainStoryboard.storyboard */, + 53F2D5AB1DE8D815001851C9 /* LaunchScreen.storyboard */, + 53F2D5AC1DE8D86D001851C9 /* Images.xcassets */, 530A6037176F8FBF004F85D9 /* Supporting Files */, ); path = Refresh; @@ -100,12 +101,7 @@ isa = PBXGroup; children = ( 530A6038176F8FBF004F85D9 /* Refresh-Info.plist */, - 530A6039176F8FBF004F85D9 /* InfoPlist.strings */, 530A603C176F8FBF004F85D9 /* main.m */, - 530A603E176F8FBF004F85D9 /* Refresh-Prefix.pch */, - 530A6042176F8FBF004F85D9 /* Default.png */, - 530A6044176F8FBF004F85D9 /* Default@2x.png */, - 530A6046176F8FBF004F85D9 /* Default-568h@2x.png */, ); name = "Supporting Files"; sourceTree = ""; @@ -137,15 +133,16 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0460; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; }; buildConfigurationList = 530A6028176F8FBF004F85D9 /* Build configuration list for PBXProject "Refresh" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 530A6024176F8FBF004F85D9; productRefGroup = 530A602E176F8FBF004F85D9 /* Products */; @@ -162,12 +159,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 530A603B176F8FBF004F85D9 /* InfoPlist.strings in Resources */, - 530A6043176F8FBF004F85D9 /* Default.png in Resources */, - 530A6045176F8FBF004F85D9 /* Default@2x.png in Resources */, - 530A6047176F8FBF004F85D9 /* Default-568h@2x.png in Resources */, + 53F2D5A91DE8D815001851C9 /* LaunchScreen.storyboard in Resources */, + 53F2D5AD1DE8D86D001851C9 /* Images.xcassets in Resources */, 530A604A176F8FBF004F85D9 /* MainStoryboard.storyboard in Resources */, - 5332463F177104D400BED81A /* README.md in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -179,6 +173,7 @@ buildActionMask = 2147483647; files = ( 530A603D176F8FBF004F85D9 /* main.m in Sources */, + 53F2D5A21DE8A0CA001851C9 /* DeckDataSource.m in Sources */, 530A6041176F8FBF004F85D9 /* UYLAppDelegate.m in Sources */, 530A6058176F9081004F85D9 /* UYLTableViewController.m in Sources */, ); @@ -187,20 +182,20 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 530A6039176F8FBF004F85D9 /* InfoPlist.strings */ = { + 530A6048176F8FBF004F85D9 /* MainStoryboard.storyboard */ = { isa = PBXVariantGroup; children = ( - 530A603A176F8FBF004F85D9 /* en */, + 53F2D5A61DE8D715001851C9 /* Base */, ); - name = InfoPlist.strings; + name = MainStoryboard.storyboard; sourceTree = ""; }; - 530A6048176F8FBF004F85D9 /* MainStoryboard.storyboard */ = { + 53F2D5AB1DE8D815001851C9 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - 530A6049176F8FBF004F85D9 /* en */, + 53F2D5AA1DE8D815001851C9 /* Base */, ); - name = MainStoryboard.storyboard; + name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ @@ -210,28 +205,47 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -241,21 +255,39 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -265,10 +297,14 @@ 530A6051176F8FBF004F85D9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Refresh/Refresh-Prefix.pch"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; INFOPLIST_FILE = "Refresh/Refresh-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Debug; @@ -276,10 +312,14 @@ 530A6052176F8FBF004F85D9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Refresh/Refresh-Prefix.pch"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + GCC_PREFIX_HEADER = ""; INFOPLIST_FILE = "Refresh/Refresh-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; }; name = Release; diff --git a/Refresh/Refresh/Base.lproj/LaunchScreen.storyboard b/Refresh/Refresh/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..b3f8cb1 --- /dev/null +++ b/Refresh/Refresh/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Refresh/Refresh/en.lproj/MainStoryboard.storyboard b/Refresh/Refresh/Base.lproj/MainStoryboard.storyboard similarity index 51% rename from Refresh/Refresh/en.lproj/MainStoryboard.storyboard rename to Refresh/Refresh/Base.lproj/MainStoryboard.storyboard index 2c7ad58..c26048a 100644 --- a/Refresh/Refresh/en.lproj/MainStoryboard.storyboard +++ b/Refresh/Refresh/Base.lproj/MainStoryboard.storyboard @@ -1,76 +1,84 @@ - - + + + + + - - - + + + - + - - + + - + - + - - + + - - - + - - - - - + + - - + + - + - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + - \ No newline at end of file + diff --git a/Refresh/Refresh/DeckDataSource.h b/Refresh/Refresh/DeckDataSource.h new file mode 100644 index 0000000..bb86685 --- /dev/null +++ b/Refresh/Refresh/DeckDataSource.h @@ -0,0 +1,39 @@ +// +// DeckDataSource.h +// Refresh +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface DeckDataSource : NSObject +- (void)shuffle; +@end diff --git a/Refresh/Refresh/DeckDataSource.m b/Refresh/Refresh/DeckDataSource.m new file mode 100644 index 0000000..7c0eb32 --- /dev/null +++ b/Refresh/Refresh/DeckDataSource.m @@ -0,0 +1,96 @@ +// +// DeckDataSource.m +// Refresh +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "DeckDataSource.h" + +@interface DeckDataSource () +@property (nonatomic, strong) NSMutableArray *deck; +@end + +@implementation DeckDataSource + +static const NSUInteger UYL_MAXOBJECTS = 52; + +#pragma mark - +#pragma mark Custom Accessors +#pragma mark - + +- (NSMutableArray *)deck +{ + if (_deck == nil) + { + _deck = [[NSMutableArray alloc] initWithCapacity:UYL_MAXOBJECTS]; + for (NSInteger index = 0; index < UYL_MAXOBJECTS; index++) + { + [_deck insertObject:@(index+1) atIndex:index]; + } + } + return _deck; +} + +#pragma mark - +#pragma mark Public Interface +#pragma mark - + +- (void)shuffle +{ + NSUInteger count = self.deck.count; + + if (count > 1) + { + for (NSUInteger i = count - 1; i > 0; --i) + { + [self.deck exchangeObjectAtIndex:i + withObjectAtIndex:arc4random_uniform((int32_t)(i + 1))]; + } + } +} + +#pragma mark - +#pragma mark UITableViewDataSource +#pragma mark - + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.deck.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"BasicCell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; + cell.textLabel.text = [NSString stringWithFormat:@"%@", self.deck[indexPath.row]]; + return cell; +} + +@end diff --git a/Refresh/Refresh/Default-568h@2x.png b/Refresh/Refresh/Default-568h@2x.png deleted file mode 100644 index 0891b7a..0000000 Binary files a/Refresh/Refresh/Default-568h@2x.png and /dev/null differ diff --git a/Refresh/Refresh/Default.png b/Refresh/Refresh/Default.png deleted file mode 100644 index 4c8ca6f..0000000 Binary files a/Refresh/Refresh/Default.png and /dev/null differ diff --git a/Refresh/Refresh/Default@2x.png b/Refresh/Refresh/Default@2x.png deleted file mode 100644 index 35b84cf..0000000 Binary files a/Refresh/Refresh/Default@2x.png and /dev/null differ diff --git a/Refresh/Refresh/Images.xcassets/AppIcon.appiconset/Contents.json b/Refresh/Refresh/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..19882d5 --- /dev/null +++ b/Refresh/Refresh/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,53 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Refresh/Refresh/Refresh-Info.plist b/Refresh/Refresh/Refresh-Info.plist index faa11bb..b202fa6 100644 --- a/Refresh/Refresh/Refresh-Info.plist +++ b/Refresh/Refresh/Refresh-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -17,13 +17,15 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.1 CFBundleSignature ???? CFBundleVersion - 1.0 + 2 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile MainStoryboard UIRequiredDeviceCapabilities diff --git a/Refresh/Refresh/Refresh-Prefix.pch b/Refresh/Refresh/Refresh-Prefix.pch deleted file mode 100644 index 3a4d89f..0000000 --- a/Refresh/Refresh/Refresh-Prefix.pch +++ /dev/null @@ -1,14 +0,0 @@ -// -// Prefix header for all source files of the 'Refresh' target in the 'Refresh' project -// - -#import - -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/Refresh/Refresh/UYLTableViewController.m b/Refresh/Refresh/UYLTableViewController.m index 1837bda..52bffda 100644 --- a/Refresh/Refresh/UYLTableViewController.m +++ b/Refresh/Refresh/UYLTableViewController.m @@ -2,100 +2,55 @@ // UYLTableViewController.m // Refresh // -// Created by Keith Harrison http://useyourloaf.com -// Copyright (c) 2013 Keith Harrison. All rights reserved. +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. All rights reserved. // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: // -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. // -// 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. +// 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. // -// Neither the name of Keith Harrison nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''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 HOLDER 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. - +// 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 HOLDER 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 "UYLTableViewController.h" +#import "DeckDataSource.h" @interface UYLTableViewController () -@property (nonatomic,strong) NSMutableArray *deck; +@property (nonatomic,strong) DeckDataSource *deckDataSource; @end -#define UYL_MAXOBJECTS 52 - @implementation UYLTableViewController - (void)viewDidLoad { [super viewDidLoad]; - - // ************************************************************************ - // With the UIRefreshControl added to the Storyboard the action is never - // received unless we manually set the target-action here. - // - // To reproduce the bug comment the following line. - // ************************************************************************ - - [self.refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - return [self.deck count]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - static NSString *CellIdentifier = @"BasicCell"; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; - cell.textLabel.text = [NSString stringWithFormat:@"%@", [self.deck objectAtIndex:indexPath.row]]; - return cell; + self.deckDataSource = [DeckDataSource new]; + self.tableView.dataSource = self.deckDataSource; } -- (IBAction)refresh:(id)sender -{ - [self shuffle]; +- (IBAction)refresh:(UIRefreshControl *)sender { + [self.deckDataSource shuffle]; [self.tableView reloadData]; - [self.refreshControl endRefreshing]; -} - -- (void)shuffle -{ - NSInteger count = [self.deck count]; - for (NSInteger i = 0; i < count; i++) - { - NSInteger position = random() % (count - i) + i; - [self.deck exchangeObjectAtIndex:i withObjectAtIndex:position]; - } -} - -- (NSMutableArray *)deck -{ - if (_deck == nil) - { - _deck = [[NSMutableArray alloc] initWithCapacity:UYL_MAXOBJECTS]; - for (NSInteger index = 0; index < UYL_MAXOBJECTS; index++) - { - [_deck insertObject:[NSNumber numberWithInteger:index+1] atIndex:index]; - } - } - return _deck; + [sender endRefreshing]; } @end diff --git a/RefreshScroll/README.md b/RefreshScroll/README.md new file mode 100644 index 0000000..14b278a --- /dev/null +++ b/RefreshScroll/README.md @@ -0,0 +1,9 @@ +An example of adding a refresh control to a scroll view. This uses +the new in iOS 10 refreshControl property of UIScrollView. For +further details see the following post: + ++ [Refresh Control Changes in iOS 10](https://useyourloaf.com/blog/refresh-control-changes-in-ios-10/) + +### Version History + + Version 1.0 27-Nov-2016 Initial Version (Xcode 8, iOS 10) diff --git a/RefreshScroll/RefreshScroll.xcodeproj/project.pbxproj b/RefreshScroll/RefreshScroll.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e56c093 --- /dev/null +++ b/RefreshScroll/RefreshScroll.xcodeproj/project.pbxproj @@ -0,0 +1,360 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 53C353961DEB6CA700E33073 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53C353951DEB6CA700E33073 /* AppDelegate.swift */; }; + 53C3539D1DEB6CA700E33073 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53C3539C1DEB6CA700E33073 /* Assets.xcassets */; }; + 53C353A01DEB6CA700E33073 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53C3539E1DEB6CA700E33073 /* LaunchScreen.storyboard */; }; + 53C353A91DEB6D2200E33073 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53C353AB1DEB6D2200E33073 /* Main.storyboard */; }; + 53C353AE1DEB6DB100E33073 /* AdaptiveScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53C353AC1DEB6DB100E33073 /* AdaptiveScrollView.swift */; }; + 53C353AF1DEB6DB100E33073 /* SignUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53C353AD1DEB6DB100E33073 /* SignUpViewController.swift */; }; + 53C353B51DEB735B00E33073 /* UIRefreshControl+UYL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53C353B41DEB735B00E33073 /* UIRefreshControl+UYL.swift */; }; + 53C353B81DEB767F00E33073 /* UIRefreshControl.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53C353BA1DEB767F00E33073 /* UIRefreshControl.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53C353921DEB6CA700E33073 /* RefreshScroll.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RefreshScroll.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53C353951DEB6CA700E33073 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53C3539C1DEB6CA700E33073 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53C3539F1DEB6CA700E33073 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53C353A11DEB6CA700E33073 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53C353AA1DEB6D2200E33073 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53C353AC1DEB6DB100E33073 /* AdaptiveScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdaptiveScrollView.swift; sourceTree = ""; }; + 53C353AD1DEB6DB100E33073 /* SignUpViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignUpViewController.swift; sourceTree = ""; }; + 53C353B21DEB707100E33073 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53C353B41DEB735B00E33073 /* UIRefreshControl+UYL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIRefreshControl+UYL.swift"; sourceTree = ""; }; + 53C353B91DEB767F00E33073 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/UIRefreshControl.strings; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53C3538F1DEB6CA700E33073 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53C353891DEB6CA700E33073 = { + isa = PBXGroup; + children = ( + 53C353B21DEB707100E33073 /* README.md */, + 53C353941DEB6CA700E33073 /* RefreshScroll */, + 53C353931DEB6CA700E33073 /* Products */, + ); + sourceTree = ""; + }; + 53C353931DEB6CA700E33073 /* Products */ = { + isa = PBXGroup; + children = ( + 53C353921DEB6CA700E33073 /* RefreshScroll.app */, + ); + name = Products; + sourceTree = ""; + }; + 53C353941DEB6CA700E33073 /* RefreshScroll */ = { + isa = PBXGroup; + children = ( + 53C353AD1DEB6DB100E33073 /* SignUpViewController.swift */, + 53C353951DEB6CA700E33073 /* AppDelegate.swift */, + 53C353AC1DEB6DB100E33073 /* AdaptiveScrollView.swift */, + 53C353B41DEB735B00E33073 /* UIRefreshControl+UYL.swift */, + 53C353BA1DEB767F00E33073 /* UIRefreshControl.strings */, + 53C3539C1DEB6CA700E33073 /* Assets.xcassets */, + 53C3539E1DEB6CA700E33073 /* LaunchScreen.storyboard */, + 53C353AB1DEB6D2200E33073 /* Main.storyboard */, + 53C353A11DEB6CA700E33073 /* Info.plist */, + ); + path = RefreshScroll; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53C353911DEB6CA700E33073 /* RefreshScroll */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53C353A41DEB6CA700E33073 /* Build configuration list for PBXNativeTarget "RefreshScroll" */; + buildPhases = ( + 53C3538E1DEB6CA700E33073 /* Sources */, + 53C3538F1DEB6CA700E33073 /* Frameworks */, + 53C353901DEB6CA700E33073 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RefreshScroll; + productName = RefreshScroll; + productReference = 53C353921DEB6CA700E33073 /* RefreshScroll.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53C3538A1DEB6CA700E33073 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0810; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53C353911DEB6CA700E33073 = { + CreatedOnToolsVersion = 8.1; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 1020; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 53C3538D1DEB6CA700E33073 /* Build configuration list for PBXProject "RefreshScroll" */; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53C353891DEB6CA700E33073; + productRefGroup = 53C353931DEB6CA700E33073 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53C353911DEB6CA700E33073 /* RefreshScroll */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53C353901DEB6CA700E33073 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53C353A91DEB6D2200E33073 /* Main.storyboard in Resources */, + 53C353A01DEB6CA700E33073 /* LaunchScreen.storyboard in Resources */, + 53C353B81DEB767F00E33073 /* UIRefreshControl.strings in Resources */, + 53C3539D1DEB6CA700E33073 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53C3538E1DEB6CA700E33073 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53C353B51DEB735B00E33073 /* UIRefreshControl+UYL.swift in Sources */, + 53C353AF1DEB6DB100E33073 /* SignUpViewController.swift in Sources */, + 53C353961DEB6CA700E33073 /* AppDelegate.swift in Sources */, + 53C353AE1DEB6DB100E33073 /* AdaptiveScrollView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53C3539E1DEB6CA700E33073 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53C3539F1DEB6CA700E33073 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 53C353AB1DEB6D2200E33073 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53C353AA1DEB6D2200E33073 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53C353BA1DEB767F00E33073 /* UIRefreshControl.strings */ = { + isa = PBXVariantGroup; + children = ( + 53C353B91DEB767F00E33073 /* Base */, + ); + name = UIRefreshControl.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53C353A21DEB6CA700E33073 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53C353A31DEB6CA700E33073 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53C353A51DEB6CA700E33073 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RefreshScroll/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RefreshScroll; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 53C353A61DEB6CA700E33073 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RefreshScroll/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RefreshScroll; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53C3538D1DEB6CA700E33073 /* Build configuration list for PBXProject "RefreshScroll" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53C353A21DEB6CA700E33073 /* Debug */, + 53C353A31DEB6CA700E33073 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53C353A41DEB6CA700E33073 /* Build configuration list for PBXNativeTarget "RefreshScroll" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53C353A51DEB6CA700E33073 /* Debug */, + 53C353A61DEB6CA700E33073 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53C3538A1DEB6CA700E33073 /* Project object */; +} diff --git a/RefreshScroll/RefreshScroll/AdaptiveScrollView.swift b/RefreshScroll/RefreshScroll/AdaptiveScrollView.swift new file mode 100644 index 0000000..235488e --- /dev/null +++ b/RefreshScroll/RefreshScroll/AdaptiveScrollView.swift @@ -0,0 +1,65 @@ +// +// AdaptiveScrollView.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class AdaptiveScrollView: UIScrollView { + private func setup() { + let defaultCenter = NotificationCenter.default + defaultCenter.addObserver(self, selector: #selector(AdaptiveScrollView.keyboardDidChangeFrame(_:)), name: UIResponder.keyboardDidChangeFrameNotification, object: nil) + } + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + @objc func keyboardDidChangeFrame(_ notification: Notification) { + guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue else { + return + } + + let keyboardSize = keyboardFrame.cgRectValue.size + let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0) + adjustContentInsets(contentInsets) + } + + private func adjustContentInsets(_ contentInsets: UIEdgeInsets) { + contentInset = contentInsets + scrollIndicatorInsets = contentInsets + } +} diff --git a/RefreshScroll/RefreshScroll/AppDelegate.swift b/RefreshScroll/RefreshScroll/AppDelegate.swift new file mode 100644 index 0000000..39d6c65 --- /dev/null +++ b/RefreshScroll/RefreshScroll/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// RefreshScroll +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/AppIcon.appiconset/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUp.imageset/BlueSignUp.pdf b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUp.imageset/BlueSignUp.pdf new file mode 100644 index 0000000..66e58de Binary files /dev/null and b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUp.imageset/BlueSignUp.pdf differ diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUp.imageset/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUp.imageset/Contents.json new file mode 100644 index 0000000..d89ef4f --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUp.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "BlueSignUp.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUpSelected.imageset/BlueSignUp-Selected.pdf b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUpSelected.imageset/BlueSignUp-Selected.pdf new file mode 100644 index 0000000..ad88215 Binary files /dev/null and b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUpSelected.imageset/BlueSignUp-Selected.pdf differ diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUpSelected.imageset/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUpSelected.imageset/Contents.json new file mode 100644 index 0000000..13d1a37 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/BlueSignUpSelected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "BlueSignUp-Selected.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Blue/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUp.imageset/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUp.imageset/Contents.json new file mode 100644 index 0000000..bfe1daf --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUp.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "OrangeSignUp.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUp.imageset/OrangeSignUp.pdf b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUp.imageset/OrangeSignUp.pdf new file mode 100644 index 0000000..04fef61 Binary files /dev/null and b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUp.imageset/OrangeSignUp.pdf differ diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUpSelected.imageset/Contents.json b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUpSelected.imageset/Contents.json new file mode 100644 index 0000000..9856c1b --- /dev/null +++ b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUpSelected.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "OrangeSignUp-Selected.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUpSelected.imageset/OrangeSignUp-Selected.pdf b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUpSelected.imageset/OrangeSignUp-Selected.pdf new file mode 100644 index 0000000..b18f2d9 Binary files /dev/null and b/RefreshScroll/RefreshScroll/Assets.xcassets/Orange/OrangeSignUpSelected.imageset/OrangeSignUp-Selected.pdf differ diff --git a/RefreshScroll/RefreshScroll/Base.lproj/LaunchScreen.storyboard b/RefreshScroll/RefreshScroll/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..d278eb3 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RefreshScroll/RefreshScroll/Base.lproj/Main.storyboard b/RefreshScroll/RefreshScroll/Base.lproj/Main.storyboard new file mode 100644 index 0000000..ec3b561 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Base.lproj/Main.storyboard @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RefreshScroll/RefreshScroll/Base.lproj/UIRefreshControl.strings b/RefreshScroll/RefreshScroll/Base.lproj/UIRefreshControl.strings new file mode 100644 index 0000000..2f4efdf --- /dev/null +++ b/RefreshScroll/RefreshScroll/Base.lproj/UIRefreshControl.strings @@ -0,0 +1,30 @@ +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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. + +"PullToRefresh" = "Pull to refresh"; diff --git a/RefreshScroll/RefreshScroll/Info.plist b/RefreshScroll/RefreshScroll/Info.plist new file mode 100644 index 0000000..3e33804 --- /dev/null +++ b/RefreshScroll/RefreshScroll/Info.plist @@ -0,0 +1,46 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/RefreshScroll/RefreshScroll/SignUpViewController.swift b/RefreshScroll/RefreshScroll/SignUpViewController.swift new file mode 100644 index 0000000..3fc53ef --- /dev/null +++ b/RefreshScroll/RefreshScroll/SignUpViewController.swift @@ -0,0 +1,65 @@ +// +// SignUpViewController.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class SignUpViewController: UIViewController { + @IBOutlet private var scrollView: AdaptiveScrollView! + @IBOutlet private var orangeLabel: UILabel! + @IBOutlet private var orangeButton: UIButton! + + private var orangeAvailable = true { + didSet { + orangeLabel.isHidden = !orangeAvailable + orangeButton.isHidden = !orangeAvailable + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + if #available(iOS 10.0, *) { + let refreshControl = UIRefreshControl() + let title = NSLocalizedString("PullToRefresh", comment: "Pull to refresh") + refreshControl.attributedTitle = NSAttributedString(string: title) + refreshControl.addTarget(self, + action: #selector(refreshOptions(sender:)), + for: .valueChanged) + scrollView.refreshControl = refreshControl + } + } + + @objc private func refreshOptions(sender: UIRefreshControl) { + orangeAvailable = !orangeAvailable + sender.endRefreshing() + } +} diff --git a/RefreshScroll/RefreshScroll/UIRefreshControl+UYL.swift b/RefreshScroll/RefreshScroll/UIRefreshControl+UYL.swift new file mode 100644 index 0000000..7394fdc --- /dev/null +++ b/RefreshScroll/RefreshScroll/UIRefreshControl+UYL.swift @@ -0,0 +1,44 @@ +// +// UIRefreshControl+UYL.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +extension UIRefreshControl { + // Example class factory method with preset title + class func uylDefault(target: Any?, action: Selector) -> UIRefreshControl { + let refreshControl = UIRefreshControl() + let title = NSLocalizedString("PullToRefresh", comment: "Pull to refresh") + refreshControl.attributedTitle = NSAttributedString(string: title) + refreshControl.addTarget(target, action: action, for: .valueChanged) + return refreshControl + } +} diff --git a/RemindMe10/RemindMe.xcodeproj/project.pbxproj b/RemindMe10/RemindMe.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f91d866 --- /dev/null +++ b/RemindMe10/RemindMe.xcodeproj/project.pbxproj @@ -0,0 +1,497 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 532E65951DB6C89000D63AC8 /* UYLNotificationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532E65941DB6C89000D63AC8 /* UYLNotificationDelegate.swift */; }; + 532E65971DB6CEC300D63AC8 /* UIAlertController+UYLAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532E65961DB6CEC300D63AC8 /* UIAlertController+UYLAlert.swift */; }; + 538B04F61DB55F210085BDA4 /* RemindMeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538B04F51DB55F210085BDA4 /* RemindMeViewController.swift */; }; + 539D5EBD1DC4DBF500130F2F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 539D5EBC1DC4DBF500130F2F /* main.m */; }; + 539D5EC01DC4DBF500130F2F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 539D5EBF1DC4DBF500130F2F /* AppDelegate.m */; }; + 539D5EC61DC4DBF500130F2F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539D5EC41DC4DBF500130F2F /* Main.storyboard */; }; + 539D5EC81DC4DBF500130F2F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 539D5EC71DC4DBF500130F2F /* Assets.xcassets */; }; + 539D5ECB1DC4DBF500130F2F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539D5EC91DC4DBF500130F2F /* LaunchScreen.storyboard */; }; + 539D5ED21DC4E0CF00130F2F /* UYLNotificationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 539D5ED11DC4E0CF00130F2F /* UYLNotificationDelegate.m */; }; + 539D5ED51DC4E93000130F2F /* RemindMeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 539D5ED41DC4E93000130F2F /* RemindMeViewController.m */; }; + 539D5ED81DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 539D5ED71DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.m */; }; + 53BA9AF91DB283D7000BD07D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53BA9AF81DB283D7000BD07D /* AppDelegate.swift */; }; + 53BA9AFE1DB283D7000BD07D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53BA9AFC1DB283D7000BD07D /* Main.storyboard */; }; + 53BA9B001DB283D7000BD07D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53BA9AFF1DB283D7000BD07D /* Assets.xcassets */; }; + 53BA9B031DB283D7000BD07D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53BA9B011DB283D7000BD07D /* LaunchScreen.storyboard */; }; + 53DE938E1DCBD7F300196391 /* UNMutableNotification+UYL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DE938D1DCBD7F300196391 /* UNMutableNotification+UYL.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 532E65941DB6C89000D63AC8 /* UYLNotificationDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UYLNotificationDelegate.swift; sourceTree = ""; }; + 532E65961DB6CEC300D63AC8 /* UIAlertController+UYLAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIAlertController+UYLAlert.swift"; sourceTree = ""; }; + 538B04F51DB55F210085BDA4 /* RemindMeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemindMeViewController.swift; sourceTree = ""; }; + 539D5EB91DC4DBF500130F2F /* RemindMeObjc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RemindMeObjc.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 539D5EBC1DC4DBF500130F2F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 539D5EBE1DC4DBF500130F2F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 539D5EBF1DC4DBF500130F2F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 539D5EC51DC4DBF500130F2F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 539D5EC71DC4DBF500130F2F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 539D5ECA1DC4DBF500130F2F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 539D5ECC1DC4DBF500130F2F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 539D5ED01DC4E0CF00130F2F /* UYLNotificationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLNotificationDelegate.h; sourceTree = ""; }; + 539D5ED11DC4E0CF00130F2F /* UYLNotificationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLNotificationDelegate.m; sourceTree = ""; }; + 539D5ED31DC4E93000130F2F /* RemindMeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemindMeViewController.h; sourceTree = ""; }; + 539D5ED41DC4E93000130F2F /* RemindMeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemindMeViewController.m; sourceTree = ""; }; + 539D5ED61DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UNMutableNotificationContent+UYLHelper.h"; sourceTree = ""; }; + 539D5ED71DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UNMutableNotificationContent+UYLHelper.m"; sourceTree = ""; }; + 53BA9AF51DB283D7000BD07D /* RemindMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RemindMe.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53BA9AF81DB283D7000BD07D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53BA9AFD1DB283D7000BD07D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53BA9AFF1DB283D7000BD07D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53BA9B021DB283D7000BD07D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53BA9B041DB283D7000BD07D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53DE938D1DCBD7F300196391 /* UNMutableNotification+UYL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UNMutableNotification+UYL.swift"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 539D5EB61DC4DBF500130F2F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 53BA9AF21DB283D7000BD07D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 539D5EBA1DC4DBF500130F2F /* RemindMeObjc */ = { + isa = PBXGroup; + children = ( + 539D5EBE1DC4DBF500130F2F /* AppDelegate.h */, + 539D5EBF1DC4DBF500130F2F /* AppDelegate.m */, + 539D5ED31DC4E93000130F2F /* RemindMeViewController.h */, + 539D5ED41DC4E93000130F2F /* RemindMeViewController.m */, + 539D5EC41DC4DBF500130F2F /* Main.storyboard */, + 539D5ED61DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.h */, + 539D5ED71DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.m */, + 539D5EC71DC4DBF500130F2F /* Assets.xcassets */, + 539D5EC91DC4DBF500130F2F /* LaunchScreen.storyboard */, + 539D5ECC1DC4DBF500130F2F /* Info.plist */, + 539D5EBB1DC4DBF500130F2F /* Supporting Files */, + 539D5ED01DC4E0CF00130F2F /* UYLNotificationDelegate.h */, + 539D5ED11DC4E0CF00130F2F /* UYLNotificationDelegate.m */, + ); + path = RemindMeObjc; + sourceTree = ""; + }; + 539D5EBB1DC4DBF500130F2F /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 539D5EBC1DC4DBF500130F2F /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 53BA9AEC1DB283D7000BD07D = { + isa = PBXGroup; + children = ( + 53BA9AF71DB283D7000BD07D /* RemindMe */, + 539D5EBA1DC4DBF500130F2F /* RemindMeObjc */, + 53BA9AF61DB283D7000BD07D /* Products */, + ); + sourceTree = ""; + }; + 53BA9AF61DB283D7000BD07D /* Products */ = { + isa = PBXGroup; + children = ( + 53BA9AF51DB283D7000BD07D /* RemindMe.app */, + 539D5EB91DC4DBF500130F2F /* RemindMeObjc.app */, + ); + name = Products; + sourceTree = ""; + }; + 53BA9AF71DB283D7000BD07D /* RemindMe */ = { + isa = PBXGroup; + children = ( + 53DE938D1DCBD7F300196391 /* UNMutableNotification+UYL.swift */, + 538B04F51DB55F210085BDA4 /* RemindMeViewController.swift */, + 532E65961DB6CEC300D63AC8 /* UIAlertController+UYLAlert.swift */, + 532E65941DB6C89000D63AC8 /* UYLNotificationDelegate.swift */, + 53BA9AF81DB283D7000BD07D /* AppDelegate.swift */, + 53BA9AFC1DB283D7000BD07D /* Main.storyboard */, + 53BA9AFF1DB283D7000BD07D /* Assets.xcassets */, + 53BA9B011DB283D7000BD07D /* LaunchScreen.storyboard */, + 53BA9B041DB283D7000BD07D /* Info.plist */, + ); + path = RemindMe; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 539D5EB81DC4DBF500130F2F /* RemindMeObjc */ = { + isa = PBXNativeTarget; + buildConfigurationList = 539D5ECF1DC4DBF500130F2F /* Build configuration list for PBXNativeTarget "RemindMeObjc" */; + buildPhases = ( + 539D5EB51DC4DBF500130F2F /* Sources */, + 539D5EB61DC4DBF500130F2F /* Frameworks */, + 539D5EB71DC4DBF500130F2F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RemindMeObjc; + productName = RemindMeObjc; + productReference = 539D5EB91DC4DBF500130F2F /* RemindMeObjc.app */; + productType = "com.apple.product-type.application"; + }; + 53BA9AF41DB283D7000BD07D /* RemindMe */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53BA9B071DB283D7000BD07D /* Build configuration list for PBXNativeTarget "RemindMe" */; + buildPhases = ( + 53BA9AF11DB283D7000BD07D /* Sources */, + 53BA9AF21DB283D7000BD07D /* Frameworks */, + 53BA9AF31DB283D7000BD07D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RemindMe; + productName = RemindMe; + productReference = 53BA9AF51DB283D7000BD07D /* RemindMe.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53BA9AED1DB283D7000BD07D /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0800; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 539D5EB81DC4DBF500130F2F = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + 53BA9AF41DB283D7000BD07D = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 53BA9AF01DB283D7000BD07D /* Build configuration list for PBXProject "RemindMe" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53BA9AEC1DB283D7000BD07D; + productRefGroup = 53BA9AF61DB283D7000BD07D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53BA9AF41DB283D7000BD07D /* RemindMe */, + 539D5EB81DC4DBF500130F2F /* RemindMeObjc */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 539D5EB71DC4DBF500130F2F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 539D5ECB1DC4DBF500130F2F /* LaunchScreen.storyboard in Resources */, + 539D5EC81DC4DBF500130F2F /* Assets.xcassets in Resources */, + 539D5EC61DC4DBF500130F2F /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 53BA9AF31DB283D7000BD07D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53BA9B031DB283D7000BD07D /* LaunchScreen.storyboard in Resources */, + 53BA9B001DB283D7000BD07D /* Assets.xcassets in Resources */, + 53BA9AFE1DB283D7000BD07D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 539D5EB51DC4DBF500130F2F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 539D5ED81DC4ECE200130F2F /* UNMutableNotificationContent+UYLHelper.m in Sources */, + 539D5EC01DC4DBF500130F2F /* AppDelegate.m in Sources */, + 539D5EBD1DC4DBF500130F2F /* main.m in Sources */, + 539D5ED21DC4E0CF00130F2F /* UYLNotificationDelegate.m in Sources */, + 539D5ED51DC4E93000130F2F /* RemindMeViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 53BA9AF11DB283D7000BD07D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53DE938E1DCBD7F300196391 /* UNMutableNotification+UYL.swift in Sources */, + 532E65971DB6CEC300D63AC8 /* UIAlertController+UYLAlert.swift in Sources */, + 53BA9AF91DB283D7000BD07D /* AppDelegate.swift in Sources */, + 532E65951DB6C89000D63AC8 /* UYLNotificationDelegate.swift in Sources */, + 538B04F61DB55F210085BDA4 /* RemindMeViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 539D5EC41DC4DBF500130F2F /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 539D5EC51DC4DBF500130F2F /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 539D5EC91DC4DBF500130F2F /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 539D5ECA1DC4DBF500130F2F /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 53BA9AFC1DB283D7000BD07D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53BA9AFD1DB283D7000BD07D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53BA9B011DB283D7000BD07D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53BA9B021DB283D7000BD07D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 539D5ECD1DC4DBF500130F2F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RemindMeObjc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RemindMeObjc; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 539D5ECE1DC4DBF500130F2F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RemindMeObjc/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RemindMeObjc; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 53BA9B051DB283D7000BD07D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53BA9B061DB283D7000BD07D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53BA9B081DB283D7000BD07D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RemindMe/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RemindMe; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 53BA9B091DB283D7000BD07D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RemindMe/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RemindMe; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 539D5ECF1DC4DBF500130F2F /* Build configuration list for PBXNativeTarget "RemindMeObjc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 539D5ECD1DC4DBF500130F2F /* Debug */, + 539D5ECE1DC4DBF500130F2F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53BA9AF01DB283D7000BD07D /* Build configuration list for PBXProject "RemindMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53BA9B051DB283D7000BD07D /* Debug */, + 53BA9B061DB283D7000BD07D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53BA9B071DB283D7000BD07D /* Build configuration list for PBXNativeTarget "RemindMe" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53BA9B081DB283D7000BD07D /* Debug */, + 53BA9B091DB283D7000BD07D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53BA9AED1DB283D7000BD07D /* Project object */; +} diff --git a/RemindMe10/RemindMe/AppDelegate.swift b/RemindMe10/RemindMe/AppDelegate.swift new file mode 100644 index 0000000..85e52f5 --- /dev/null +++ b/RemindMe10/RemindMe/AppDelegate.swift @@ -0,0 +1,60 @@ +// +// AppDelegate.swift +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +import UserNotifications + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + let notificationDelegate = UYLNotificationDelegate() + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { + let options: UNAuthorizationOptions = [.alert, .sound]; + registerForLocalNotifications(options: options) + let center = UNUserNotificationCenter.current() + center.delegate = notificationDelegate + notificationDelegate.registerCategories() + return true + } + + private func registerForLocalNotifications(options: UNAuthorizationOptions = [.alert, .sound]) { + let center = UNUserNotificationCenter.current() + center.requestAuthorization(options: options) { (granted, error) in + if !granted { + print("Unable to register") + } + } + } +} diff --git a/RemindMe10/RemindMe/Assets.xcassets/AppIcon.appiconset/Contents.json b/RemindMe10/RemindMe/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/RemindMe10/RemindMe/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RemindMe10/RemindMe/Base.lproj/LaunchScreen.storyboard b/RemindMe10/RemindMe/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/RemindMe10/RemindMe/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RemindMe10/RemindMe/Base.lproj/Main.storyboard b/RemindMe10/RemindMe/Base.lproj/Main.storyboard new file mode 100644 index 0000000..b721145 --- /dev/null +++ b/RemindMe10/RemindMe/Base.lproj/Main.storyboard @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RemindMe10/RemindMe/Info.plist b/RemindMe10/RemindMe/Info.plist new file mode 100644 index 0000000..3e33804 --- /dev/null +++ b/RemindMe10/RemindMe/Info.plist @@ -0,0 +1,46 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/RemindMe10/RemindMe/RemindMeViewController.swift b/RemindMe10/RemindMe/RemindMeViewController.swift new file mode 100644 index 0000000..e2663e1 --- /dev/null +++ b/RemindMe10/RemindMe/RemindMeViewController.swift @@ -0,0 +1,120 @@ +// +// RemindMeViewController.swift +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +import UserNotifications + +class RemindMeViewController: UIViewController { + + @IBOutlet private weak var reminderText: UITextField! + @IBOutlet private weak var scheduleControl: UISegmentedControl! + @IBOutlet private weak var datePicker: UIDatePicker! + + @IBAction private func scheduleNotification() { + + guard let body = reminderText.text, !body.isEmpty else { + return + } + + clearNotification() + + let content = UNMutableNotificationContent(body: body, title: "Don't forget") + content.categoryIdentifier = UYLNotificationCategory.reminder.rawValue + + // If we want this notification to repeat starting at a future date we schedule + // a non repeating notification at the initial fire date and include + // the repeat interval in the userInfo of the content. + + if let interval = UYLNotificationRepeatInterval(index: scheduleControl.selectedSegmentIndex), + interval != .none { + let userInfo = [UYLNotificationUserDataKey.repeatInterval.rawValue : interval.rawValue] + content.userInfo = userInfo + } + + let triggerDate = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute], from: datePicker.date) + let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false) + + let request = UNNotificationRequest(identifier: UYLNotificationIdentifier.reminder.rawValue, content: content, trigger: trigger) + + UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in + if let error = error { + print(error) + } + self.show(body: body, error: error) + }) + } + + @IBAction private func clearNotification() { + UNUserNotificationCenter.current().removeAllPendingNotificationRequests() + reminderText.resignFirstResponder() + } + + private func show(body: String, error: Error?) { + var alertController: UIAlertController + let title = NSLocalizedString("Scheduled Reminder", comment: "Scheduled Reminder") + if let error = error { + alertController = UIAlertController(title: title, error: error) + } else { + alertController = UIAlertController(title: title, message: body) + } + + DispatchQueue.main.async { + self.present(alertController, animated: true) + } + } + + private func dumpNotifications() { + UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in + for request in requests { + print(request) + } + } + } + + override func viewDidLoad() { + super.viewDidLoad() + setupInterface() + } + + private func setupInterface() { + datePicker.minimumDate = Date() + } +} + +extension RemindMeViewController: UITextFieldDelegate { + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } +} diff --git a/RemindMe10/RemindMe/UIAlertController+UYLAlert.swift b/RemindMe10/RemindMe/UIAlertController+UYLAlert.swift new file mode 100644 index 0000000..68db2b6 --- /dev/null +++ b/RemindMe10/RemindMe/UIAlertController+UYLAlert.swift @@ -0,0 +1,47 @@ +// +// UIAlertController+UYLALert.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +extension UIAlertController { + + convenience init(title: String, message: String, okHandler: ((UIAlertAction) -> Void)? = nil) { + self.init(title: title, message: message, preferredStyle: .alert) + let okAction = UIAlertAction(title: NSLocalizedString("OK", comment: "OK Alert Button"), style: .cancel, handler: okHandler) + addAction(okAction) + } + + convenience init(title: String, error: Error, okHandler: ((UIAlertAction) -> Void)? = nil) { + let message = error.localizedDescription + self.init(title: title, message: message, okHandler: okHandler) + } +} diff --git a/RemindMe10/RemindMe/UNMutableNotification+UYL.swift b/RemindMe10/RemindMe/UNMutableNotification+UYL.swift new file mode 100644 index 0000000..8ab4d29 --- /dev/null +++ b/RemindMe10/RemindMe/UNMutableNotification+UYL.swift @@ -0,0 +1,73 @@ +// +// UNMutableNotification+UYL.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 UserNotifications + +extension UNMutableNotificationContent { + + /// Create editable content for a user notification. This + /// is a convenience initializer for a simple notification + /// containing a title, body and default sound. + /// + /// - parameters: + /// - body: The message displayed in the notification alert. + /// - title: A short description of the reason for the alert. + /// - sound: The sound to play when the notification is + /// delivered. Defaults to `UNNotificationSound.default`. + + convenience init(body: String, title: String, sound: UNNotificationSound = UNNotificationSound.default) { + self.init() + self.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil) + self.body = body + self.sound = sound + } + + /// Create editiable content for a user notification + /// from the content of an existing notification. + /// + /// - parameters: + /// - content: The content of a local or remote + /// notification. + + convenience init(content: UNNotificationContent) { + self.init() + self.title = content.title + self.subtitle = content.subtitle + self.body = content.body + self.sound = content.sound + self.badge = content.badge + self.launchImageName = content.launchImageName + self.categoryIdentifier = content.categoryIdentifier + self.threadIdentifier = content.threadIdentifier + } +} + diff --git a/RemindMe10/RemindMe/UYLNotificationDelegate.swift b/RemindMe10/RemindMe/UYLNotificationDelegate.swift new file mode 100644 index 0000000..502720a --- /dev/null +++ b/RemindMe10/RemindMe/UYLNotificationDelegate.swift @@ -0,0 +1,143 @@ +// +// UYLNotificationDelegate.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 UserNotifications + +enum UYLNotificationIdentifier: String { + case reminder +} + +enum UYLNotificationUserDataKey: String { + case repeatInterval +} + +enum UYLNotificationRepeatInterval: String { + case none + case minute + case hour + case day + case week + + init?(index: Int) { + switch index { + case 0: self = .none + case 1: self = .minute + case 2: self = .hour + case 3: self = .day + case 4: self = .week + default: return nil + } + } +} + +enum UYLNotificationAction: String { + case snooze = "com.useyourloaf.actionSnooze" + case delete = "com.useyourloaf.actionDelete" +} + +enum UYLNotificationCategory: String { + case reminder = "com.useyourloaf.reminder" +} + +class UYLNotificationDelegate: NSObject, UNUserNotificationCenterDelegate { + + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + rescheduleRepeating(notification: notification) + completionHandler([.alert,.sound]) + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + + switch response.actionIdentifier { + case UNNotificationDismissActionIdentifier: + print("Dismiss Action") + case UNNotificationDefaultActionIdentifier: + print("Default Action") + case UYLNotificationAction.snooze.rawValue: + print("Snooze") + case UYLNotificationAction.delete.rawValue: + print("Delete") + let identifier = response.notification.request.identifier + UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifier]) + break + default: + rescheduleRepeating(notification: response.notification) + } + completionHandler() + } + + func registerCategories() { + let snoozeAction = UNNotificationAction(identifier: UYLNotificationAction.snooze.rawValue, title: "Snooze", options: []) + let deleteAction = UNNotificationAction(identifier: UYLNotificationAction.delete.rawValue, title: "Delete", options: [.destructive]) + let category = UNNotificationCategory(identifier: UYLNotificationCategory.reminder.rawValue, actions: [snoozeAction,deleteAction], intentIdentifiers: [], options: []) + UNUserNotificationCenter.current().setNotificationCategories([category]) + } + + private func rescheduleRepeating(notification: UNNotification) { + + let userInfo = notification.request.content.userInfo + let repeatKey = UYLNotificationUserDataKey.repeatInterval.rawValue + + guard let identifier = UYLNotificationIdentifier(rawValue: notification.request.identifier), + identifier == .reminder, + let repeatIntervalRawValue = userInfo[repeatKey] as? String, + let repeatInterval = UYLNotificationRepeatInterval(rawValue: repeatIntervalRawValue), + repeatInterval != .none else { + return + } + + let triggerDate = Calendar.current.dateComponents([.weekday,.day,.hour,.minute], from: notification.date) + + var date = DateComponents() + switch repeatInterval { + case .minute: + date.second = 0 + case .hour: + date.minute = triggerDate.minute + case .day: + date.hour = triggerDate.hour + date.minute = triggerDate.minute + case .week: + date.weekday = triggerDate.weekday + date.hour = triggerDate.hour + date.minute = triggerDate.minute + case .none: + return + } + + let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true) + let content = UNMutableNotificationContent(content: notification.request.content) + let request = UNNotificationRequest(identifier: UYLNotificationIdentifier.reminder.rawValue, content: content, trigger: trigger) + + UNUserNotificationCenter.current().add(request) + } +} diff --git a/RemindMe10/RemindMeObjc/AppDelegate.h b/RemindMe10/RemindMeObjc/AppDelegate.h new file mode 100644 index 0000000..d6e06d6 --- /dev/null +++ b/RemindMe10/RemindMeObjc/AppDelegate.h @@ -0,0 +1,40 @@ +// +// AppDelegate.h +// RemindMeObjc +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end + diff --git a/RemindMe10/RemindMeObjc/AppDelegate.m b/RemindMe10/RemindMeObjc/AppDelegate.m new file mode 100644 index 0000000..c725a0f --- /dev/null +++ b/RemindMe10/RemindMeObjc/AppDelegate.m @@ -0,0 +1,77 @@ +// +// AppDelegate.m +// RemindMeObjc +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 UserNotifications; + +#import "AppDelegate.h" +#import "UYLNotificationDelegate.h" + +@interface AppDelegate () +@property (nonatomic,strong) id notificationDelegate; +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [self registerForLocalNotifications]; + self.notificationDelegate = [UYLNotificationDelegate new]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + center.delegate = self.notificationDelegate; + return YES; +} + +- (void)registerForLocalNotifications { + + UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound; + UNUserNotificationCenter *center = UNUserNotificationCenter.currentNotificationCenter; + [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) { + if (!granted) { + NSLog(@"Something went wrong"); + } + }]; + + UNNotificationAction *snoozeAction = [UNNotificationAction actionWithIdentifier:@"Snooze" title:@"Snooze" options:UNNotificationActionOptionNone]; + UNNotificationAction *deleteAction = [UNNotificationAction actionWithIdentifier:@"Delete" title:@"Delete" options:UNNotificationActionOptionDestructive]; + + UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"UYLReminderCategory" actions:@[snoozeAction,deleteAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone]; + NSSet *categories = [NSSet setWithObject:category]; + [center setNotificationCategories:categories]; + +// let snoozeAction = UNNotificationAction(identifier: "Snooze", title: "Snooze", options: []) +// let deleteAction = UNNotificationAction(identifier: UYLNotificationAction.delete.rawValue, title: "Delete", options: [.destructive]) +// let category = UNNotificationCategory(identifier: UYLNotificationCategory.reminder.rawValue, actions: [snoozeAction,deleteAction], intentIdentifiers: [], options: []) +// UNUserNotificationCenter.current().setNotificationCategories([category]) + +} +@end diff --git a/RemindMe10/RemindMeObjc/Assets.xcassets/AppIcon.appiconset/Contents.json b/RemindMe10/RemindMeObjc/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/RemindMe10/RemindMeObjc/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RemindMe10/RemindMeObjc/Base.lproj/LaunchScreen.storyboard b/RemindMe10/RemindMeObjc/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/RemindMe10/RemindMeObjc/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RemindMe10/RemindMeObjc/Base.lproj/Main.storyboard b/RemindMe10/RemindMeObjc/Base.lproj/Main.storyboard new file mode 100644 index 0000000..d193fc6 --- /dev/null +++ b/RemindMe10/RemindMeObjc/Base.lproj/Main.storyboard @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RemindMe10/RemindMeObjc/Info.plist b/RemindMe10/RemindMeObjc/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/RemindMe10/RemindMeObjc/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/RemindMe10/RemindMeObjc/RemindMeViewController.h b/RemindMe10/RemindMeObjc/RemindMeViewController.h new file mode 100644 index 0000000..69ec74a --- /dev/null +++ b/RemindMe10/RemindMeObjc/RemindMeViewController.h @@ -0,0 +1,39 @@ +// +// RemindMeViewController.h +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface RemindMeViewController : UIViewController + +@end diff --git a/RemindMe10/RemindMeObjc/RemindMeViewController.m b/RemindMe10/RemindMeObjc/RemindMeViewController.m new file mode 100644 index 0000000..06b7f5b --- /dev/null +++ b/RemindMe10/RemindMeObjc/RemindMeViewController.m @@ -0,0 +1,105 @@ +// +// RemindMeViewController.m +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "RemindMeViewController.h" +@import UserNotifications; + +@interface RemindMeViewController () +@property (weak, nonatomic) IBOutlet UITextField *reminderText; +@property (weak, nonatomic) IBOutlet UISegmentedControl *scheduleControl; +@property (weak, nonatomic) IBOutlet UIDatePicker *datePicker; +@end + +@implementation RemindMeViewController + +- (IBAction)scheduleNotification { + + if (self.reminderText.text == nil || [self.reminderText.text isEqual:@""]) { + return; + } + + [self clearNotification]; + + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + + UNMutableNotificationContent *content = [UNMutableNotificationContent new]; + content.title = @"Don't forget"; + content.body = self.reminderText.text; + content.sound = [UNNotificationSound defaultSound]; + + NSDateComponents *triggerDate = [[NSCalendar currentCalendar] components:NSCalendarUnitYear+NSCalendarUnitMonth+NSCalendarUnitDay+NSCalendarUnitHour+NSCalendarUnitMinute+NSCalendarUnitSecond fromDate:self.datePicker.date]; + UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDate repeats:NO]; + + NSString *identifier = @"UYLLocalNotification"; + + UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger]; + + [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { + if (error != nil) { + NSLog(@"Something went wrong: %@",error); + } + }]; +} + + +- (IBAction)clearNotification { + [UNUserNotificationCenter.currentNotificationCenter removeAllPendingNotificationRequests]; + [self.reminderText resignFirstResponder]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self setupInterface]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { + if (settings.authorizationStatus != UNAuthorizationStatusAuthorized) { + // Notifications not allowed + } + }]; +} + +- (void)setupInterface { + self.datePicker.minimumDate = [NSDate date]; +} + +- (BOOL)textFieldShouldReturn:(UITextField *)textField { + [textField resignFirstResponder]; + return YES; +} + +@end diff --git a/RemindMe10/RemindMeObjc/UNMutableNotificationContent+UYLHelper.h b/RemindMe10/RemindMeObjc/UNMutableNotificationContent+UYLHelper.h new file mode 100644 index 0000000..fff2fde --- /dev/null +++ b/RemindMe10/RemindMeObjc/UNMutableNotificationContent+UYLHelper.h @@ -0,0 +1,39 @@ +// +// UNMutableNotificationContent+UYLHelper.h +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface UNMutableNotificationContent (UYLHelper) + +@end diff --git a/RemindMe10/RemindMeObjc/UNMutableNotificationContent+UYLHelper.m b/RemindMe10/RemindMeObjc/UNMutableNotificationContent+UYLHelper.m new file mode 100644 index 0000000..4277bdf --- /dev/null +++ b/RemindMe10/RemindMeObjc/UNMutableNotificationContent+UYLHelper.m @@ -0,0 +1,48 @@ +// +// UNMutableNotificationContent+UYLHelper.m +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "UNMutableNotificationContent+UYLHelper.h" + +@implementation UNMutableNotificationContent (UYLHelper) + +- (instancetype)initWithBody:(NSString *)body title:(NSString *)title sound:(UNNotificationSound *)sound { + self = [super init]; + if (self) { + self.title = title; + self.body = body; + self.sound = sound; + } + return self; +} +@end diff --git a/RemindMe10/RemindMeObjc/UYLNotificationDelegate.h b/RemindMe10/RemindMeObjc/UYLNotificationDelegate.h new file mode 100644 index 0000000..ea756c7 --- /dev/null +++ b/RemindMe10/RemindMeObjc/UYLNotificationDelegate.h @@ -0,0 +1,40 @@ +// +// UYLNotificationDelegate.h +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +@import UserNotifications; + +@interface UYLNotificationDelegate : NSObject + +@end diff --git a/RemindMe10/RemindMeObjc/UYLNotificationDelegate.m b/RemindMe10/RemindMeObjc/UYLNotificationDelegate.m new file mode 100644 index 0000000..011b8d5 --- /dev/null +++ b/RemindMe10/RemindMeObjc/UYLNotificationDelegate.m @@ -0,0 +1,47 @@ +// +// UYLNotificationDelegate.m +// RemindMe +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "UYLNotificationDelegate.h" + +@implementation UYLNotificationDelegate + +- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { + completionHandler(UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound); +} + +- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { + completionHandler(); +} + +@end diff --git a/RemindMe10/RemindMeObjc/main.m b/RemindMe10/RemindMeObjc/main.m new file mode 100644 index 0000000..7017275 --- /dev/null +++ b/RemindMe10/RemindMeObjc/main.m @@ -0,0 +1,42 @@ +// +// main.m +// RemindMeObjc +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/Restorer/README b/Restorer/README index 09b20b8..7ddd65f 100644 --- a/Restorer/README +++ b/Restorer/README @@ -1,20 +1,27 @@ -======================================================================= -Restorer +# Restorer -Version 1.2 01 Jun 2013 Added checks for bundle version and user - interface idiom when restoring. -Version 1.1 23 May 2013 Added example of using a restoration class - with a UIWebView -Version 1.0 21 May 2013 Initial Version -======================================================================= - -The Restorer App demonstrates how to add support for State Preservation and -Restoration to an iOS 6 App. +The Restorer App demonstrates how to add support for **State Preservation and Restoration** to an iOS App. For further details see: -http://useyourloaf.com/blog/2013/05/21/state-preservation-and-restoration.html ++ [State Preservation and Restoration](https://useyourloaf.com/blog/state-preservation-and-restoration/ +) +## License The geographic data used in this App is from GeoNames and used under -the Creative Commons Attributions License (see www.geonames.org). \ No newline at end of file +the Creative Commons Attributions License (see [www.geonames.org](https://www.geonames.org)). + +## Version History + ++ Version 1.3 - 23 Apr 2019 + Update for Xcode 10.2, iOS 12 and WKWebView + ++ Version 1.2 - 01 Jun 2013 + Added checks for bundle version and user interface idiom when restoring. + ++ Version 1.1 - 23 May 2013 + Added example of using a restoration class with a UIWebView + ++ Version 1.0 - 21 May 2013 + Initial Version diff --git a/Restorer/Restorer.xcodeproj/project.pbxproj b/Restorer/Restorer.xcodeproj/project.pbxproj index 12d4818..c65f8ed 100644 --- a/Restorer/Restorer.xcodeproj/project.pbxproj +++ b/Restorer/Restorer.xcodeproj/project.pbxproj @@ -3,29 +3,24 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 531447D3174EBE2400E1AE4F /* UYLWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 531447D2174EBE2400E1AE4F /* UYLWebViewController.m */; }; - 531447D5174EBE4B00E1AE4F /* UYLWebViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 531447D4174EBE4B00E1AE4F /* UYLWebViewController.xib */; }; + 5320FB22225264E200AADA00 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5320FB21225264E200AADA00 /* Images.xcassets */; }; + 5320FB252252655800AADA00 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5320FB232252655800AADA00 /* LaunchScreen.storyboard */; }; 535CDCD2174C2E440021AE7F /* README in Resources */ = {isa = PBXBuildFile; fileRef = 535CDCD1174C2E440021AE7F /* README */; }; + 535EBE002252692700EEF01D /* UYLWebViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 535EBE022252692700EEF01D /* UYLWebViewController.xib */; }; 53844B4016F7B2E0007B7561 /* countries.plist in Resources */ = {isa = PBXBuildFile; fileRef = 53844B3F16F7B2E0007B7561 /* countries.plist */; }; 53844B4316F7B7F0007B7561 /* UYLCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53844B4216F7B7F0007B7561 /* UYLCountryViewController.m */; }; 53844B4616F7BE98007B7561 /* UYLSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53844B4516F7BE98007B7561 /* UYLSettingsViewController.m */; }; - 53844B9C16F7CFC4007B7561 /* first.png in Resources */ = {isa = PBXBuildFile; fileRef = 53844B9816F7CFC3007B7561 /* first.png */; }; - 53844B9D16F7CFC4007B7561 /* first@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53844B9916F7CFC3007B7561 /* first@2x.png */; }; - 53844B9E16F7CFC4007B7561 /* second.png in Resources */ = {isa = PBXBuildFile; fileRef = 53844B9A16F7CFC3007B7561 /* second.png */; }; - 53844B9F16F7CFC4007B7561 /* second@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53844B9B16F7CFC3007B7561 /* second@2x.png */; }; 53EA99B016F7AE6F0005DF78 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53EA99AF16F7AE6F0005DF78 /* UIKit.framework */; }; 53EA99B216F7AE6F0005DF78 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53EA99B116F7AE6F0005DF78 /* Foundation.framework */; }; 53EA99B416F7AE6F0005DF78 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53EA99B316F7AE6F0005DF78 /* CoreGraphics.framework */; }; 53EA99BA16F7AE6F0005DF78 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53EA99B816F7AE6F0005DF78 /* InfoPlist.strings */; }; 53EA99BC16F7AE6F0005DF78 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EA99BB16F7AE6F0005DF78 /* main.m */; }; 53EA99C016F7AE6F0005DF78 /* UYLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EA99BF16F7AE6F0005DF78 /* UYLAppDelegate.m */; }; - 53EA99C216F7AE6F0005DF78 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 53EA99C116F7AE6F0005DF78 /* Default.png */; }; - 53EA99C416F7AE6F0005DF78 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53EA99C316F7AE6F0005DF78 /* Default@2x.png */; }; - 53EA99C616F7AE6F0005DF78 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53EA99C516F7AE6F0005DF78 /* Default-568h@2x.png */; }; 53EA99C916F7AE6F0005DF78 /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53EA99C716F7AE6F0005DF78 /* MainStoryboard.storyboard */; }; 53EA99E116F7B06A0005DF78 /* UYLTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EA99E016F7B06A0005DF78 /* UYLTableViewController.m */; }; /* End PBXBuildFile section */ @@ -33,17 +28,16 @@ /* Begin PBXFileReference section */ 531447D1174EBE2400E1AE4F /* UYLWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLWebViewController.h; sourceTree = ""; }; 531447D2174EBE2400E1AE4F /* UYLWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLWebViewController.m; sourceTree = ""; }; - 531447D4174EBE4B00E1AE4F /* UYLWebViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UYLWebViewController.xib; sourceTree = ""; }; - 535CDCD1174C2E440021AE7F /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 5320FB202252630D00AADA00 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainStoryboard.storyboard; sourceTree = ""; }; + 5320FB21225264E200AADA00 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 5320FB242252655800AADA00 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 535CDCD1174C2E440021AE7F /* README */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; path = README; sourceTree = ""; }; + 535EBE012252692700EEF01D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UYLWebViewController.xib; sourceTree = ""; }; 53844B3F16F7B2E0007B7561 /* countries.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = countries.plist; sourceTree = ""; }; 53844B4116F7B7F0007B7561 /* UYLCountryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLCountryViewController.h; sourceTree = ""; }; 53844B4216F7B7F0007B7561 /* UYLCountryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLCountryViewController.m; sourceTree = ""; }; 53844B4416F7BE98007B7561 /* UYLSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLSettingsViewController.h; sourceTree = ""; }; 53844B4516F7BE98007B7561 /* UYLSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLSettingsViewController.m; sourceTree = ""; }; - 53844B9816F7CFC3007B7561 /* first.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = first.png; sourceTree = ""; }; - 53844B9916F7CFC3007B7561 /* first@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "first@2x.png"; sourceTree = ""; }; - 53844B9A16F7CFC3007B7561 /* second.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = second.png; sourceTree = ""; }; - 53844B9B16F7CFC3007B7561 /* second@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "second@2x.png"; sourceTree = ""; }; 53EA99AC16F7AE6F0005DF78 /* Restorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Restorer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53EA99AF16F7AE6F0005DF78 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 53EA99B116F7AE6F0005DF78 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -54,10 +48,6 @@ 53EA99BD16F7AE6F0005DF78 /* Restorer-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Restorer-Prefix.pch"; sourceTree = ""; }; 53EA99BE16F7AE6F0005DF78 /* UYLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 53EA99BF16F7AE6F0005DF78 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; - 53EA99C116F7AE6F0005DF78 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; - 53EA99C316F7AE6F0005DF78 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; - 53EA99C516F7AE6F0005DF78 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; - 53EA99C816F7AE6F0005DF78 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard.storyboard; sourceTree = ""; }; 53EA99DF16F7B06A0005DF78 /* UYLTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLTableViewController.h; sourceTree = ""; }; 53EA99E016F7B06A0005DF78 /* UYLTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLTableViewController.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -111,6 +101,7 @@ 53EA99DD16F7B0290005DF78 /* Resources */, 53EA99BE16F7AE6F0005DF78 /* UYLAppDelegate.h */, 53EA99BF16F7AE6F0005DF78 /* UYLAppDelegate.m */, + 5320FB21225264E200AADA00 /* Images.xcassets */, 53EA99B616F7AE6F0005DF78 /* Supporting Files */, ); path = Restorer; @@ -123,9 +114,6 @@ 53EA99B816F7AE6F0005DF78 /* InfoPlist.strings */, 53EA99BB16F7AE6F0005DF78 /* main.m */, 53EA99BD16F7AE6F0005DF78 /* Restorer-Prefix.pch */, - 53EA99C116F7AE6F0005DF78 /* Default.png */, - 53EA99C316F7AE6F0005DF78 /* Default@2x.png */, - 53EA99C516F7AE6F0005DF78 /* Default-568h@2x.png */, ); name = "Supporting Files"; sourceTree = ""; @@ -133,13 +121,10 @@ 53EA99DD16F7B0290005DF78 /* Resources */ = { isa = PBXGroup; children = ( - 531447D4174EBE4B00E1AE4F /* UYLWebViewController.xib */, - 53844B9816F7CFC3007B7561 /* first.png */, - 53844B9916F7CFC3007B7561 /* first@2x.png */, - 53844B9A16F7CFC3007B7561 /* second.png */, - 53844B9B16F7CFC3007B7561 /* second@2x.png */, + 535EBE022252692700EEF01D /* UYLWebViewController.xib */, 53844B3F16F7B2E0007B7561 /* countries.plist */, 53EA99C716F7AE6F0005DF78 /* MainStoryboard.storyboard */, + 5320FB232252655800AADA00 /* LaunchScreen.storyboard */, ); name = Resources; sourceTree = ""; @@ -186,15 +171,21 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0460; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53EA99AB16F7AE6F0005DF78 = { + DevelopmentTeam = LCC2J94N44; + }; + }; }; buildConfigurationList = 53EA99A716F7AE6F0005DF78 /* Build configuration list for PBXProject "Restorer" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 10.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 53EA99A316F7AE6F0005DF78; productRefGroup = 53EA99AD16F7AE6F0005DF78 /* Products */; @@ -212,17 +203,12 @@ buildActionMask = 2147483647; files = ( 53EA99BA16F7AE6F0005DF78 /* InfoPlist.strings in Resources */, - 53EA99C216F7AE6F0005DF78 /* Default.png in Resources */, - 53EA99C416F7AE6F0005DF78 /* Default@2x.png in Resources */, - 53EA99C616F7AE6F0005DF78 /* Default-568h@2x.png in Resources */, + 5320FB22225264E200AADA00 /* Images.xcassets in Resources */, 53EA99C916F7AE6F0005DF78 /* MainStoryboard.storyboard in Resources */, 53844B4016F7B2E0007B7561 /* countries.plist in Resources */, - 53844B9C16F7CFC4007B7561 /* first.png in Resources */, - 53844B9D16F7CFC4007B7561 /* first@2x.png in Resources */, - 53844B9E16F7CFC4007B7561 /* second.png in Resources */, - 53844B9F16F7CFC4007B7561 /* second@2x.png in Resources */, 535CDCD2174C2E440021AE7F /* README in Resources */, - 531447D5174EBE4B00E1AE4F /* UYLWebViewController.xib in Resources */, + 5320FB252252655800AADA00 /* LaunchScreen.storyboard in Resources */, + 535EBE002252692700EEF01D /* UYLWebViewController.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -245,6 +231,22 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + 5320FB232252655800AADA00 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5320FB242252655800AADA00 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + 535EBE022252692700EEF01D /* UYLWebViewController.xib */ = { + isa = PBXVariantGroup; + children = ( + 535EBE012252692700EEF01D /* Base */, + ); + name = UYLWebViewController.xib; + sourceTree = ""; + }; 53EA99B816F7AE6F0005DF78 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -256,7 +258,7 @@ 53EA99C716F7AE6F0005DF78 /* MainStoryboard.storyboard */ = { isa = PBXVariantGroup; children = ( - 53EA99C816F7AE6F0005DF78 /* en */, + 5320FB202252630D00AADA00 /* Base */, ); name = MainStoryboard.storyboard; sourceTree = ""; @@ -268,28 +270,47 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -299,21 +320,39 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.1; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -323,9 +362,12 @@ 53EA99DB16F7AE6F0005DF78 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Restorer/Restorer-Prefix.pch"; INFOPLIST_FILE = "Restorer/Restorer-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -334,9 +376,12 @@ 53EA99DC16F7AE6F0005DF78 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Restorer/Restorer-Prefix.pch"; INFOPLIST_FILE = "Restorer/Restorer-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/Restorer/Restorer/Base.lproj/LaunchScreen.storyboard b/Restorer/Restorer/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..a6e1b7e --- /dev/null +++ b/Restorer/Restorer/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Restorer/Restorer/en.lproj/MainStoryboard.storyboard b/Restorer/Restorer/Base.lproj/MainStoryboard.storyboard similarity index 55% rename from Restorer/Restorer/en.lproj/MainStoryboard.storyboard rename to Restorer/Restorer/Base.lproj/MainStoryboard.storyboard index 3af4f0e..139c642 100644 --- a/Restorer/Restorer/en.lproj/MainStoryboard.storyboard +++ b/Restorer/Restorer/Base.lproj/MainStoryboard.storyboard @@ -1,7 +1,14 @@ - - + + + + + - + + + + + @@ -12,7 +19,7 @@ - + @@ -21,36 +28,35 @@ - + - + - - + + - + - + - - + + - - - + - + @@ -63,47 +69,58 @@ - + - + - + - - - - - - - - - - + + + + + + + + + + @@ -112,25 +129,31 @@ - + - + - + - - + + + + + + + + @@ -139,17 +162,17 @@ - + - + - - - + + + @@ -159,17 +182,17 @@ - + - + - - - + + + @@ -179,33 +202,11 @@ - + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/Restorer/Restorer/Base.lproj/UYLWebViewController.xib b/Restorer/Restorer/Base.lproj/UYLWebViewController.xib new file mode 100644 index 0000000..d33cff2 --- /dev/null +++ b/Restorer/Restorer/Base.lproj/UYLWebViewController.xib @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Restorer/Restorer/Default-568h@2x.png b/Restorer/Restorer/Default-568h@2x.png deleted file mode 100644 index 0891b7a..0000000 Binary files a/Restorer/Restorer/Default-568h@2x.png and /dev/null differ diff --git a/Restorer/Restorer/Default.png b/Restorer/Restorer/Default.png deleted file mode 100644 index 4c8ca6f..0000000 Binary files a/Restorer/Restorer/Default.png and /dev/null differ diff --git a/Restorer/Restorer/Default@2x.png b/Restorer/Restorer/Default@2x.png deleted file mode 100644 index 35b84cf..0000000 Binary files a/Restorer/Restorer/Default@2x.png and /dev/null differ diff --git a/Restorer/Restorer/Images.xcassets/AppIcon.appiconset/Contents.json b/Restorer/Restorer/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..19882d5 --- /dev/null +++ b/Restorer/Restorer/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,53 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Restorer/Restorer/Images.xcassets/Contents.json b/Restorer/Restorer/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Restorer/Restorer/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Restorer/Restorer/Images.xcassets/first.imageset/Contents.json b/Restorer/Restorer/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000..4c4d062 --- /dev/null +++ b/Restorer/Restorer/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "first@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Restorer/Restorer/first.png b/Restorer/Restorer/Images.xcassets/first.imageset/first.png similarity index 100% rename from Restorer/Restorer/first.png rename to Restorer/Restorer/Images.xcassets/first.imageset/first.png diff --git a/Restorer/Restorer/first@2x.png b/Restorer/Restorer/Images.xcassets/first.imageset/first@2x.png similarity index 100% rename from Restorer/Restorer/first@2x.png rename to Restorer/Restorer/Images.xcassets/first.imageset/first@2x.png diff --git a/Restorer/Restorer/Images.xcassets/second.imageset/Contents.json b/Restorer/Restorer/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000..044ce4b --- /dev/null +++ b/Restorer/Restorer/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "second@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Restorer/Restorer/second.png b/Restorer/Restorer/Images.xcassets/second.imageset/second.png similarity index 100% rename from Restorer/Restorer/second.png rename to Restorer/Restorer/Images.xcassets/second.imageset/second.png diff --git a/Restorer/Restorer/second@2x.png b/Restorer/Restorer/Images.xcassets/second.imageset/second@2x.png similarity index 100% rename from Restorer/Restorer/second@2x.png rename to Restorer/Restorer/Images.xcassets/second.imageset/second@2x.png diff --git a/Restorer/Restorer/Restorer-Info.plist b/Restorer/Restorer/Restorer-Info.plist index df7f6f2..16c34dd 100644 --- a/Restorer/Restorer/Restorer-Info.plist +++ b/Restorer/Restorer/Restorer-Info.plist @@ -8,8 +8,12 @@ ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} + CFBundleIcons + + CFBundleIcons~ipad + CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -17,13 +21,15 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.2 + 1.3 CFBundleSignature ???? CFBundleVersion - 2 + 3 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile MainStoryboard UIRequiredDeviceCapabilities diff --git a/Restorer/Restorer/UYLAppDelegate.m b/Restorer/Restorer/UYLAppDelegate.m index e3b9085..8c9ed4c 100644 --- a/Restorer/Restorer/UYLAppDelegate.m +++ b/Restorer/Restorer/UYLAppDelegate.m @@ -37,7 +37,7 @@ @implementation UYLAppDelegate NSString *kUYLSettingsAmazingKey = @"amazing"; -#define BUNDLEMINVERSION 2 +#define BUNDLEMINVERSION 3 // Common initilisation code for backward compatibility with iOS 5 - (void)commonFinishLaunchingWithOptions:(NSDictionary *)launchOptions @@ -94,7 +94,7 @@ - (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:( UIUserInterfaceIdiom currentInterfaceIdiom = currentDevice.userInterfaceIdiom; if (restorationInterfaceIdiom != currentInterfaceIdiom) { - NSLog(@"Ignoring restoration data for interface idiom: %d",restorationInterfaceIdiom); + NSLog(@"Ignoring restoration data for interface idiom: %ld",(long)restorationInterfaceIdiom); return NO; } diff --git a/Restorer/Restorer/UYLCountryViewController.m b/Restorer/Restorer/UYLCountryViewController.m index fbddcc4..3877603 100644 --- a/Restorer/Restorer/UYLCountryViewController.m +++ b/Restorer/Restorer/UYLCountryViewController.m @@ -51,11 +51,6 @@ - (void)viewWillAppear:(BOOL)animated self.capitalLabel.text = self.capital; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - #pragma mark - #pragma mark === State Restoration === #pragma mark - diff --git a/Restorer/Restorer/UYLSettingsViewController.m b/Restorer/Restorer/UYLSettingsViewController.m index 7d46efb..c5b184f 100644 --- a/Restorer/Restorer/UYLSettingsViewController.m +++ b/Restorer/Restorer/UYLSettingsViewController.m @@ -51,11 +51,6 @@ - (void)viewDidLoad self.amazingSwitch.on = [defaults boolForKey:kUYLSettingsAmazingKey]; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - - (void)didDismissPresentedView { [self.presentedViewController dismissViewControllerAnimated:YES completion:NULL]; @@ -70,7 +65,6 @@ - (IBAction)amazingAction BOOL amazingEnabled = self.amazingSwitch.isOn; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setBool:amazingEnabled forKey:kUYLSettingsAmazingKey]; - [defaults synchronize]; } - (IBAction)pushMe @@ -78,8 +72,8 @@ - (IBAction)pushMe UYLWebViewController *wvc = [[UYLWebViewController alloc] initWithNibName:@"UYLWebViewController" bundle:nil]; wvc.restorationIdentifier = @"UYLWebViewController"; wvc.restorationClass = [UYLWebViewController class]; - [self.navigationController pushViewController:wvc animated:YES]; - [wvc showPage:@"http://useyourloaf.com"]; + wvc.urlString = @"https://useyourloaf.com"; + [self.navigationController showViewController:wvc sender:self]; } @end diff --git a/Restorer/Restorer/UYLTableViewController.m b/Restorer/Restorer/UYLTableViewController.m index 9d6e49f..50c6ffc 100644 --- a/Restorer/Restorer/UYLTableViewController.m +++ b/Restorer/Restorer/UYLTableViewController.m @@ -55,11 +55,6 @@ - (NSArray *)worldData #pragma mark === View Life Cycle Management === #pragma mark - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; -} - - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { static NSString *UYLSegueShowCountry = @"UYLSegueShowCountry"; diff --git a/Restorer/Restorer/UYLWebViewController.h b/Restorer/Restorer/UYLWebViewController.h index 15c82b6..8369e78 100644 --- a/Restorer/Restorer/UYLWebViewController.h +++ b/Restorer/Restorer/UYLWebViewController.h @@ -34,5 +34,5 @@ #import @interface UYLWebViewController : UIViewController -- (void)showPage:(NSString *)utlString; +@property (nonatomic, copy) NSString *urlString; @end diff --git a/Restorer/Restorer/UYLWebViewController.m b/Restorer/Restorer/UYLWebViewController.m index deef512..b4bef91 100644 --- a/Restorer/Restorer/UYLWebViewController.m +++ b/Restorer/Restorer/UYLWebViewController.m @@ -30,38 +30,38 @@ // (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 #import "UYLWebViewController.h" @interface UYLWebViewController () -@property (weak, nonatomic) IBOutlet UIWebView *webView; -@property (nonatomic) BOOL restoringState; +@property (strong, nonatomic) IBOutlet WKWebView *webView; @end @implementation UYLWebViewController +static NSString *UYLKeyURL = @"UYLKeyURL"; + #pragma mark - #pragma mark === View Life Cycle Management === #pragma mark - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - return YES; +- (void)setUrlString:(NSString *)urlString { + if (_urlString != urlString) { + _urlString = [urlString copy]; + [self loadPage]; + } } -- (void)viewDidAppear:(BOOL)animated +- (void)viewDidLoad { - [super viewDidAppear:animated]; - if (self.restoringState) - { - [self.webView reload]; - self.restoringState = NO; - } + [super viewDidLoad]; + [self loadPage]; } -- (void)showPage:(NSString *)urlString +- (void)loadPage { - NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; + NSURL *URL = [NSURL URLWithString:self.urlString]; + NSURLRequest *request = [NSURLRequest requestWithURL:URL]; [self.webView loadRequest:request]; } @@ -69,10 +69,16 @@ - (void)showPage:(NSString *)urlString #pragma mark === State Restoration === #pragma mark - +- (void)encodeRestorableStateWithCoder:(NSCoder *)coder +{ + [coder encodeObject:self.urlString forKey:UYLKeyURL]; + [super encodeRestorableStateWithCoder:coder]; +} + - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { [super decodeRestorableStateWithCoder:coder]; - self.restoringState = YES; + self.urlString = [coder decodeObjectForKey:UYLKeyURL]; } #pragma mark - diff --git a/Restorer/Restorer/UYLWebViewController.xib b/Restorer/Restorer/UYLWebViewController.xib deleted file mode 100644 index 1ec95a4..0000000 --- a/Restorer/Restorer/UYLWebViewController.xib +++ /dev/null @@ -1,139 +0,0 @@ - - - - 1552 - 12D78 - 3084 - 1187.37 - 626.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 - - - IBProxyObject - IBUIWebView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 292 - {240, 128} - - - - _NS:9 - - 1 - MSAxIDEAA - - WebViewID - IBCocoaTouchFramework - 1 - YES - - - - - - - view - - - - 6 - - - - webView - - - - 7 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 5 - - - - - - - UYLWebViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 7 - - - - - UYLWebViewController - UIViewController - - webView - UIWebView - - - webView - - webView - UIWebView - - - - IBProjectSource - ./Classes/UYLWebViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - YES - 2083 - - diff --git a/RevealStack/README.md b/RevealStack/README.md new file mode 100644 index 0000000..8e4c4af --- /dev/null +++ b/RevealStack/README.md @@ -0,0 +1,13 @@ +### RevealStack - Background Views for Stack Views + +An example of adding subviews to a stack view without adding them to +`arrangedSubviews`. This is useful when you want the stack view to have +a background view or to add an overlay. + +See the following post for more: + ++ [Stack View Background Color](https://useyourloaf.com/blog/stack-view-background-color/) + +### Version History + ++ Version 1.0 03-Apr-2017 Initial Version diff --git a/RevealStack/RevealStack.xcodeproj/project.pbxproj b/RevealStack/RevealStack.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ee2d5f6 --- /dev/null +++ b/RevealStack/RevealStack.xcodeproj/project.pbxproj @@ -0,0 +1,338 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 535B225D1E915D1C002F6D4C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535B225C1E915D1C002F6D4C /* AppDelegate.swift */; }; + 535B22621E915D1C002F6D4C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 535B22601E915D1C002F6D4C /* Main.storyboard */; }; + 535B22641E915D1C002F6D4C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 535B22631E915D1C002F6D4C /* Assets.xcassets */; }; + 535B22671E915D1C002F6D4C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 535B22651E915D1C002F6D4C /* LaunchScreen.storyboard */; }; + 535B226F1E915D7B002F6D4C /* RevealViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535B226E1E915D7B002F6D4C /* RevealViewController.swift */; }; + 535B22711E915DA7002F6D4C /* UIView+UYLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535B22701E915DA7002F6D4C /* UIView+UYLExtensions.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 535B22591E915D1C002F6D4C /* RevealStack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RevealStack.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 535B225C1E915D1C002F6D4C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 535B22611E915D1C002F6D4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 535B22631E915D1C002F6D4C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 535B22661E915D1C002F6D4C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 535B22681E915D1C002F6D4C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 535B226E1E915D7B002F6D4C /* RevealViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RevealViewController.swift; sourceTree = ""; }; + 535B22701E915DA7002F6D4C /* UIView+UYLExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+UYLExtensions.swift"; sourceTree = ""; }; + 535B22721E923F62002F6D4C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 535B22561E915D1C002F6D4C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 535B22501E915D1C002F6D4C = { + isa = PBXGroup; + children = ( + 535B22721E923F62002F6D4C /* README.md */, + 535B225B1E915D1C002F6D4C /* RevealStack */, + 535B225A1E915D1C002F6D4C /* Products */, + ); + sourceTree = ""; + }; + 535B225A1E915D1C002F6D4C /* Products */ = { + isa = PBXGroup; + children = ( + 535B22591E915D1C002F6D4C /* RevealStack.app */, + ); + name = Products; + sourceTree = ""; + }; + 535B225B1E915D1C002F6D4C /* RevealStack */ = { + isa = PBXGroup; + children = ( + 535B226E1E915D7B002F6D4C /* RevealViewController.swift */, + 535B225C1E915D1C002F6D4C /* AppDelegate.swift */, + 535B22701E915DA7002F6D4C /* UIView+UYLExtensions.swift */, + 535B22601E915D1C002F6D4C /* Main.storyboard */, + 535B22631E915D1C002F6D4C /* Assets.xcassets */, + 535B22651E915D1C002F6D4C /* LaunchScreen.storyboard */, + 535B22681E915D1C002F6D4C /* Info.plist */, + ); + path = RevealStack; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 535B22581E915D1C002F6D4C /* RevealStack */ = { + isa = PBXNativeTarget; + buildConfigurationList = 535B226B1E915D1C002F6D4C /* Build configuration list for PBXNativeTarget "RevealStack" */; + buildPhases = ( + 535B22551E915D1C002F6D4C /* Sources */, + 535B22561E915D1C002F6D4C /* Frameworks */, + 535B22571E915D1C002F6D4C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RevealStack; + productName = RevealStack; + productReference = 535B22591E915D1C002F6D4C /* RevealStack.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 535B22511E915D1C002F6D4C /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 535B22581E915D1C002F6D4C = { + CreatedOnToolsVersion = 8.3; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 535B22541E915D1C002F6D4C /* Build configuration list for PBXProject "RevealStack" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 535B22501E915D1C002F6D4C; + productRefGroup = 535B225A1E915D1C002F6D4C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 535B22581E915D1C002F6D4C /* RevealStack */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 535B22571E915D1C002F6D4C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 535B22671E915D1C002F6D4C /* LaunchScreen.storyboard in Resources */, + 535B22641E915D1C002F6D4C /* Assets.xcassets in Resources */, + 535B22621E915D1C002F6D4C /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 535B22551E915D1C002F6D4C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 535B225D1E915D1C002F6D4C /* AppDelegate.swift in Sources */, + 535B226F1E915D7B002F6D4C /* RevealViewController.swift in Sources */, + 535B22711E915DA7002F6D4C /* UIView+UYLExtensions.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 535B22601E915D1C002F6D4C /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 535B22611E915D1C002F6D4C /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 535B22651E915D1C002F6D4C /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 535B22661E915D1C002F6D4C /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 535B22691E915D1C002F6D4C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 535B226A1E915D1C002F6D4C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 535B226C1E915D1C002F6D4C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RevealStack/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RevealStack; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 535B226D1E915D1C002F6D4C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = RevealStack/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.RevealStack; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 535B22541E915D1C002F6D4C /* Build configuration list for PBXProject "RevealStack" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 535B22691E915D1C002F6D4C /* Debug */, + 535B226A1E915D1C002F6D4C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 535B226B1E915D1C002F6D4C /* Build configuration list for PBXNativeTarget "RevealStack" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 535B226C1E915D1C002F6D4C /* Debug */, + 535B226D1E915D1C002F6D4C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 535B22511E915D1C002F6D4C /* Project object */; +} diff --git a/RevealStack/RevealStack/AppDelegate.swift b/RevealStack/RevealStack/AppDelegate.swift new file mode 100644 index 0000000..62ee578 --- /dev/null +++ b/RevealStack/RevealStack/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// RevealStack +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/RevealStack/RevealStack/Assets.xcassets/AppIcon.appiconset/Contents.json b/RevealStack/RevealStack/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/RevealStack/RevealStack/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RevealStack/RevealStack/Assets.xcassets/Contents.json b/RevealStack/RevealStack/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/RevealStack/RevealStack/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/Contents.json b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/Contents.json new file mode 100644 index 0000000..581c8f1 --- /dev/null +++ b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "heart100.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "heart200.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "heart300.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart100.png b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart100.png new file mode 100644 index 0000000..d6be769 Binary files /dev/null and b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart100.png differ diff --git a/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart200.png b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart200.png new file mode 100644 index 0000000..932019f Binary files /dev/null and b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart200.png differ diff --git a/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart300.png b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart300.png new file mode 100644 index 0000000..c24ae62 Binary files /dev/null and b/RevealStack/RevealStack/Assets.xcassets/Heart.imageset/heart300.png differ diff --git a/RevealStack/RevealStack/Assets.xcassets/Star.imageset/Contents.json b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/Contents.json new file mode 100644 index 0000000..9ee1843 --- /dev/null +++ b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "star100.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "star200.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "star300.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star100.png b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star100.png new file mode 100644 index 0000000..4965255 Binary files /dev/null and b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star100.png differ diff --git a/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star200.png b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star200.png new file mode 100644 index 0000000..49311bc Binary files /dev/null and b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star200.png differ diff --git a/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star300.png b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star300.png new file mode 100644 index 0000000..d46d41b Binary files /dev/null and b/RevealStack/RevealStack/Assets.xcassets/Star.imageset/star300.png differ diff --git a/RevealStack/RevealStack/Base.lproj/LaunchScreen.storyboard b/RevealStack/RevealStack/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/RevealStack/RevealStack/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RevealStack/RevealStack/Base.lproj/Main.storyboard b/RevealStack/RevealStack/Base.lproj/Main.storyboard new file mode 100644 index 0000000..d3bf493 --- /dev/null +++ b/RevealStack/RevealStack/Base.lproj/Main.storyboard @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RevealStack/RevealStack/Info.plist b/RevealStack/RevealStack/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/RevealStack/RevealStack/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/RevealStack/RevealStack/RevealViewController.swift b/RevealStack/RevealStack/RevealViewController.swift new file mode 100644 index 0000000..73eaeed --- /dev/null +++ b/RevealStack/RevealStack/RevealViewController.swift @@ -0,0 +1,82 @@ +// +// RevealViewController.swift +// RevealStack +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class RevealViewController: UIViewController { + @IBOutlet private var rootStackView: UIStackView! + @IBOutlet private var imageStackView: UIStackView! + @IBOutlet private var revealSwitch: UISwitch! + + private lazy var coverView: UIView = { + let view = UIView() + view.backgroundColor = .yellow + return view + }() + + private lazy var backgroundView: UIView = { + let view = UIView() + view.backgroundColor = .purple + view.layer.cornerRadius = 10.0 + return view + }() + + @IBAction func revealAction(_ sender: UISwitch) { + UIView.animate(withDuration: 0.25) { + self.configureReveal() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + pinBackground(backgroundView, to: rootStackView) + pinForeground(coverView, to: imageStackView) + configureReveal() + } + + private func configureReveal() { + coverView.alpha = revealSwitch.isOn ? 0 : 1.0 + } + + private func pinBackground(_ view: UIView, to stackView: UIStackView) { + view.translatesAutoresizingMaskIntoConstraints = false + stackView.insertSubview(view, at: 0) + view.pin(to: stackView) + } + + private func pinForeground(_ view: UIView, to stackView: UIStackView) { + view.translatesAutoresizingMaskIntoConstraints = false + stackView.addSubview(view) + view.pin(to: stackView) + } +} diff --git a/RevealStack/RevealStack/UIView+UYLExtensions.swift b/RevealStack/RevealStack/UIView+UYLExtensions.swift new file mode 100644 index 0000000..25b5b9e --- /dev/null +++ b/RevealStack/RevealStack/UIView+UYLExtensions.swift @@ -0,0 +1,44 @@ +// +// UIView+UYLExtensions.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +public extension UIView { + func pin(to view: UIView) { + NSLayoutConstraint.activate([ + leadingAnchor.constraint(equalTo: view.leadingAnchor), + trailingAnchor.constraint(equalTo: view.trailingAnchor), + topAnchor.constraint(equalTo: view.topAnchor), + bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } +} diff --git a/ScaledFont/README.md b/ScaledFont/README.md new file mode 100644 index 0000000..d54fccd --- /dev/null +++ b/ScaledFont/README.md @@ -0,0 +1,44 @@ +# Scaled Font + +## Using Dynamic Type With Custom Fonts + +An example of using custom fonts with dynamic type making use of the `UIFontMetrics` class introduced with iOS 11. It provides examples using the Noteworthy font which is built-in to iOS and the Noto Serif font which was downloaded from google fonts: + ++ [Noto Serif](https://fonts.google.com/specimen/Noto+Serif?selection.family=Noto+Serif) + +*Refer to LICENSE.txt if you plan on using Noto Serif in a shipping application.* + +**This project requires iOS 11** + +### ScaledFont + +A utility class to help you use custom fonts with dynamic type. + +To use this class you must supply the name of a style dictionary for the font when creating the class. The style dictionary should be stored as a property list file in the main bundle. + +The style dictionary contains an entry for each text style that uses the raw string value for each `UIFontTextStyle` as the key. + +The value of each entry is a dictionary with two keys: + ++ fontName: A String which is the font name. ++ fontSize: A number which is the point size to use at the `.large` content size. + +For example to use a 17 pt Noteworthy-Bold font for the `.headline` style at the `.large` content size: + + + UICTFontTextStyleHeadline + + fontName + Noteworthy-Bold + fontSize + 17 + + + +You do not need to include an entry for every text style but if you try to use a text style that is not included in the dictionary it will fallback to the system preferred font. + +### Further Details + +See the following blog post for further details: + ++ [Using A Custom Font With Dynamic Type](https://useyourloaf.com/blog/using-a-custom-font-with-dynamic-type/) diff --git a/ScaledFont/ScaledFont.xcodeproj/project.pbxproj b/ScaledFont/ScaledFont.xcodeproj/project.pbxproj new file mode 100644 index 0000000..59a6cc6 --- /dev/null +++ b/ScaledFont/ScaledFont.xcodeproj/project.pbxproj @@ -0,0 +1,374 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 537709DB1F4061130041A64F /* Noteworthy.plist in Resources */ = {isa = PBXBuildFile; fileRef = 537919321F3FA0CF00FF9E25 /* Noteworthy.plist */; }; + 537709E21F40B0650041A64F /* NotoSerif-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 537709DE1F40AFD80041A64F /* NotoSerif-Bold.ttf */; }; + 537709E31F40B06B0041A64F /* NotoSerif-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 537709E11F40AFD80041A64F /* NotoSerif-Regular.ttf */; }; + 537709E41F40B06F0041A64F /* NotoSerif-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 537709E01F40AFD80041A64F /* NotoSerif-Italic.ttf */; }; + 537709E61F40B18B0041A64F /* NotoSerif.plist in Resources */ = {isa = PBXBuildFile; fileRef = 537709E51F40B18B0041A64F /* NotoSerif.plist */; }; + 5379191F1F3FA05700FF9E25 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5379191E1F3FA05700FF9E25 /* AppDelegate.swift */; }; + 537919211F3FA05700FF9E25 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537919201F3FA05700FF9E25 /* ViewController.swift */; }; + 537919241F3FA05700FF9E25 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 537919221F3FA05700FF9E25 /* Main.storyboard */; }; + 537919261F3FA05700FF9E25 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 537919251F3FA05700FF9E25 /* Assets.xcassets */; }; + 537919291F3FA05700FF9E25 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 537919271F3FA05700FF9E25 /* LaunchScreen.storyboard */; }; + 537919311F3FA0B500FF9E25 /* ScaledFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537919301F3FA0B500FF9E25 /* ScaledFont.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 537709DD1F40AFD80041A64F /* LICENSE.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; }; + 537709DE1F40AFD80041A64F /* NotoSerif-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-Bold.ttf"; sourceTree = ""; }; + 537709DF1F40AFD80041A64F /* NotoSerif-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-BoldItalic.ttf"; sourceTree = ""; }; + 537709E01F40AFD80041A64F /* NotoSerif-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-Italic.ttf"; sourceTree = ""; }; + 537709E11F40AFD80041A64F /* NotoSerif-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-Regular.ttf"; sourceTree = ""; }; + 537709E51F40B18B0041A64F /* NotoSerif.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = NotoSerif.plist; sourceTree = ""; }; + 537709E71F40F3B80041A64F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 5379191B1F3FA05700FF9E25 /* ScaledFont.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScaledFont.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5379191E1F3FA05700FF9E25 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 537919201F3FA05700FF9E25 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 537919231F3FA05700FF9E25 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 537919251F3FA05700FF9E25 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 537919281F3FA05700FF9E25 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5379192A1F3FA05700FF9E25 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 537919301F3FA0B500FF9E25 /* ScaledFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaledFont.swift; sourceTree = ""; }; + 537919321F3FA0CF00FF9E25 /* Noteworthy.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Noteworthy.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 537919181F3FA05700FF9E25 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 537709DC1F40AFD80041A64F /* Noto_Serif */ = { + isa = PBXGroup; + children = ( + 537709DD1F40AFD80041A64F /* LICENSE.txt */, + 537709DE1F40AFD80041A64F /* NotoSerif-Bold.ttf */, + 537709DF1F40AFD80041A64F /* NotoSerif-BoldItalic.ttf */, + 537709E01F40AFD80041A64F /* NotoSerif-Italic.ttf */, + 537709E11F40AFD80041A64F /* NotoSerif-Regular.ttf */, + ); + path = Noto_Serif; + sourceTree = ""; + }; + 537919121F3FA05700FF9E25 = { + isa = PBXGroup; + children = ( + 537709E71F40F3B80041A64F /* README.md */, + 5379191D1F3FA05700FF9E25 /* ScaledFont */, + 5379191C1F3FA05700FF9E25 /* Products */, + ); + sourceTree = ""; + }; + 5379191C1F3FA05700FF9E25 /* Products */ = { + isa = PBXGroup; + children = ( + 5379191B1F3FA05700FF9E25 /* ScaledFont.app */, + ); + name = Products; + sourceTree = ""; + }; + 5379191D1F3FA05700FF9E25 /* ScaledFont */ = { + isa = PBXGroup; + children = ( + 537709DC1F40AFD80041A64F /* Noto_Serif */, + 5379191E1F3FA05700FF9E25 /* AppDelegate.swift */, + 537919201F3FA05700FF9E25 /* ViewController.swift */, + 537919301F3FA0B500FF9E25 /* ScaledFont.swift */, + 537919321F3FA0CF00FF9E25 /* Noteworthy.plist */, + 537709E51F40B18B0041A64F /* NotoSerif.plist */, + 537919221F3FA05700FF9E25 /* Main.storyboard */, + 537919251F3FA05700FF9E25 /* Assets.xcassets */, + 537919271F3FA05700FF9E25 /* LaunchScreen.storyboard */, + 5379192A1F3FA05700FF9E25 /* Info.plist */, + ); + path = ScaledFont; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5379191A1F3FA05700FF9E25 /* ScaledFont */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5379192D1F3FA05700FF9E25 /* Build configuration list for PBXNativeTarget "ScaledFont" */; + buildPhases = ( + 537919171F3FA05700FF9E25 /* Sources */, + 537919181F3FA05700FF9E25 /* Frameworks */, + 537919191F3FA05700FF9E25 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ScaledFont; + productName = ScaledFont; + productReference = 5379191B1F3FA05700FF9E25 /* ScaledFont.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 537919131F3FA05700FF9E25 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0900; + LastUpgradeCheck = 0940; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 5379191A1F3FA05700FF9E25 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 1020; + }; + }; + }; + buildConfigurationList = 537919161F3FA05700FF9E25 /* Build configuration list for PBXProject "ScaledFont" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 537919121F3FA05700FF9E25; + productRefGroup = 5379191C1F3FA05700FF9E25 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5379191A1F3FA05700FF9E25 /* ScaledFont */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 537919191F3FA05700FF9E25 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 537919291F3FA05700FF9E25 /* LaunchScreen.storyboard in Resources */, + 537709E31F40B06B0041A64F /* NotoSerif-Regular.ttf in Resources */, + 537709E61F40B18B0041A64F /* NotoSerif.plist in Resources */, + 537709E41F40B06F0041A64F /* NotoSerif-Italic.ttf in Resources */, + 537709DB1F4061130041A64F /* Noteworthy.plist in Resources */, + 537709E21F40B0650041A64F /* NotoSerif-Bold.ttf in Resources */, + 537919261F3FA05700FF9E25 /* Assets.xcassets in Resources */, + 537919241F3FA05700FF9E25 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 537919171F3FA05700FF9E25 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 537919311F3FA0B500FF9E25 /* ScaledFont.swift in Sources */, + 537919211F3FA05700FF9E25 /* ViewController.swift in Sources */, + 5379191F1F3FA05700FF9E25 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 537919221F3FA05700FF9E25 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 537919231F3FA05700FF9E25 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 537919271F3FA05700FF9E25 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 537919281F3FA05700FF9E25 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5379192B1F3FA05700FF9E25 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 5379192C1F3FA05700FF9E25 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5379192E1F3FA05700FF9E25 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ScaledFont/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ScaledFont; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5379192F1F3FA05700FF9E25 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ScaledFont/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ScaledFont; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 537919161F3FA05700FF9E25 /* Build configuration list for PBXProject "ScaledFont" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5379192B1F3FA05700FF9E25 /* Debug */, + 5379192C1F3FA05700FF9E25 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5379192D1F3FA05700FF9E25 /* Build configuration list for PBXNativeTarget "ScaledFont" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5379192E1F3FA05700FF9E25 /* Debug */, + 5379192F1F3FA05700FF9E25 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 537919131F3FA05700FF9E25 /* Project object */; +} diff --git a/ScaledFont/ScaledFont/AppDelegate.swift b/ScaledFont/ScaledFont/AppDelegate.swift new file mode 100644 index 0000000..6420758 --- /dev/null +++ b/ScaledFont/ScaledFont/AppDelegate.swift @@ -0,0 +1,35 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/ScaledFont/ScaledFont/Assets.xcassets/AppIcon.appiconset/Contents.json b/ScaledFont/ScaledFont/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/ScaledFont/ScaledFont/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ScaledFont/ScaledFont/Base.lproj/LaunchScreen.storyboard b/ScaledFont/ScaledFont/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f83f6fd --- /dev/null +++ b/ScaledFont/ScaledFont/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ScaledFont/ScaledFont/Base.lproj/Main.storyboard b/ScaledFont/ScaledFont/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f995ddd --- /dev/null +++ b/ScaledFont/ScaledFont/Base.lproj/Main.storyboard @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ScaledFont/ScaledFont/Info.plist b/ScaledFont/ScaledFont/Info.plist new file mode 100644 index 0000000..24cd042 --- /dev/null +++ b/ScaledFont/ScaledFont/Info.plist @@ -0,0 +1,52 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIAppFonts + + NotoSerif-Regular.ttf + NotoSerif-Bold.ttf + NotoSerif-Italic.ttf + + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ScaledFont/ScaledFont/Noteworthy.plist b/ScaledFont/ScaledFont/Noteworthy.plist new file mode 100644 index 0000000..4395e75 --- /dev/null +++ b/ScaledFont/ScaledFont/Noteworthy.plist @@ -0,0 +1,83 @@ + + + + + UICTFontTextStyleTitle0 + + fontName + Noteworthy-Light + fontSize + 34 + + UICTFontTextStyleTitle1 + + fontName + Noteworthy-Light + fontSize + 28 + + UICTFontTextStyleTitle2 + + fontName + Noteworthy-Light + fontSize + 22 + + UICTFontTextStyleTitle3 + + fontName + Noteworthy-Light + fontSize + 20 + + UICTFontTextStyleHeadline + + fontName + Noteworthy-Bold + fontSize + 17 + + UICTFontTextStyleSubhead + + fontName + Noteworthy-Light + fontSize + 15 + + UICTFontTextStyleBody + + fontName + Noteworthy-Light + fontSize + 17 + + UICTFontTextStyleCallout + + fontName + Noteworthy-Light + fontSize + 16 + + UICTFontTextStyleFootnote + + fontName + Noteworthy-Light + fontSize + 13 + + UICTFontTextStyleCaption1 + + fontName + Noteworthy-Light + fontSize + 12 + + UICTFontTextStyleCaption2 + + fontName + Noteworthy-Light + fontSize + 11 + + + diff --git a/ScaledFont/ScaledFont/NotoSerif.plist b/ScaledFont/ScaledFont/NotoSerif.plist new file mode 100644 index 0000000..2d35c45 --- /dev/null +++ b/ScaledFont/ScaledFont/NotoSerif.plist @@ -0,0 +1,83 @@ + + + + + UICTFontTextStyleTitle0 + + fontName + NotoSerif + fontSize + 34 + + UICTFontTextStyleTitle1 + + fontName + NotoSerif + fontSize + 28 + + UICTFontTextStyleTitle2 + + fontName + NotoSerif + fontSize + 22 + + UICTFontTextStyleTitle3 + + fontName + NotoSerif + fontSize + 20 + + UICTFontTextStyleHeadline + + fontName + NotoSerif-Bold + fontSize + 17 + + UICTFontTextStyleSubhead + + fontName + NotoSerif-Italic + fontSize + 15 + + UICTFontTextStyleBody + + fontName + NotoSerif + fontSize + 17 + + UICTFontTextStyleCallout + + fontName + NotoSerif + fontSize + 16 + + UICTFontTextStyleFootnote + + fontName + NotoSerif + fontSize + 13 + + UICTFontTextStyleCaption1 + + fontName + NotoSerif-Italic + fontSize + 12 + + UICTFontTextStyleCaption2 + + fontName + NotoSerif-Italic + fontSize + 10 + + + diff --git a/ScaledFont/ScaledFont/Noto_Serif/LICENSE.txt b/ScaledFont/ScaledFont/Noto_Serif/LICENSE.txt new file mode 100755 index 0000000..75b5248 --- /dev/null +++ b/ScaledFont/ScaledFont/Noto_Serif/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Bold.ttf b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Bold.ttf new file mode 100755 index 0000000..580ff28 Binary files /dev/null and b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Bold.ttf differ diff --git a/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-BoldItalic.ttf b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-BoldItalic.ttf new file mode 100755 index 0000000..32d38af Binary files /dev/null and b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-BoldItalic.ttf differ diff --git a/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Italic.ttf b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Italic.ttf new file mode 100755 index 0000000..1d3cc3a Binary files /dev/null and b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Italic.ttf differ diff --git a/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Regular.ttf b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Regular.ttf new file mode 100755 index 0000000..a1c6f10 Binary files /dev/null and b/ScaledFont/ScaledFont/Noto_Serif/NotoSerif-Regular.ttf differ diff --git a/ScaledFont/ScaledFont/ScaledFont.swift b/ScaledFont/ScaledFont/ScaledFont.swift new file mode 100644 index 0000000..09b8b81 --- /dev/null +++ b/ScaledFont/ScaledFont/ScaledFont.swift @@ -0,0 +1,113 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +/// A utility class to help you use custom fonts with +/// dynamic type. +/// +/// To use this class you must supply the name of a style +/// dictionary for the font when creating the class. The +/// style dictionary should be stored as a property list +/// file in the main bundle. +/// +/// The style dictionary contains an entry for each text +/// style that uses the raw string value for each +/// `UIFontTextStyle` as the key. +/// +/// The value of each entry is a dictionary with two keys: +/// +/// + fontName: A String which is the font name. +/// + fontSize: A number which is the point size to use +/// at the `.large` content size. +/// +/// For example to use a 17 pt Noteworthy-Bold font +/// for the `.headline` style at the `.large` content size: +/// +/// +/// UICTFontTextStyleHeadline +/// +/// fontName +/// Noteworthy-Bold +/// fontSize +/// 17 +/// +/// +/// +/// You do not need to include an entry for every text style +/// but if you try to use a text style that is not included +/// in the dictionary it will fallback to the system preferred +/// font. + +public final class ScaledFont { + private struct FontDescription: Decodable { + let fontSize: CGFloat + let fontName: String + } + + private typealias StyleDictionary = [UIFont.TextStyle.RawValue: FontDescription] + private var styleDictionary: StyleDictionary? + + /// Create a `ScaledFont` + /// + /// - Parameter fontName: Name of a plist file (without the extension) + /// in the main bundle that contains the style dictionary used to + /// scale fonts for each text style. + + public init(fontName: String) { + if let url = Bundle.main.url(forResource: fontName, withExtension: "plist"), + let data = try? Data(contentsOf: url) { + let decoder = PropertyListDecoder() + styleDictionary = try? decoder.decode(StyleDictionary.self, from: data) + } + } + + /// Get the scaled font for the given text style using the + /// style dictionary supplied at initialization. + /// + /// - Parameter textStyle: The `UIFontTextStyle` for the + /// font. + /// - Returns: A `UIFont` of the custom font that has been + /// scaled for the users currently selected preferred + /// text size. + /// + /// - Note: If the style dictionary does not have + /// a font for this text style the default preferred + /// font is returned. + + public func font(forTextStyle textStyle: UIFont.TextStyle) -> UIFont { + guard let fontDescription = styleDictionary?[textStyle.rawValue], + let font = UIFont(name: fontDescription.fontName, size: fontDescription.fontSize) else { + return UIFont.preferredFont(forTextStyle: textStyle) + } + + let fontMetrics = UIFontMetrics(forTextStyle: textStyle) + return fontMetrics.scaledFont(for: font) + } +} diff --git a/ScaledFont/ScaledFont/ViewController.swift b/ScaledFont/ScaledFont/ViewController.swift new file mode 100644 index 0000000..315a7fd --- /dev/null +++ b/ScaledFont/ScaledFont/ViewController.swift @@ -0,0 +1,124 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class ViewController: UIViewController { +// private let fontName = "Default" +// private let fontName = "Noteworthy" + private let fontName = "NotoSerif" + + private let defaultSpacing: CGFloat = 8.0 + + private lazy var scaledFont: ScaledFont = { + ScaledFont(fontName: fontName) + }() + + override func viewDidLoad() { + super.viewDidLoad() + title = fontName + setupViews() + } + + private lazy var title1Label: UILabel = { + label(forTextStyle: .title1, text: "Title 1") + }() + + private lazy var title2Label: UILabel = { + label(forTextStyle: .title2, text: "Title 2") + }() + + private lazy var title3Label: UILabel = { + label(forTextStyle: .title3, text: "Title 3") + }() + + private lazy var headlineLabel: UILabel = { + label(forTextStyle: .headline, text: "Headline") + }() + + private lazy var subheadlineLabel: UILabel = { + label(forTextStyle: .subheadline, text: "Subheadline") + }() + + private lazy var bodyLabel: UILabel = { + label(forTextStyle: .body, text: "Body") + }() + + private lazy var calloutLabel: UILabel = { + label(forTextStyle: .callout, text: "Callout") + }() + + private lazy var footnoteLabel: UILabel = { + label(forTextStyle: .footnote, text: "Footnote") + }() + + private lazy var caption1Label: UILabel = { + label(forTextStyle: .caption1, text: "Caption 1") + }() + + private lazy var caption2Label: UILabel = { + label(forTextStyle: .caption2, text: "Caption 2") + }() + + private func label(forTextStyle textStyle: UIFont.TextStyle, text: String) -> UILabel { + let label = UILabel() + label.font = scaledFont.font(forTextStyle: textStyle) + label.adjustsFontForContentSizeCategory = true + label.text = text + label.numberOfLines = 0 + return label + } + + private func setupViews() { + let stackView = UIStackView(arrangedSubviews: [title1Label, title2Label, title3Label, headlineLabel, subheadlineLabel, bodyLabel, calloutLabel, footnoteLabel, caption1Label, caption2Label]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.spacing = defaultSpacing + stackView.axis = .vertical + + let scrollView = UIScrollView() + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(stackView) + view.addSubview(scrollView) + + let margins = view.readableContentGuide + NSLayoutConstraint.activate([ + scrollView.topAnchor.constraint(equalTo: margins.topAnchor), + scrollView.bottomAnchor.constraint(equalTo: margins.bottomAnchor), + scrollView.leadingAnchor.constraint(equalTo: margins.leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: margins.trailingAnchor), + + scrollView.topAnchor.constraint(equalTo: stackView.topAnchor), + scrollView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor), + scrollView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: stackView.trailingAnchor), + + scrollView.widthAnchor.constraint(equalTo: stackView.widthAnchor) + ]) + } +} diff --git a/ScrollGuide-IB/README.md b/ScrollGuide-IB/README.md new file mode 100644 index 0000000..5193288 --- /dev/null +++ b/ScrollGuide-IB/README.md @@ -0,0 +1,9 @@ +# Scroll View Layout Guides + +Xcode 11 adds direct support for the content layout guides of a `UIScrollView` to Interface Builder. See the following post for details: + ++ [Scroll View Layouts With Interface Builder](https://useyourloaf.com/blog/scroll-view-layouts-with-interface-builder/) + +You can compare the Interface Builder version of the layout with the progammatic version described in this earlier post: + ++ [Easier Scrolling With Layout Guides](https://useyourloaf.com/blog/easier-scrolling-with-layout-guides/) diff --git a/ScrollGuide-IB/ScrollGuide-IB.xcodeproj/project.pbxproj b/ScrollGuide-IB/ScrollGuide-IB.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5622ba2 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB.xcodeproj/project.pbxproj @@ -0,0 +1,345 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 537CC979232BD70800424444 /* ForecastViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537CC978232BD70800424444 /* ForecastViewController.swift */; }; + 537CC97B232BD80300424444 /* Forecast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537CC97A232BD80300424444 /* Forecast.swift */; }; + 53926B86232BD49B0070DCB1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53926B85232BD49B0070DCB1 /* AppDelegate.swift */; }; + 53926B8D232BD49B0070DCB1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53926B8B232BD49B0070DCB1 /* Main.storyboard */; }; + 53926B8F232BD49B0070DCB1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53926B8E232BD49B0070DCB1 /* Assets.xcassets */; }; + 53926B92232BD49B0070DCB1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53926B90232BD49B0070DCB1 /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 537CC978232BD70800424444 /* ForecastViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastViewController.swift; sourceTree = ""; }; + 537CC97A232BD80300424444 /* Forecast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Forecast.swift; sourceTree = ""; }; + 537CC99C23301D1800424444 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53926B82232BD49B0070DCB1 /* ScrollGuide-IB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ScrollGuide-IB.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 53926B85232BD49B0070DCB1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53926B8C232BD49B0070DCB1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53926B8E232BD49B0070DCB1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53926B91232BD49B0070DCB1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53926B93232BD49B0070DCB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53926B7F232BD49B0070DCB1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53926B79232BD49B0070DCB1 = { + isa = PBXGroup; + children = ( + 537CC99C23301D1800424444 /* README.md */, + 53926B84232BD49B0070DCB1 /* ScrollGuide-IB */, + 53926B83232BD49B0070DCB1 /* Products */, + ); + sourceTree = ""; + }; + 53926B83232BD49B0070DCB1 /* Products */ = { + isa = PBXGroup; + children = ( + 53926B82232BD49B0070DCB1 /* ScrollGuide-IB.app */, + ); + name = Products; + sourceTree = ""; + }; + 53926B84232BD49B0070DCB1 /* ScrollGuide-IB */ = { + isa = PBXGroup; + children = ( + 537CC978232BD70800424444 /* ForecastViewController.swift */, + 537CC97A232BD80300424444 /* Forecast.swift */, + 53926B85232BD49B0070DCB1 /* AppDelegate.swift */, + 53926B8B232BD49B0070DCB1 /* Main.storyboard */, + 53926B8E232BD49B0070DCB1 /* Assets.xcassets */, + 53926B90232BD49B0070DCB1 /* LaunchScreen.storyboard */, + 53926B93232BD49B0070DCB1 /* Info.plist */, + ); + path = "ScrollGuide-IB"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53926B81232BD49B0070DCB1 /* ScrollGuide-IB */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53926B96232BD49B0070DCB1 /* Build configuration list for PBXNativeTarget "ScrollGuide-IB" */; + buildPhases = ( + 53926B7E232BD49B0070DCB1 /* Sources */, + 53926B7F232BD49B0070DCB1 /* Frameworks */, + 53926B80232BD49B0070DCB1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "ScrollGuide-IB"; + productName = "ScrollGuide-IB"; + productReference = 53926B82232BD49B0070DCB1 /* ScrollGuide-IB.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53926B7A232BD49B0070DCB1 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53926B81232BD49B0070DCB1 = { + CreatedOnToolsVersion = 11.0; + }; + }; + }; + buildConfigurationList = 53926B7D232BD49B0070DCB1 /* Build configuration list for PBXProject "ScrollGuide-IB" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53926B79232BD49B0070DCB1; + productRefGroup = 53926B83232BD49B0070DCB1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53926B81232BD49B0070DCB1 /* ScrollGuide-IB */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53926B80232BD49B0070DCB1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53926B92232BD49B0070DCB1 /* LaunchScreen.storyboard in Resources */, + 53926B8F232BD49B0070DCB1 /* Assets.xcassets in Resources */, + 53926B8D232BD49B0070DCB1 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53926B7E232BD49B0070DCB1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53926B86232BD49B0070DCB1 /* AppDelegate.swift in Sources */, + 537CC97B232BD80300424444 /* Forecast.swift in Sources */, + 537CC979232BD70800424444 /* ForecastViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53926B8B232BD49B0070DCB1 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53926B8C232BD49B0070DCB1 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53926B90232BD49B0070DCB1 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53926B91232BD49B0070DCB1 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53926B94232BD49B0070DCB1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53926B95232BD49B0070DCB1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53926B97232BD49B0070DCB1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = "ScrollGuide-IB/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.ScrollGuide-IB"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53926B98232BD49B0070DCB1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = "ScrollGuide-IB/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.ScrollGuide-IB"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53926B7D232BD49B0070DCB1 /* Build configuration list for PBXProject "ScrollGuide-IB" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53926B94232BD49B0070DCB1 /* Debug */, + 53926B95232BD49B0070DCB1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53926B96232BD49B0070DCB1 /* Build configuration list for PBXNativeTarget "ScrollGuide-IB" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53926B97232BD49B0070DCB1 /* Debug */, + 53926B98232BD49B0070DCB1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53926B7A232BD49B0070DCB1 /* Project object */; +} diff --git a/ScrollGuide-IB/ScrollGuide-IB/AppDelegate.swift b/ScrollGuide-IB/ScrollGuide-IB/AppDelegate.swift new file mode 100644 index 0000000..a95b2c1 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/AppDelegate.swift @@ -0,0 +1,43 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + if let navigationController = window?.rootViewController as? UINavigationController, + let forecastViewController = navigationController.topViewController as? ForecastViewController { + let forecast = Forecast(title: "Weather For Today", condition: .sun, summary: "Today will be hot and sunny. If you are going out you will need a hat and sunglasses. There is a small chance of a heavy thunderstorm in the afternoon that could cause severe flooding so you may also want to take a boat.") + forecastViewController.forecast = forecast + } + return true + } +} diff --git a/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/AppIcon.appiconset/Contents.json b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Contents.json b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/SkyBlue.colorset/Contents.json b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/SkyBlue.colorset/Contents.json new file mode 100644 index 0000000..1f49b00 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/SkyBlue.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.463", + "alpha" : "1.000", + "blue" : "1.000", + "green" : "0.835" + } + } + } + ] +} \ No newline at end of file diff --git a/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Sun.imageset/Contents.json b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Sun.imageset/Contents.json new file mode 100644 index 0000000..d73dd65 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Sun.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Sun150.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Sun.imageset/Sun150.pdf b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Sun.imageset/Sun150.pdf new file mode 100644 index 0000000..0715bf8 Binary files /dev/null and b/ScrollGuide-IB/ScrollGuide-IB/Assets.xcassets/Sun.imageset/Sun150.pdf differ diff --git a/ScrollGuide-IB/ScrollGuide-IB/Base.lproj/LaunchScreen.storyboard b/ScrollGuide-IB/ScrollGuide-IB/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fc2d48c --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ScrollGuide-IB/ScrollGuide-IB/Base.lproj/Main.storyboard b/ScrollGuide-IB/ScrollGuide-IB/Base.lproj/Main.storyboard new file mode 100644 index 0000000..a0fc3ec --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Base.lproj/Main.storyboard @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ScrollGuide-IB/ScrollGuide-IB/Forecast.swift b/ScrollGuide-IB/ScrollGuide-IB/Forecast.swift new file mode 100644 index 0000000..a36cd4d --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Forecast.swift @@ -0,0 +1,49 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +public struct Forecast { + public enum Condition { + case sun + // other conditions... + } + + let title: String + let condition: Condition + let summary: String +} + +public extension Forecast { + func icon() -> UIImage { + switch condition { + case .sun: return UIImage(named: "Sun")! + // other conditions... + } + } +} diff --git a/ScrollGuide-IB/ScrollGuide-IB/ForecastViewController.swift b/ScrollGuide-IB/ScrollGuide-IB/ForecastViewController.swift new file mode 100644 index 0000000..35e972a --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/ForecastViewController.swift @@ -0,0 +1,57 @@ +// Copyright © 2019 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class ForecastViewController: UIViewController { + @IBOutlet private var titleLabel: UILabel? + @IBOutlet private var summaryLabel: UILabel? + @IBOutlet private var imageView: UIImageView? + + var forecast: Forecast? { didSet { updateView() } } + + private func updateView() { + if let forecast = forecast { + titleLabel?.text = forecast.title + summaryLabel?.text = forecast.summary + imageView?.image = forecast.icon() + imageView?.sizeToFit() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + updateView() + } +} + +extension ForecastViewController { + @IBAction private func showInfo(_ sender: UIButton) { + print("Show Info") + } +} diff --git a/ScrollGuide-IB/ScrollGuide-IB/Info.plist b/ScrollGuide-IB/ScrollGuide-IB/Info.plist new file mode 100644 index 0000000..8f416d0 --- /dev/null +++ b/ScrollGuide-IB/ScrollGuide-IB/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ScrollGuide/README.md b/ScrollGuide/README.md new file mode 100644 index 0000000..73909f2 --- /dev/null +++ b/ScrollGuide/README.md @@ -0,0 +1,9 @@ +# Scroll View Layout Guides + +An example of using the two new layout guides added to `UIScrollView` in iOS 11. See the following post for details: + ++ [Easier Scrolling With Layout Guides](https://useyourloaf.com/blog/easier-scrolling-with-layout-guides/) + +Starting with Xcode 11 the content layout guides are available in Interface Builder. See this later post for a version of this layout built entirely with Interface Builder: + ++ [Scroll View Layouts With Interface Builder](https://useyourloaf.com/blog/scroll-view-layouts-with-interface-builder/) diff --git a/ScrollGuide/ScrollGuide.xcodeproj/project.pbxproj b/ScrollGuide/ScrollGuide.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d35b6dd --- /dev/null +++ b/ScrollGuide/ScrollGuide.xcodeproj/project.pbxproj @@ -0,0 +1,344 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 53FD5C342126C480008DA03A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FD5C332126C480008DA03A /* AppDelegate.swift */; }; + 53FD5C382126C481008DA03A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53FD5C372126C481008DA03A /* Assets.xcassets */; }; + 53FD5C3B2126C481008DA03A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53FD5C392126C481008DA03A /* LaunchScreen.storyboard */; }; + 53FD5C432126C514008DA03A /* ForecastViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FD5C422126C514008DA03A /* ForecastViewController.swift */; }; + 53FD5C452126C533008DA03A /* ForecastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FD5C442126C533008DA03A /* ForecastView.swift */; }; + 53FD5C492126C5DA008DA03A /* Forecast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FD5C482126C5DA008DA03A /* Forecast.swift */; }; + 53FD5C4B2126C617008DA03A /* UILabel+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FD5C4A2126C617008DA03A /* UILabel+Style.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53B5CE7C212AEBDA00FF5FCB /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 53FD5C302126C480008DA03A /* ScrollGuide.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScrollGuide.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53FD5C332126C480008DA03A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53FD5C372126C481008DA03A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53FD5C3A2126C481008DA03A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53FD5C3C2126C481008DA03A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53FD5C422126C514008DA03A /* ForecastViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastViewController.swift; sourceTree = ""; }; + 53FD5C442126C533008DA03A /* ForecastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForecastView.swift; sourceTree = ""; }; + 53FD5C482126C5DA008DA03A /* Forecast.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Forecast.swift; sourceTree = ""; }; + 53FD5C4A2126C617008DA03A /* UILabel+Style.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILabel+Style.swift"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53FD5C2D2126C480008DA03A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53FD5C272126C480008DA03A = { + isa = PBXGroup; + children = ( + 53B5CE7C212AEBDA00FF5FCB /* README.md */, + 53FD5C322126C480008DA03A /* ScrollGuide */, + 53FD5C312126C480008DA03A /* Products */, + ); + sourceTree = ""; + }; + 53FD5C312126C480008DA03A /* Products */ = { + isa = PBXGroup; + children = ( + 53FD5C302126C480008DA03A /* ScrollGuide.app */, + ); + name = Products; + sourceTree = ""; + }; + 53FD5C322126C480008DA03A /* ScrollGuide */ = { + isa = PBXGroup; + children = ( + 53FD5C4A2126C617008DA03A /* UILabel+Style.swift */, + 53FD5C332126C480008DA03A /* AppDelegate.swift */, + 53FD5C422126C514008DA03A /* ForecastViewController.swift */, + 53FD5C442126C533008DA03A /* ForecastView.swift */, + 53FD5C482126C5DA008DA03A /* Forecast.swift */, + 53FD5C372126C481008DA03A /* Assets.xcassets */, + 53FD5C392126C481008DA03A /* LaunchScreen.storyboard */, + 53FD5C3C2126C481008DA03A /* Info.plist */, + ); + path = ScrollGuide; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53FD5C2F2126C480008DA03A /* ScrollGuide */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53FD5C3F2126C481008DA03A /* Build configuration list for PBXNativeTarget "ScrollGuide" */; + buildPhases = ( + 53FD5C2C2126C480008DA03A /* Sources */, + 53FD5C2D2126C480008DA03A /* Frameworks */, + 53FD5C2E2126C480008DA03A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ScrollGuide; + productName = ScrollGuide; + productReference = 53FD5C302126C480008DA03A /* ScrollGuide.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53FD5C282126C480008DA03A /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1000; + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53FD5C2F2126C480008DA03A = { + CreatedOnToolsVersion = 10.0; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 53FD5C2B2126C480008DA03A /* Build configuration list for PBXProject "ScrollGuide" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53FD5C272126C480008DA03A; + productRefGroup = 53FD5C312126C480008DA03A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53FD5C2F2126C480008DA03A /* ScrollGuide */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53FD5C2E2126C480008DA03A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53FD5C382126C481008DA03A /* Assets.xcassets in Resources */, + 53FD5C3B2126C481008DA03A /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53FD5C2C2126C480008DA03A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53FD5C342126C480008DA03A /* AppDelegate.swift in Sources */, + 53FD5C432126C514008DA03A /* ForecastViewController.swift in Sources */, + 53FD5C4B2126C617008DA03A /* UILabel+Style.swift in Sources */, + 53FD5C452126C533008DA03A /* ForecastView.swift in Sources */, + 53FD5C492126C5DA008DA03A /* Forecast.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53FD5C392126C481008DA03A /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53FD5C3A2126C481008DA03A /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53FD5C3D2126C481008DA03A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53FD5C3E2126C481008DA03A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53FD5C402126C481008DA03A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ScrollGuide/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ScrollGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53FD5C412126C481008DA03A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = ScrollGuide/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.ScrollGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53FD5C2B2126C480008DA03A /* Build configuration list for PBXProject "ScrollGuide" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53FD5C3D2126C481008DA03A /* Debug */, + 53FD5C3E2126C481008DA03A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53FD5C3F2126C481008DA03A /* Build configuration list for PBXNativeTarget "ScrollGuide" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53FD5C402126C481008DA03A /* Debug */, + 53FD5C412126C481008DA03A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53FD5C282126C480008DA03A /* Project object */; +} diff --git a/ScrollGuide/ScrollGuide/AppDelegate.swift b/ScrollGuide/ScrollGuide/AppDelegate.swift new file mode 100644 index 0000000..071c8dd --- /dev/null +++ b/ScrollGuide/ScrollGuide/AppDelegate.swift @@ -0,0 +1,50 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + window = UIWindow(frame: UIScreen.main.bounds) + window?.backgroundColor = .white + + let forecastViewController = ForecastViewController() + forecastViewController.title = NSLocalizedString("Forecast", comment: "Forecast") + let forecast = Forecast(title: "Weather For Today", condition: .sun, summary: "Today will be hot and sunny. If you are going out you will need a hat and sunglasses. There is a small chance of a heavy thunderstorm in the afternoon that could cause severe flooding so you may also want to take a boat.") + forecastViewController.forecast = forecast + + let navigationController = UINavigationController(rootViewController: forecastViewController) + window?.rootViewController = navigationController + window?.makeKeyAndVisible() + return true + } +} diff --git a/ScrollGuide/ScrollGuide/Assets.xcassets/AppIcon.appiconset/Contents.json b/ScrollGuide/ScrollGuide/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ScrollGuide/ScrollGuide/Assets.xcassets/Contents.json b/ScrollGuide/ScrollGuide/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ScrollGuide/ScrollGuide/Assets.xcassets/SkyBlue.colorset/Contents.json b/ScrollGuide/ScrollGuide/Assets.xcassets/SkyBlue.colorset/Contents.json new file mode 100644 index 0000000..e039289 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Assets.xcassets/SkyBlue.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.463", + "alpha" : "1.000", + "blue" : "1.000", + "green" : "0.839" + } + } + } + ] +} \ No newline at end of file diff --git a/ScrollGuide/ScrollGuide/Assets.xcassets/Sun.imageset/Contents.json b/ScrollGuide/ScrollGuide/Assets.xcassets/Sun.imageset/Contents.json new file mode 100644 index 0000000..d73dd65 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Assets.xcassets/Sun.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Sun150.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/ScrollGuide/ScrollGuide/Assets.xcassets/Sun.imageset/Sun150.pdf b/ScrollGuide/ScrollGuide/Assets.xcassets/Sun.imageset/Sun150.pdf new file mode 100644 index 0000000..0715bf8 Binary files /dev/null and b/ScrollGuide/ScrollGuide/Assets.xcassets/Sun.imageset/Sun150.pdf differ diff --git a/ScrollGuide/ScrollGuide/Base.lproj/LaunchScreen.storyboard b/ScrollGuide/ScrollGuide/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ScrollGuide/ScrollGuide/Forecast.swift b/ScrollGuide/ScrollGuide/Forecast.swift new file mode 100644 index 0000000..691ebc2 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Forecast.swift @@ -0,0 +1,50 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +public struct Forecast { + + public enum Condition { + case sun + // other conditions... + } + + let title: String + let condition: Condition + let summary: String +} + +public extension Forecast { + func icon() -> UIImage { + switch condition { + case .sun: return UIImage(named: "Sun")! + // other conditions... + } + } +} diff --git a/ScrollGuide/ScrollGuide/ForecastView.swift b/ScrollGuide/ScrollGuide/ForecastView.swift new file mode 100644 index 0000000..1ef4a53 --- /dev/null +++ b/ScrollGuide/ScrollGuide/ForecastView.swift @@ -0,0 +1,81 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class ForecastView: UIView { + + let titleLabel: UILabel = { + let label = UILabel.makeLabel(forTextStyle: .title1) + label.textAlignment = .center + return label + }() + + let imageView: UIImageView = { + let view = UIImageView() + view.translatesAutoresizingMaskIntoConstraints = false + view.setContentHuggingPriority(.defaultLow + 1, for: .horizontal) + view.setContentCompressionResistancePriority(.defaultHigh + 1, for: .horizontal) + return view + }() + + let summaryLabel: UILabel = { + return UILabel.makeLabel(forTextStyle: .body) + }() + + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupView() + } + + private func setupView() { + addSubview(titleLabel) + addSubview(summaryLabel) + addSubview(imageView) + + let margin = readableContentGuide + NSLayoutConstraint.activate([ + titleLabel.leadingAnchor.constraint(equalTo: margin.leadingAnchor), + titleLabel.topAnchor.constraint(equalTo: margin.topAnchor), + titleLabel.trailingAnchor.constraint(equalTo: margin.trailingAnchor), + + imageView.centerXAnchor.constraint(equalTo: margin.centerXAnchor), + imageView.topAnchor.constraint(equalToSystemSpacingBelow: titleLabel.bottomAnchor, multiplier: 1.0), + + summaryLabel.leadingAnchor.constraint(equalTo: margin.leadingAnchor), + summaryLabel.topAnchor.constraint(equalToSystemSpacingBelow: imageView.bottomAnchor, multiplier: 1.0), + summaryLabel.trailingAnchor.constraint(equalTo: margin.trailingAnchor), + summaryLabel.bottomAnchor.constraint(equalTo: margin.bottomAnchor) + ]) + } +} diff --git a/ScrollGuide/ScrollGuide/ForecastViewController.swift b/ScrollGuide/ScrollGuide/ForecastViewController.swift new file mode 100644 index 0000000..8b2f1e0 --- /dev/null +++ b/ScrollGuide/ScrollGuide/ForecastViewController.swift @@ -0,0 +1,125 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class ForecastViewController: UIViewController { + + private enum ViewMetrics { + static let margin: CGFloat = 20.0 + static let backgroundColor = UIColor(named: "SkyBlue") + } + + private let forecastView: ForecastView = { + let view = ForecastView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = ViewMetrics.backgroundColor + return view + }() + + private lazy var scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(forecastView) + return scrollView + }() + + private let infoButton: UIButton = { + let button = UIButton(type: .infoDark) + button.translatesAutoresizingMaskIntoConstraints = false + button.addTarget(self, action: #selector(showInfo(_:)), for: .touchUpInside) + return button + }() + + var forecast: Forecast? { didSet { updateView() } } + + private func updateView() { + if let forecast = forecast { + forecastView.titleLabel.text = forecast.title + forecastView.summaryLabel.text = forecast.summary + forecastView.imageView.image = forecast.icon() + forecastView.imageView.sizeToFit() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + updateView() + } + + private func setupView() { + view.backgroundColor = ViewMetrics.backgroundColor + forecastView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: ViewMetrics.margin, leading: ViewMetrics.margin, bottom: ViewMetrics.margin, trailing: ViewMetrics.margin) + view.addSubview(scrollView) + + scrollView.addSubview(infoButton) + + let frameGuide = scrollView.frameLayoutGuide + let contentGuide = scrollView.contentLayoutGuide + + // Classic scroll view setup using scroll view anchors +// NSLayoutConstraint.activate([ +// scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), +// scrollView.topAnchor.constraint(equalTo: view.topAnchor), +// scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), +// scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), +// +// scrollView.leadingAnchor.constraint(equalTo: forecastView.leadingAnchor), +// scrollView.topAnchor.constraint(equalTo: forecastView.topAnchor), +// scrollView.trailingAnchor.constraint(equalTo: forecastView.trailingAnchor), +// scrollView.bottomAnchor.constraint(equalTo: forecastView.bottomAnchor), +// +// forecastView.widthAnchor.constraint(equalTo: scrollView.widthAnchor) +// ]) + + // Scroll view layout guides (iOS 11) + NSLayoutConstraint.activate([ + frameGuide.leadingAnchor.constraint(equalTo: view.leadingAnchor), + frameGuide.topAnchor.constraint(equalTo: view.topAnchor), + frameGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor), + frameGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + contentGuide.leadingAnchor.constraint(equalTo: forecastView.leadingAnchor), + contentGuide.topAnchor.constraint(equalTo: forecastView.topAnchor), + contentGuide.trailingAnchor.constraint(equalTo: forecastView.trailingAnchor), + contentGuide.bottomAnchor.constraint(equalTo: forecastView.bottomAnchor), + + contentGuide.widthAnchor.constraint(equalTo: frameGuide.widthAnchor), + + infoButton.leadingAnchor.constraint(equalTo: scrollView.layoutMarginsGuide.leadingAnchor), + infoButton.topAnchor.constraint(equalTo: scrollView.layoutMarginsGuide.topAnchor) + ]) + } +} + +extension ForecastViewController { + @objc private func showInfo(_ sender: UIButton) { + print("Show Info") + } +} diff --git a/ScrollGuide/ScrollGuide/Info.plist b/ScrollGuide/ScrollGuide/Info.plist new file mode 100644 index 0000000..e39ce31 --- /dev/null +++ b/ScrollGuide/ScrollGuide/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 2 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/ScrollGuide/ScrollGuide/UILabel+Style.swift b/ScrollGuide/ScrollGuide/UILabel+Style.swift new file mode 100644 index 0000000..b1ca3b3 --- /dev/null +++ b/ScrollGuide/ScrollGuide/UILabel+Style.swift @@ -0,0 +1,40 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +extension UILabel { + static func makeLabel(forTextStyle style: UIFont.TextStyle) -> UILabel { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = UIFont.preferredFont(forTextStyle: style) + label.adjustsFontForContentSizeCategory = true + label.numberOfLines = 0 + return label + } +} diff --git a/SelfSize/README b/SelfSize/README index f2cf08d..9a6664e 100644 --- a/SelfSize/README +++ b/SelfSize/README @@ -7,9 +7,9 @@ Example of using self-sizing table view cells and universal storyboards introduced in iOS 8. This is a reworking of the Huckleberry project removing code that is no longer required. The full details are in the following post: -http://useyourloaf.com/blog/2014/08/07/self-sizing-table-view-cells.html +https://useyourloaf.com/blog/self-sizing-table-view-cells/ The original post can also be found here: -http://useyourloaf.com/blog/2014/02/14/table-view-cells-with-varying-row-heights.html +https://useyourloaf.com/blog/table-view-cells-with-varying-row-heights/ diff --git a/SelfSize/SelfSize.xcodeproj/project.pbxproj b/SelfSize/SelfSize.xcodeproj/project.pbxproj index 28d9945..f6033cc 100644 --- a/SelfSize/SelfSize.xcodeproj/project.pbxproj +++ b/SelfSize/SelfSize.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ + 5325894A23C91363008ABE63 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5325894923C91363008ABE63 /* LaunchScreen.storyboard */; }; 5351AA8A19845210006179CA /* README in Resources */ = {isa = PBXBuildFile; fileRef = 5351AA8919845210006179CA /* README */; }; 53EDDFCA19819CC40064D44A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EDDFC919819CC40064D44A /* main.m */; }; 53EDDFCD19819CC40064D44A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 53EDDFCC19819CC40064D44A /* AppDelegate.m */; }; @@ -18,6 +19,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 5325894923C91363008ABE63 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 5351AA8919845210006179CA /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; 53EDDFC419819CC40064D44A /* SelfSize.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SelfSize.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53EDDFC819819CC40064D44A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -71,6 +73,7 @@ 53EDDFF119819E1C0064D44A /* UYLTextCell.h */, 53EDDFF219819E1C0064D44A /* UYLTextCell.m */, 53EDDFD119819CC40064D44A /* Main.storyboard */, + 5325894923C91363008ABE63 /* LaunchScreen.storyboard */, 53EDDFD419819CC40064D44A /* Images.xcassets */, 53EDDFC719819CC40064D44A /* Supporting Files */, ); @@ -113,7 +116,7 @@ 53EDDFBC19819CC40064D44A /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53EDDFC319819CC40064D44A = { @@ -122,8 +125,8 @@ }; }; buildConfigurationList = 53EDDFBF19819CC40064D44A /* Build configuration list for PBXProject "SelfSize" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -147,6 +150,7 @@ 5351AA8A19845210006179CA /* README in Resources */, 53EDDFD319819CC40064D44A /* Main.storyboard in Resources */, 53EDDFD519819CC40064D44A /* Images.xcassets in Resources */, + 5325894A23C91363008ABE63 /* LaunchScreen.storyboard in Resources */, 53EDDFF519819FFC0064D44A /* SourceData.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -183,24 +187,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -225,17 +242,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -243,6 +271,7 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -261,9 +290,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; INFOPLIST_FILE = SelfSize/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -272,9 +304,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; INFOPLIST_FILE = SelfSize/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/SelfSize/SelfSize/Base.lproj/Main.storyboard b/SelfSize/SelfSize/Base.lproj/Main.storyboard index 6bfa106..03be3d6 100644 --- a/SelfSize/SelfSize/Base.lproj/Main.storyboard +++ b/SelfSize/SelfSize/Base.lproj/Main.storyboard @@ -1,7 +1,10 @@ - - + + + - + + + @@ -9,23 +12,25 @@ - + - + + + - + @@ -64,7 +69,7 @@ - + diff --git a/SelfSize/SelfSize/Images.xcassets/AppIcon.appiconset/Contents.json b/SelfSize/SelfSize/Images.xcassets/AppIcon.appiconset/Contents.json index 91bf9c1..d8db8d6 100644 --- a/SelfSize/SelfSize/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/SelfSize/SelfSize/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,18 +1,53 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, { "idiom" : "iphone", "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", "scale" : "2x" }, { @@ -44,6 +79,16 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/SelfSize/SelfSize/Images.xcassets/Contents.json b/SelfSize/SelfSize/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/SelfSize/SelfSize/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SelfSize/SelfSize/Images.xcassets/LaunchImage.launchimage/Contents.json b/SelfSize/SelfSize/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index 6f870a4..0000000 --- a/SelfSize/SelfSize/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/SelfSize/SelfSize/Info.plist b/SelfSize/SelfSize/Info.plist index cab5273..95c9575 100644 --- a/SelfSize/SelfSize/Info.plist +++ b/SelfSize/SelfSize/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,6 +22,8 @@ 1 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities diff --git a/SelfSize/SelfSize/LaunchScreen.storyboard b/SelfSize/SelfSize/LaunchScreen.storyboard new file mode 100644 index 0000000..883d763 --- /dev/null +++ b/SelfSize/SelfSize/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SpeakEasy/README b/SpeakEasy/README index 02b311d..96d071a 100644 --- a/SpeakEasy/README +++ b/SpeakEasy/README @@ -8,4 +8,4 @@ text to speech synthesis. Makes use of custom voices, pitch, rate and text highlighting. For further details see the following blog post: -http://useyourloaf.com/blog/2014/01/08/synthesized-speech-from-text.html \ No newline at end of file +https://useyourloaf.com/blog/synthesized-speech-from-text/ diff --git a/SpeakEasy/SpeakEasy.xcodeproj/project.pbxproj b/SpeakEasy/SpeakEasy.xcodeproj/project.pbxproj index 1fd4ccd..07fa233 100644 --- a/SpeakEasy/SpeakEasy.xcodeproj/project.pbxproj +++ b/SpeakEasy/SpeakEasy.xcodeproj/project.pbxproj @@ -3,10 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ + 530D9CF023C926AC0087DFA0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 530D9CEF23C926AC0087DFA0 /* LaunchScreen.storyboard */; }; 5329C82318785C4F00B91692 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5329C82218785C4F00B91692 /* Foundation.framework */; }; 5329C82518785C4F00B91692 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5329C82418785C4F00B91692 /* CoreGraphics.framework */; }; 5329C82718785C4F00B91692 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5329C82618785C4F00B91692 /* UIKit.framework */; }; @@ -19,6 +20,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 530D9CEF23C926AC0087DFA0 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 5329C81F18785C4F00B91692 /* SpeakEasy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpeakEasy.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5329C82218785C4F00B91692 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 5329C82418785C4F00B91692 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -26,7 +28,6 @@ 5329C82A18785C4F00B91692 /* SpeakEasy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SpeakEasy-Info.plist"; sourceTree = ""; }; 5329C82C18785C4F00B91692 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 5329C82E18785C4F00B91692 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 5329C83018785C4F00B91692 /* SpeakEasy-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SpeakEasy-Prefix.pch"; sourceTree = ""; }; 5329C83118785C4F00B91692 /* UYLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UYLAppDelegate.h; sourceTree = ""; }; 5329C83218785C4F00B91692 /* UYLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UYLAppDelegate.m; sourceTree = ""; }; 5329C83518785C4F00B91692 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -86,6 +87,7 @@ 5329C83118785C4F00B91692 /* UYLAppDelegate.h */, 5329C83218785C4F00B91692 /* UYLAppDelegate.m */, 5329C83418785C4F00B91692 /* Main.storyboard */, + 530D9CEF23C926AC0087DFA0 /* LaunchScreen.storyboard */, 5329C83718785C4F00B91692 /* UYLViewController.h */, 5329C83818785C4F00B91692 /* UYLViewController.m */, 5329C83A18785C4F00B91692 /* Images.xcassets */, @@ -100,7 +102,6 @@ 5329C82A18785C4F00B91692 /* SpeakEasy-Info.plist */, 5329C82B18785C4F00B91692 /* InfoPlist.strings */, 5329C82E18785C4F00B91692 /* main.m */, - 5329C83018785C4F00B91692 /* SpeakEasy-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; @@ -132,12 +133,12 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0510; + LastUpgradeCheck = 1120; ORGANIZATIONNAME = "Keith Harrison"; }; buildConfigurationList = 5329C81A18785C4F00B91692 /* Build configuration list for PBXProject "SpeakEasy" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -159,6 +160,7 @@ buildActionMask = 2147483647; files = ( 5329C83B18785C4F00B91692 /* Images.xcassets in Resources */, + 530D9CF023C926AC0087DFA0 /* LaunchScreen.storyboard in Resources */, 5329C82D18785C4F00B91692 /* InfoPlist.strings in Resources */, 5329C83618785C4F00B91692 /* Main.storyboard in Resources */, ); @@ -203,22 +205,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -231,7 +248,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -241,29 +258,43 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; @@ -273,10 +304,9 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "SpeakEasy/SpeakEasy-Prefix.pch"; INFOPLIST_FILE = "SpeakEasy/SpeakEasy-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -286,10 +316,9 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "SpeakEasy/SpeakEasy-Prefix.pch"; INFOPLIST_FILE = "SpeakEasy/SpeakEasy-Info.plist"; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/SpeakEasy/SpeakEasy/Base.lproj/Main.storyboard b/SpeakEasy/SpeakEasy/Base.lproj/Main.storyboard index fc9f909..bf0a3b5 100644 --- a/SpeakEasy/SpeakEasy/Base.lproj/Main.storyboard +++ b/SpeakEasy/SpeakEasy/Base.lproj/Main.storyboard @@ -1,10 +1,13 @@ - - + + + - + + + - + @@ -13,12 +16,11 @@ - + - - + @@ -26,8 +28,7 @@ - - + @@ -39,8 +40,7 @@ - - + @@ -51,26 +51,24 @@ - - + - + @@ -97,11 +95,7 @@ + - - - - - - \ No newline at end of file + diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/Contents.json b/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/Contents.json index 80689ca..19882d5 100644 --- a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,22 +1,49 @@ { "images" : [ { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", "size" : "29x29", + "scale" : "2x" + }, + { "idiom" : "iphone", - "filename" : "icon58.png", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", "scale" : "2x" }, { + "idiom" : "iphone", "size" : "40x40", + "scale" : "3x" + }, + { "idiom" : "iphone", - "filename" : "icon80.png", + "size" : "60x60", "scale" : "2x" }, { - "size" : "60x60", "idiom" : "iphone", - "filename" : "icon120.png", - "scale" : "2x" + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon120.png b/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon120.png deleted file mode 100644 index 0077715..0000000 Binary files a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon120.png and /dev/null differ diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon58.png b/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon58.png deleted file mode 100644 index 75bfc8a..0000000 Binary files a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon58.png and /dev/null differ diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon80.png b/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon80.png deleted file mode 100644 index 8f906ac..0000000 Binary files a/SpeakEasy/SpeakEasy/Images.xcassets/AppIcon.appiconset/icon80.png and /dev/null differ diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/Contents.json b/SpeakEasy/SpeakEasy/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/SpeakEasy/SpeakEasy/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/Contents.json b/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index a195255..0000000 --- a/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "filename" : "Default.png", - "scale" : "2x" - }, - { - "extent" : "full-screen", - "idiom" : "iphone", - "subtype" : "retina4", - "filename" : "DefaultR4.png", - "minimum-system-version" : "7.0", - "orientation" : "portrait", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/Default.png b/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/Default.png deleted file mode 100644 index d66b897..0000000 Binary files a/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/Default.png and /dev/null differ diff --git a/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/DefaultR4.png b/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/DefaultR4.png deleted file mode 100644 index 804499c..0000000 Binary files a/SpeakEasy/SpeakEasy/Images.xcassets/LaunchImage.launchimage/DefaultR4.png and /dev/null differ diff --git a/SpeakEasy/SpeakEasy/LaunchScreen.storyboard b/SpeakEasy/SpeakEasy/LaunchScreen.storyboard new file mode 100644 index 0000000..6cb06fe --- /dev/null +++ b/SpeakEasy/SpeakEasy/LaunchScreen.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SpeakEasy/SpeakEasy/SpeakEasy-Info.plist b/SpeakEasy/SpeakEasy/SpeakEasy-Info.plist index 23cd2c3..bc8f3ff 100644 --- a/SpeakEasy/SpeakEasy/SpeakEasy-Info.plist +++ b/SpeakEasy/SpeakEasy/SpeakEasy-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +24,8 @@ 1.0 LSRequiresIPhoneOS + UILaunchStoryboardName + LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities diff --git a/SpeakEasy/SpeakEasy/SpeakEasy-Prefix.pch b/SpeakEasy/SpeakEasy/SpeakEasy-Prefix.pch deleted file mode 100644 index 82a2bb4..0000000 --- a/SpeakEasy/SpeakEasy/SpeakEasy-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header -// -// The contents of this file are implicitly included at the beginning of every source file. -// - -#import - -#ifndef __IPHONE_5_0 -#warning "This project uses features only available in iOS SDK 5.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import -#endif diff --git a/StackMargin/README.md b/StackMargin/README.md new file mode 100644 index 0000000..a4b28b9 --- /dev/null +++ b/StackMargin/README.md @@ -0,0 +1,7 @@ +# Adding Padding To A StackView + +How to use layout margins and the readable content guide to add padding to a stack view. The sample project shows how to do this with Interface Builder and when working with programmatic layouts. + +For further details see the blog post: + ++ [Adding padding to a stack view](https://useyourloaf.com/blog/adding-padding-to-a-stack-view/) diff --git a/StackMargin/StackMargin.xcodeproj/project.pbxproj b/StackMargin/StackMargin.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ad65d2c --- /dev/null +++ b/StackMargin/StackMargin.xcodeproj/project.pbxproj @@ -0,0 +1,348 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 5315FB2D2145A86800E81704 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5315FB2C2145A86800E81704 /* AppDelegate.swift */; }; + 5315FB322145A86800E81704 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5315FB302145A86800E81704 /* Main.storyboard */; }; + 5315FB342145A86A00E81704 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5315FB332145A86A00E81704 /* Assets.xcassets */; }; + 5315FB372145A86A00E81704 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5315FB352145A86A00E81704 /* LaunchScreen.storyboard */; }; + 5315FB5A2146B0D300E81704 /* IBViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5315FB592146B0D300E81704 /* IBViewController.swift */; }; + 5315FB5C2146B12700E81704 /* CodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5315FB5B2146B12700E81704 /* CodeViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 5315FB292145A86800E81704 /* StackMargin.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StackMargin.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5315FB2C2145A86800E81704 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5315FB312145A86800E81704 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5315FB332145A86A00E81704 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5315FB362145A86A00E81704 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5315FB382145A86A00E81704 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5315FB592146B0D300E81704 /* IBViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IBViewController.swift; sourceTree = ""; }; + 5315FB5B2146B12700E81704 /* CodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeViewController.swift; sourceTree = ""; }; + 5315FB5D2146CCC700E81704 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5315FB262145A86800E81704 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5315FB202145A86800E81704 = { + isa = PBXGroup; + children = ( + 5315FB5D2146CCC700E81704 /* README.md */, + 5315FB2B2145A86800E81704 /* StackMargin */, + 5315FB2A2145A86800E81704 /* Products */, + ); + sourceTree = ""; + }; + 5315FB2A2145A86800E81704 /* Products */ = { + isa = PBXGroup; + children = ( + 5315FB292145A86800E81704 /* StackMargin.app */, + ); + name = Products; + sourceTree = ""; + }; + 5315FB2B2145A86800E81704 /* StackMargin */ = { + isa = PBXGroup; + children = ( + 5315FB2C2145A86800E81704 /* AppDelegate.swift */, + 5315FB592146B0D300E81704 /* IBViewController.swift */, + 5315FB5B2146B12700E81704 /* CodeViewController.swift */, + 5315FB302145A86800E81704 /* Main.storyboard */, + 5315FB332145A86A00E81704 /* Assets.xcassets */, + 5315FB352145A86A00E81704 /* LaunchScreen.storyboard */, + 5315FB382145A86A00E81704 /* Info.plist */, + ); + path = StackMargin; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5315FB282145A86800E81704 /* StackMargin */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5315FB3B2145A86A00E81704 /* Build configuration list for PBXNativeTarget "StackMargin" */; + buildPhases = ( + 5315FB252145A86800E81704 /* Sources */, + 5315FB262145A86800E81704 /* Frameworks */, + 5315FB272145A86800E81704 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StackMargin; + productName = StackMargin; + productReference = 5315FB292145A86800E81704 /* StackMargin.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5315FB212145A86800E81704 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1000; + LastUpgradeCheck = 1000; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 5315FB282145A86800E81704 = { + CreatedOnToolsVersion = 10.0; + LastSwiftMigration = 1120; + }; + }; + }; + buildConfigurationList = 5315FB242145A86800E81704 /* Build configuration list for PBXProject "StackMargin" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5315FB202145A86800E81704; + productRefGroup = 5315FB2A2145A86800E81704 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5315FB282145A86800E81704 /* StackMargin */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5315FB272145A86800E81704 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5315FB372145A86A00E81704 /* LaunchScreen.storyboard in Resources */, + 5315FB342145A86A00E81704 /* Assets.xcassets in Resources */, + 5315FB322145A86800E81704 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5315FB252145A86800E81704 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5315FB5C2146B12700E81704 /* CodeViewController.swift in Sources */, + 5315FB2D2145A86800E81704 /* AppDelegate.swift in Sources */, + 5315FB5A2146B0D300E81704 /* IBViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5315FB302145A86800E81704 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5315FB312145A86800E81704 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5315FB352145A86A00E81704 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5315FB362145A86A00E81704 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5315FB392145A86A00E81704 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 5315FB3A2145A86A00E81704 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5315FB3C2145A86A00E81704 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = StackMargin/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StackMargin; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5315FB3D2145A86A00E81704 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = StackMargin/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StackMargin; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5315FB242145A86800E81704 /* Build configuration list for PBXProject "StackMargin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5315FB392145A86A00E81704 /* Debug */, + 5315FB3A2145A86A00E81704 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5315FB3B2145A86A00E81704 /* Build configuration list for PBXNativeTarget "StackMargin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5315FB3C2145A86A00E81704 /* Debug */, + 5315FB3D2145A86A00E81704 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5315FB212145A86800E81704 /* Project object */; +} diff --git a/StackMargin/StackMargin/AppDelegate.swift b/StackMargin/StackMargin/AppDelegate.swift new file mode 100644 index 0000000..85205c0 --- /dev/null +++ b/StackMargin/StackMargin/AppDelegate.swift @@ -0,0 +1,34 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/StackMargin/StackMargin/Assets.xcassets/AppIcon.appiconset/Contents.json b/StackMargin/StackMargin/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/StackMargin/StackMargin/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/StackMargin/StackMargin/Assets.xcassets/Contents.json b/StackMargin/StackMargin/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/StackMargin/StackMargin/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/StackMargin/StackMargin/Base.lproj/LaunchScreen.storyboard b/StackMargin/StackMargin/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/StackMargin/StackMargin/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StackMargin/StackMargin/Base.lproj/Main.storyboard b/StackMargin/StackMargin/Base.lproj/Main.storyboard new file mode 100644 index 0000000..966a3c5 --- /dev/null +++ b/StackMargin/StackMargin/Base.lproj/Main.storyboard @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StackMargin/StackMargin/CodeViewController.swift b/StackMargin/StackMargin/CodeViewController.swift new file mode 100644 index 0000000..a580386 --- /dev/null +++ b/StackMargin/StackMargin/CodeViewController.swift @@ -0,0 +1,113 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class CodeViewController: UIViewController { + private let chapterLabel: UILabel = { + let label = UILabel() + label.font = UIFont.preferredFont(forTextStyle: .headline) + label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true + label.backgroundColor = .white + return label + }() + + private let textView: UITextView = { + let textView = UITextView() + textView.font = UIFont.preferredFont(forTextStyle: .body) + textView.adjustsFontForContentSizeCategory = true + textView.isScrollEnabled = false + textView.isEditable = false + return textView + }() + + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [chapterLabel, textView]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.spacing = UIStackView.spacingUseSystem + return stackView + }() + + private lazy var containerView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20) + view.addSubview(stackView) + view.backgroundColor = .red + + let readable = view.readableContentGuide + NSLayoutConstraint.activate([ + stackView.leadingAnchor.constraint(equalTo: readable.leadingAnchor), + stackView.topAnchor.constraint(equalTo: readable.topAnchor), + stackView.trailingAnchor.constraint(equalTo: readable.trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: readable.bottomAnchor), + ]) + return view + }() + + private lazy var scrollView: UIScrollView = { + let scrollView = UIScrollView() + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.addSubview(containerView) + return scrollView + }() + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + + chapterLabel.text = "Down the Rabbit-Hole" + textView.text = """ + Alice was beginning to get very tired of sitting by her sister on the \ + bank, and of having nothing to do: once or twice she had peeped into the \ + book her sister was reading, but it had no pictures or conversations in \ + it, ‘and what is the use of a book,’ thought Alice ‘without pictures or \ + conversations?’ + """ + } + + private func setupView() { + view.addSubview(scrollView) + + NSLayoutConstraint.activate([ + scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + scrollView.topAnchor.constraint(equalTo: view.topAnchor), + scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + + scrollView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor), + scrollView.topAnchor.constraint(equalTo: containerView.topAnchor), + scrollView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor), + scrollView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor), + + scrollView.widthAnchor.constraint(equalTo: containerView.widthAnchor), + ]) + } +} diff --git a/StackMargin/StackMargin/IBViewController.swift b/StackMargin/StackMargin/IBViewController.swift new file mode 100644 index 0000000..b7dc7b9 --- /dev/null +++ b/StackMargin/StackMargin/IBViewController.swift @@ -0,0 +1,67 @@ +// Copyright © 2018 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class IBViewController: UIViewController { + @IBOutlet var stackView: UIStackView! + @IBOutlet var chapterLabel: UILabel! + @IBOutlet var textView: UITextView! + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + + chapterLabel.text = "Down the Rabbit-Hole" + textView.text = """ + Alice was beginning to get very tired of sitting by her sister on the \ + bank, and of having nothing to do: once or twice she had peeped into the \ + book her sister was reading, but it had no pictures or conversations in \ + it, ‘and what is the use of a book,’ thought Alice ‘without pictures or \ + conversations?’ + """ + } + + private let backgroundView: UIView = { + let view = UIView() + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .red + return view + }() + + private func setupView() { + stackView.insertSubview(backgroundView, at: 0) + + NSLayoutConstraint.activate([ + backgroundView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor), + backgroundView.topAnchor.constraint(equalTo: stackView.topAnchor), + backgroundView.trailingAnchor.constraint(equalTo: stackView.trailingAnchor), + backgroundView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor) + ]) + } +} diff --git a/StackMargin/StackMargin/Info.plist b/StackMargin/StackMargin/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/StackMargin/StackMargin/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Stacks/README.md b/Stacks/README.md index 1386fb1..232736c 100644 --- a/Stacks/README.md +++ b/Stacks/README.md @@ -7,14 +7,14 @@ Examples of using and sometime abusing stack views (requires iOS 9) Example of how to use UIStackView to simplify layout of horizontal and vertical arrangements of views. See the following post for details: -+ [Easier Auto Layout with Stack Views](http://useyourloaf.com/blog/easier-autolayout-with-stackviews/) ++ [Easier Auto Layout with Stack Views](https://useyourloaf.com/blog/easier-autolayout-with-stackviews/) #### Using Stack Views with Size Classes Also see this post for details on how to have the stack view automatically adapt to size class changes: -+ [Adapting Stack Views with Size Classes](http://useyourloaf.com/blog/adapting-stack-views-with-size-classes/) ++ [Adapting Stack Views with Size Classes](https://useyourloaf.com/blog/adapting-stack-views-with-size-classes/) #### Hiding Views in a Stack View @@ -22,21 +22,21 @@ The third view controller - HiddenViewController is an example of how to use size classes to hide a view contained in a stack view. See this post for details: -+ [Using Size Classes to Hide Stack View Contents](http://useyourloaf.com/blog/using-size-classes-to-hide-stack-view-contents/) ++ [Using Size Classes to Hide Stack View Contents](https://useyourloaf.com/blog/using-size-classes-to-hide-stack-view-contents/) #### 3D Touch Quick Actions Quick actions allow the user to launch the app directly to one of the three tabs. See this post for details: -+ [Adding 3D Touch Quick Actions](http://useyourloaf.com/blog/adding-3d-touch-quick-actions/) ++ [Adding 3D Touch Quick Actions](https://useyourloaf.com/blog/adding-3d-touch-quick-actions/) #### Scrolling Stack View The ScrollingStackViewController provides an example of how to embed a stack view in a scroll view. See this post for details: -+ [Scroll Stack Views](http://useyourloaf.com/blog/scrolling-stack-views/) ++ [Scroll Stack Views](https://useyourloaf.com/blog/scrolling-stack-views/) #### Version History diff --git a/Stacks/Stacks.xcodeproj/project.pbxproj b/Stacks/Stacks.xcodeproj/project.pbxproj index fadae18..9605874 100644 --- a/Stacks/Stacks.xcodeproj/project.pbxproj +++ b/Stacks/Stacks.xcodeproj/project.pbxproj @@ -9,36 +9,15 @@ /* Begin PBXBuildFile section */ 5378799F1B49BA6A004CBDC1 /* SizeClassViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5378799E1B49BA6A004CBDC1 /* SizeClassViewController.swift */; }; 5395B1371BB48B4700CF54F7 /* HiddenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5395B1361BB48B4700CF54F7 /* HiddenViewController.swift */; }; - 5395B1381BB48B4700CF54F7 /* HiddenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5395B1361BB48B4700CF54F7 /* HiddenViewController.swift */; }; 53B55B951BC1B89A0071291E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53B55B981BC1B89A0071291E /* InfoPlist.strings */; }; - 53B55B961BC1B89A0071291E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53B55B981BC1B89A0071291E /* InfoPlist.strings */; }; 53DA13EE1B32184600FEEE79 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DA13ED1B32184600FEEE79 /* AppDelegate.swift */; }; 53DA13F01B32184600FEEE79 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DA13EF1B32184600FEEE79 /* ViewController.swift */; }; 53DA13F31B32184600FEEE79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53DA13F11B32184600FEEE79 /* Main.storyboard */; }; 53DA13F51B32184600FEEE79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53DA13F41B32184600FEEE79 /* Assets.xcassets */; }; 53DA13F81B32184600FEEE79 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53DA13F61B32184600FEEE79 /* LaunchScreen.storyboard */; }; - 53DA14031B32184600FEEE79 /* StacksTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DA14021B32184600FEEE79 /* StacksTests.swift */; }; - 53DA140E1B32184600FEEE79 /* StacksUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53DA140D1B32184600FEEE79 /* StacksUITests.swift */; }; 53E9DC1B1C90E0FB00C9A89C /* ScrollingStackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E9DC1A1C90E0FB00C9A89C /* ScrollingStackViewController.swift */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 53DA13FF1B32184600FEEE79 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 53DA13E21B32184500FEEE79 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 53DA13E91B32184600FEEE79; - remoteInfo = Stacks; - }; - 53DA140A1B32184600FEEE79 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 53DA13E21B32184500FEEE79 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 53DA13E91B32184600FEEE79; - remoteInfo = Stacks; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXFileReference section */ 5378799E1B49BA6A004CBDC1 /* SizeClassViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SizeClassViewController.swift; sourceTree = ""; }; 5395B1361BB48B4700CF54F7 /* HiddenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HiddenViewController.swift; sourceTree = ""; }; @@ -51,12 +30,6 @@ 53DA13F41B32184600FEEE79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 53DA13F71B32184600FEEE79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53DA13F91B32184600FEEE79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 53DA13FE1B32184600FEEE79 /* StacksTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StacksTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 53DA14021B32184600FEEE79 /* StacksTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StacksTests.swift; sourceTree = ""; }; - 53DA14041B32184600FEEE79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 53DA14091B32184600FEEE79 /* StacksUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StacksUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 53DA140D1B32184600FEEE79 /* StacksUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StacksUITests.swift; sourceTree = ""; }; - 53DA140F1B32184600FEEE79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53E9DC1A1C90E0FB00C9A89C /* ScrollingStackViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollingStackViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -68,20 +41,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 53DA13FB1B32184600FEEE79 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 53DA14061B32184600FEEE79 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -90,8 +49,6 @@ children = ( 53BB4E981C94C22D0019483F /* README.md */, 53DA13EC1B32184600FEEE79 /* Stacks */, - 53DA14011B32184600FEEE79 /* StacksTests */, - 53DA140C1B32184600FEEE79 /* StacksUITests */, 53DA13EB1B32184600FEEE79 /* Products */, ); sourceTree = ""; @@ -100,8 +57,6 @@ isa = PBXGroup; children = ( 53DA13EA1B32184600FEEE79 /* Stacks.app */, - 53DA13FE1B32184600FEEE79 /* StacksTests.xctest */, - 53DA14091B32184600FEEE79 /* StacksUITests.xctest */, ); name = Products; sourceTree = ""; @@ -123,24 +78,6 @@ path = Stacks; sourceTree = ""; }; - 53DA14011B32184600FEEE79 /* StacksTests */ = { - isa = PBXGroup; - children = ( - 53DA14021B32184600FEEE79 /* StacksTests.swift */, - 53DA14041B32184600FEEE79 /* Info.plist */, - ); - path = StacksTests; - sourceTree = ""; - }; - 53DA140C1B32184600FEEE79 /* StacksUITests */ = { - isa = PBXGroup; - children = ( - 53DA140D1B32184600FEEE79 /* StacksUITests.swift */, - 53DA140F1B32184600FEEE79 /* Info.plist */, - ); - path = StacksUITests; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -161,68 +98,25 @@ productReference = 53DA13EA1B32184600FEEE79 /* Stacks.app */; productType = "com.apple.product-type.application"; }; - 53DA13FD1B32184600FEEE79 /* StacksTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 53DA14151B32184600FEEE79 /* Build configuration list for PBXNativeTarget "StacksTests" */; - buildPhases = ( - 53DA13FA1B32184600FEEE79 /* Sources */, - 53DA13FB1B32184600FEEE79 /* Frameworks */, - 53DA13FC1B32184600FEEE79 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 53DA14001B32184600FEEE79 /* PBXTargetDependency */, - ); - name = StacksTests; - productName = StacksTests; - productReference = 53DA13FE1B32184600FEEE79 /* StacksTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 53DA14081B32184600FEEE79 /* StacksUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 53DA14181B32184600FEEE79 /* Build configuration list for PBXNativeTarget "StacksUITests" */; - buildPhases = ( - 53DA14051B32184600FEEE79 /* Sources */, - 53DA14061B32184600FEEE79 /* Frameworks */, - 53DA14071B32184600FEEE79 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 53DA140B1B32184600FEEE79 /* PBXTargetDependency */, - ); - name = StacksUITests; - productName = StacksUITests; - productReference = 53DA14091B32184600FEEE79 /* StacksUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 53DA13E21B32184500FEEE79 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 1020; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 53DA13E91B32184600FEEE79 = { CreatedOnToolsVersion = 7.0; DevelopmentTeam = LCC2J94N44; - }; - 53DA13FD1B32184600FEEE79 = { - CreatedOnToolsVersion = 7.0; - TestTargetID = 53DA13E91B32184600FEEE79; - }; - 53DA14081B32184600FEEE79 = { - CreatedOnToolsVersion = 7.0; - TestTargetID = 53DA13E91B32184600FEEE79; + LastSwiftMigration = 0820; }; }; }; buildConfigurationList = 53DA13E51B32184500FEEE79 /* Build configuration list for PBXProject "Stacks" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -234,8 +128,6 @@ projectRoot = ""; targets = ( 53DA13E91B32184600FEEE79 /* Stacks */, - 53DA13FD1B32184600FEEE79 /* StacksTests */, - 53DA14081B32184600FEEE79 /* StacksUITests */, ); }; /* End PBXProject section */ @@ -252,21 +144,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 53DA13FC1B32184600FEEE79 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 53DA14071B32184600FEEE79 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 53B55B961BC1B89A0071291E /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -282,38 +159,8 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 53DA13FA1B32184600FEEE79 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 53DA14031B32184600FEEE79 /* StacksTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 53DA14051B32184600FEEE79 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5395B1381BB48B4700CF54F7 /* HiddenViewController.swift in Sources */, - 53DA140E1B32184600FEEE79 /* StacksUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 53DA14001B32184600FEEE79 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 53DA13E91B32184600FEEE79 /* Stacks */; - targetProxy = 53DA13FF1B32184600FEEE79 /* PBXContainerItemProxy */; - }; - 53DA140B1B32184600FEEE79 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 53DA13E91B32184600FEEE79 /* Stacks */; - targetProxy = 53DA140A1B32184600FEEE79 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin PBXVariantGroup section */ 53B55B981BC1B89A0071291E /* InfoPlist.strings */ = { isa = PBXVariantGroup; @@ -346,17 +193,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -383,6 +241,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -391,17 +250,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -420,6 +290,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -434,6 +306,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Stacks; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -447,58 +320,11 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Stacks; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; - 53DA14161B32184600FEEE79 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - INFOPLIST_FILE = StacksTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StacksTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stacks.app/Stacks"; - }; - name = Debug; - }; - 53DA14171B32184600FEEE79 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - INFOPLIST_FILE = StacksTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StacksTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stacks.app/Stacks"; - }; - name = Release; - }; - 53DA14191B32184600FEEE79 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - INFOPLIST_FILE = StacksUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StacksUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_TARGET_NAME = Stacks; - USES_XCTRUNNER = YES; - }; - name = Debug; - }; - 53DA141A1B32184600FEEE79 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - INFOPLIST_FILE = StacksUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StacksUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_TARGET_NAME = Stacks; - USES_XCTRUNNER = YES; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -520,24 +346,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 53DA14151B32184600FEEE79 /* Build configuration list for PBXNativeTarget "StacksTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 53DA14161B32184600FEEE79 /* Debug */, - 53DA14171B32184600FEEE79 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 53DA14181B32184600FEEE79 /* Build configuration list for PBXNativeTarget "StacksUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 53DA14191B32184600FEEE79 /* Debug */, - 53DA141A1B32184600FEEE79 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 53DA13E21B32184500FEEE79 /* Project object */; diff --git a/Stacks/Stacks/AppDelegate.swift b/Stacks/Stacks/AppDelegate.swift index f9d2779..d0300c9 100644 --- a/Stacks/Stacks/AppDelegate.swift +++ b/Stacks/Stacks/AppDelegate.swift @@ -42,7 +42,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { case OpenTopRated init?(fullIdentifier: String) { - guard let shortIdentifier = fullIdentifier.componentsSeparatedByString(".").last else { + guard let shortIdentifier = fullIdentifier.components(separatedBy: ".").last else { return nil } self.init(rawValue: shortIdentifier) @@ -51,9 +51,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem { + if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem { handleShortcut(shortcutItem) return false @@ -62,14 +62,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - func application(application: UIApplication, - performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, - completionHandler: (Bool) -> Void) { + func application(_ application: UIApplication, + performActionFor shortcutItem: UIApplicationShortcutItem, + completionHandler: @escaping (Bool) -> Void) { completionHandler(handleShortcut(shortcutItem)) } - private func handleShortcut(shortcutItem: UIApplicationShortcutItem) -> Bool { + @discardableResult private func handleShortcut(_ shortcutItem: UIApplicationShortcutItem) -> Bool { let shortcutType = shortcutItem.type guard let shortcutIdentifier = ShortcutIdentifier(fullIdentifier: shortcutType) else { @@ -79,7 +79,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return selectTabBarItemForIdentifier(shortcutIdentifier) } - private func selectTabBarItemForIdentifier(identifier: ShortcutIdentifier) -> Bool { + private func selectTabBarItemForIdentifier(_ identifier: ShortcutIdentifier) -> Bool { guard let tabBarController = self.window?.rootViewController as? UITabBarController else { return false @@ -97,4 +97,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } } -} \ No newline at end of file +} diff --git a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/Contents.json b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/Contents.json index adeb159..1018f64 100644 --- a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,17 @@ { "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon-42.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon-60.png", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", @@ -36,6 +48,18 @@ "filename" : "icon-180.png", "scale" : "3x" }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon-20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon-41.png", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", @@ -77,6 +101,12 @@ "idiom" : "ipad", "filename" : "icon-167.png", "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "icon-1024.png", + "scale" : "1x" } ], "info" : { diff --git a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000..4a1a9de Binary files /dev/null and b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-1024.png differ diff --git a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-20.png b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-20.png new file mode 100644 index 0000000..3c16adf Binary files /dev/null and b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-20.png differ diff --git a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-41.png b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-41.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-41.png differ diff --git a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-42.png b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-42.png new file mode 100644 index 0000000..c663546 Binary files /dev/null and b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-42.png differ diff --git a/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-60.png b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-60.png new file mode 100644 index 0000000..fd2eff6 Binary files /dev/null and b/Stacks/Stacks/Assets.xcassets/AppIcon.appiconset/icon-60.png differ diff --git a/Stacks/Stacks/Base.lproj/Main.storyboard b/Stacks/Stacks/Base.lproj/Main.storyboard index d119908..efc7d33 100644 --- a/Stacks/Stacks/Base.lproj/Main.storyboard +++ b/Stacks/Stacks/Base.lproj/Main.storyboard @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -14,11 +18,11 @@ - + - + @@ -32,7 +36,7 @@ - + @@ -56,23 +60,23 @@ - + - + - + - + @@ -93,7 +97,7 @@ - + @@ -118,64 +122,46 @@ - + - + - + - + - + - - - - - - - - - - + - - - - - - - - - - + @@ -192,7 +178,7 @@ - + @@ -240,41 +226,23 @@ - + - + - - - - - - - - - - + - - - - - - - - - - + - + @@ -299,7 +267,7 @@ - + diff --git a/Stacks/Stacks/HiddenViewController.swift b/Stacks/Stacks/HiddenViewController.swift index c79f8c1..6943606 100644 --- a/Stacks/Stacks/HiddenViewController.swift +++ b/Stacks/Stacks/HiddenViewController.swift @@ -33,24 +33,23 @@ import UIKit -class HiddenViewController: UIViewController { - - @IBOutlet weak var extraHeart: UIImageView! +final class HiddenViewController: UIViewController { + @IBOutlet private var extraHeart: UIImageView! override func viewDidLoad() { super.viewDidLoad() configureView(traitCollection.verticalSizeClass) } - - override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { - super.willTransitionToTraitCollection(newCollection, withTransitionCoordinator: coordinator) + + override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) { + super.willTransition(to: newCollection, with: coordinator) configureView(newCollection.verticalSizeClass) } - - private func configureView(verticalSizeClass: UIUserInterfaceSizeClass) { + + private func configureView(_ verticalSizeClass: UIUserInterfaceSizeClass) { guard extraHeart != nil else { return } - extraHeart.hidden = (verticalSizeClass == .Compact) + extraHeart.isHidden = (verticalSizeClass == .compact) } -} \ No newline at end of file +} diff --git a/Stacks/Stacks/ScrollingStackViewController.swift b/Stacks/Stacks/ScrollingStackViewController.swift index 554b609..2363417 100644 --- a/Stacks/Stacks/ScrollingStackViewController.swift +++ b/Stacks/Stacks/ScrollingStackViewController.swift @@ -33,37 +33,36 @@ import UIKit -class ScrollingStackViewController: UIViewController { +final class ScrollingStackViewController: UIViewController { + @IBOutlet private var scrollView: UIScrollView! + @IBOutlet private var stackView: UIStackView! - @IBOutlet weak var scrollView: UIScrollView! - @IBOutlet weak var stackView: UIStackView! - - @IBAction func singleTap(sender: UITapGestureRecognizer) { + @IBAction func singleTap(_ sender: UITapGestureRecognizer) { let heartImage = UIImage(named: "Heart") let heartImageView = UIImageView(image: heartImage) stackView.addArrangedSubview(heartImageView) scrollToEnd(heartImageView) } - - @IBAction func twoFingerTap(sender: UITapGestureRecognizer) { + + @IBAction func twoFingerTap(_ sender: UITapGestureRecognizer) { let starImage = UIImage(named: "Star") let starImageView = UIImageView(image: starImage) stackView.addArrangedSubview(starImageView) scrollToEnd(starImageView) } - - @IBAction func threeFingerTap(sender: UITapGestureRecognizer) { + + @IBAction func threeFingerTap(_ sender: UITapGestureRecognizer) { let views = stackView.arrangedSubviews for entry in views { stackView.removeArrangedSubview(entry) entry.removeFromSuperview() } } - - private func scrollToEnd(addedView: UIView) { + + private func scrollToEnd(_ addedView: UIView) { let contentViewHeight = scrollView.contentSize.height + addedView.bounds.height + stackView.spacing let offsetY = contentViewHeight - scrollView.bounds.height - if (offsetY > 0) { + if offsetY > 0 { scrollView.setContentOffset(CGPoint(x: scrollView.contentOffset.x, y: offsetY), animated: true) } } diff --git a/Stacks/Stacks/SizeClassViewController.swift b/Stacks/Stacks/SizeClassViewController.swift index 50204ec..de4e79b 100644 --- a/Stacks/Stacks/SizeClassViewController.swift +++ b/Stacks/Stacks/SizeClassViewController.swift @@ -33,9 +33,8 @@ import UIKit -class SizeClassViewController: UIViewController { - - @IBOutlet weak var stackView: UIStackView! +final class SizeClassViewController: UIViewController { + @IBOutlet private var stackView: UIStackView! // The alignment axis of the stack view should be set correctly in the Storyboard // for the given size classes. It should be horizontal except for when the view @@ -51,17 +50,17 @@ class SizeClassViewController: UIViewController { // super.viewDidLoad() // configureViewForSize(view.bounds.size) // } - -// override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { -// super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) +// +// override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { +// super.viewWillTransition(to: size, with: coordinator) // configureViewForSize(size) // } - -// private func configureViewForSize(size: CGSize) { +// +// private func configureViewForSize(_ size: CGSize) { // if size.width > size.height { -// stackView.axis = .Horizontal +// stackView.axis = .horizontal // } else { -// stackView.axis = .Vertical +// stackView.axis = .vertical // } // } } diff --git a/Stacks/Stacks/ViewController.swift b/Stacks/Stacks/ViewController.swift index 2d1fa07..f172d89 100644 --- a/Stacks/Stacks/ViewController.swift +++ b/Stacks/Stacks/ViewController.swift @@ -33,27 +33,26 @@ import UIKit -class ViewController: UIViewController { - - @IBOutlet weak var axisSwitch: UISwitch! - @IBOutlet weak var stackView: UIStackView! - - @IBAction func axisChange(sender: UISwitch) { - UIView.animateWithDuration(1.0) { +final class ViewController: UIViewController { + @IBOutlet private var axisSwitch: UISwitch! + @IBOutlet private var stackView: UIStackView! + + @IBAction func axisChange(_ sender: UISwitch) { + UIView.animate(withDuration: 1.0, animations: { self.updateConstraintsForAxis() - } + }) } - + override func viewDidLoad() { super.viewDidLoad() updateConstraintsForAxis() } private func updateConstraintsForAxis() { - if (axisSwitch.on) { - stackView.axis = .Horizontal + if axisSwitch.isOn { + stackView.axis = .horizontal } else { - stackView.axis = .Vertical + stackView.axis = .vertical } } -} \ No newline at end of file +} diff --git a/Stacks/StacksTests/StacksTests.swift b/Stacks/StacksTests/StacksTests.swift deleted file mode 100644 index 01917ad..0000000 --- a/Stacks/StacksTests/StacksTests.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// StacksTests.swift -// StacksTests -// -// Created by Keith Harrison on 17/06/2015. -// Copyright © 2015 Keith Harrison. All rights reserved. -// - -import XCTest - -class StacksTests: XCTestCase { - - override func setUp() { - super.setUp() - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - super.tearDown() - } - - func testExample() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - func testPerformanceExample() { - // This is an example of a performance test case. - self.measureBlock() { - // Put the code you want to measure the time of here. - } - } - -} diff --git a/Stacks/StacksUITests/StacksUITests.swift b/Stacks/StacksUITests/StacksUITests.swift deleted file mode 100644 index 59661fb..0000000 --- a/Stacks/StacksUITests/StacksUITests.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// StacksUITests.swift -// StacksUITests -// -// Created by Keith Harrison on 17/06/2015. -// Copyright © 2015 Keith Harrison. All rights reserved. -// - -import Foundation -import XCTest - -class StacksUITests: XCTestCase { - - override func setUp() { - super.setUp() - - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. - XCUIApplication().launch() - } - - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - super.tearDown() - } - - func testExample() { - // Use recording to get started writing UI tests. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - -} diff --git a/StaticTable/StaticTable/UYLFirstViewController.xib b/StaticTable/StaticTable/UYLFirstViewController.xib deleted file mode 100644 index 5df5285..0000000 --- a/StaticTable/StaticTable/UYLFirstViewController.xib +++ /dev/null @@ -1,223 +0,0 @@ - - - - 1296 - 11D50 - 2182 - 1138.32 - 568.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBProxyObject - IBUIView - IBUILabel - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 298 - {{20, 155}, {280, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - First View Controller - - 1 - MCAwIDAAA - - - 0 - 10 - 1 - - 1 - 17 - - - Helvetica - 17 - 16 - - - - {{0, 64}, {320, 367}} - - - - - 10 - - 549453824 - {512, 1} - - - - - - TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA -AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA -AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI -AAgACAAIAAEAAQABAAE - - - - - - 3 - MCAwAA - - - groupTableViewBackgroundColor - - - - NO - - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - - - 0 - - - - - - 1 - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 5 - - - - - - - UYLFirstViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 5 - - - - - UYLFirstViewController - UIViewController - - IBProjectSource - ./Classes/UYLFirstViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1181 - - diff --git a/StaticTable/StaticTable/first.png b/StaticTable/StaticTable/first.png deleted file mode 100644 index 9300ee2..0000000 Binary files a/StaticTable/StaticTable/first.png and /dev/null differ diff --git a/StaticTable/StaticTable/first@2x.png b/StaticTable/StaticTable/first@2x.png deleted file mode 100644 index 374d78e..0000000 Binary files a/StaticTable/StaticTable/first@2x.png and /dev/null differ diff --git a/StaticTable/StaticTable/second.png b/StaticTable/StaticTable/second.png deleted file mode 100644 index 1100b48..0000000 Binary files a/StaticTable/StaticTable/second.png and /dev/null differ diff --git a/StaticTable/StaticTable/second@2x.png b/StaticTable/StaticTable/second@2x.png deleted file mode 100644 index 368d38f..0000000 Binary files a/StaticTable/StaticTable/second@2x.png and /dev/null differ diff --git a/StaticTableDynamicType/README.md b/StaticTableDynamicType/README.md index f6877c8..6c03a7e 100644 --- a/StaticTableDynamicType/README.md +++ b/StaticTableDynamicType/README.md @@ -1,8 +1,10 @@ ### Static Table View Support for Dynamic Type +*The workarounds in this project should only be required if you need to deploy back to iOS 9 or earlier.* + A look at how to get dynamic type working with static table views. See the following post further details: -+ [Static Tables and Dynamic Type](http://useyourloaf.com/blog/static-tables-and-dynamic-type/) ++ [Static Tables and Dynamic Type](https://useyourloaf.com/blog/static-tables-and-dynamic-type/) #### Version History diff --git a/StaticTableDynamicType/StaticTable.xcodeproj/project.pbxproj b/StaticTableDynamicType/StaticTable.xcodeproj/project.pbxproj index 5a4c99a..24d8da8 100644 --- a/StaticTableDynamicType/StaticTable.xcodeproj/project.pbxproj +++ b/StaticTableDynamicType/StaticTable.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -100,17 +100,19 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0730; + LastUpgradeCheck = 1030; ORGANIZATIONNAME = "Keith Harrison"; TargetAttributes = { 5347A3B51CC968FF00154F49 = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = LCC2J94N44; + LastSwiftMigration = 0830; }; }; }; buildConfigurationList = 5347A3B11CC968FF00154F49 /* Build configuration list for PBXProject "StaticTable" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -178,18 +180,29 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -216,6 +229,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -224,18 +238,29 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -254,6 +279,9 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -263,11 +291,16 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = StaticTable/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StaticTable; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -275,11 +308,16 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; INFOPLIST_FILE = StaticTable/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.StaticTable; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/StaticTableDynamicType/StaticTable/Base.lproj/Main.storyboard b/StaticTableDynamicType/StaticTable/Base.lproj/Main.storyboard index 8a368e4..2e49df3 100644 --- a/StaticTableDynamicType/StaticTable/Base.lproj/Main.storyboard +++ b/StaticTableDynamicType/StaticTable/Base.lproj/Main.storyboard @@ -1,38 +1,39 @@ - - + + + - - + + - - + + - + - + - + - - + + - + @@ -47,18 +48,18 @@ - - + + - + @@ -77,23 +78,23 @@ - - + + - + - @@ -121,12 +122,10 @@ - - - + @@ -134,7 +133,7 @@ - + @@ -144,7 +143,7 @@ - + diff --git a/StaticTableDynamicType/StaticTable/StaticTableViewController.swift b/StaticTableDynamicType/StaticTable/StaticTableViewController.swift index 1380c96..1ca1f51 100644 --- a/StaticTableDynamicType/StaticTable/StaticTableViewController.swift +++ b/StaticTableDynamicType/StaticTable/StaticTableViewController.swift @@ -34,21 +34,20 @@ import UIKit class StaticTableViewController: UITableViewController { - - override func viewDidLoad() { - super.viewDidLoad() - tableView.estimatedRowHeight = 56.0 - } - - override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath) + // This is only necessary for iOS 9. If your minimum deployment + // target is iOS 10 select the "Automatically Adjusts Font" option + // in Interface Builder for each of the text labels. + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = super.tableView(tableView, cellForRowAt: indexPath) if let cell = cell as? UYLPreferredFont { cell.contentSizeChanged() } return cell } - - override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { - return UITableViewAutomaticDimension + + // This is only necessary for iOS 9 which seems to ignore the setting + // in Interface Builder. + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableView.automaticDimension } } diff --git a/StaticTableDynamicType/StaticTable/UYLBasicStaticTableViewCell.swift b/StaticTableDynamicType/StaticTable/UYLBasicStaticTableViewCell.swift index c418b91..c27509b 100644 --- a/StaticTableDynamicType/StaticTable/UYLBasicStaticTableViewCell.swift +++ b/StaticTableDynamicType/StaticTable/UYLBasicStaticTableViewCell.swift @@ -8,13 +8,12 @@ import UIKit -class UYLBasicStaticTableViewCell: UITableViewCell { - - @IBOutlet weak var titleText: UILabel! +final class UYLBasicStaticTableViewCell: UITableViewCell { + @IBOutlet private weak var titleText: UILabel! } extension UYLBasicStaticTableViewCell: UYLPreferredFont { func contentSizeChanged() { - titleText.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline) + titleText.font = UIFont.preferredFont(forTextStyle: .headline) } } diff --git a/StaticTableDynamicType/StaticTable/UYLSubtitleStaticTableViewCell.swift b/StaticTableDynamicType/StaticTable/UYLSubtitleStaticTableViewCell.swift index 8e4ff9a..8e8226b 100644 --- a/StaticTableDynamicType/StaticTable/UYLSubtitleStaticTableViewCell.swift +++ b/StaticTableDynamicType/StaticTable/UYLSubtitleStaticTableViewCell.swift @@ -33,14 +33,14 @@ import UIKit -class UYLSubtitleStaticTableViewCell: UITableViewCell { +final class UYLSubtitleStaticTableViewCell: UITableViewCell { @IBOutlet private weak var titleText: UILabel! @IBOutlet private weak var subtitleText: UILabel! } extension UYLSubtitleStaticTableViewCell: UYLPreferredFont { func contentSizeChanged() { - titleText.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline) - subtitleText.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline) + titleText.font = UIFont.preferredFont(forTextStyle: .headline) + subtitleText.font = UIFont.preferredFont(forTextStyle: .subheadline) } } diff --git a/Stepper/Stepper/en.lproj/UYLViewController.xib b/Stepper/Stepper/en.lproj/UYLViewController.xib deleted file mode 100644 index 61a93e4..0000000 --- a/Stepper/Stepper/en.lproj/UYLViewController.xib +++ /dev/null @@ -1,449 +0,0 @@ - - - - 1280 - 11C74 - 1938 - 1138.23 - 567.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 933 - - - IBUISwitch - IBUIStepper - IBUIView - IBUILabel - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{20, 20}, {280, 40}} - - - - _NS:328 - NO - YES - 7 - NO - IBCocoaTouchFramework - UIStepper - - 1 - MSAxIDAAA - - - 1 - 10 - 1 - - 2 - 24 - - - Helvetica-Bold - 24 - 16 - - - - - 292 - {{130, 68}, {60, 50}} - - - - _NS:328 - - 1 - MCAwIDAAA - - NO - YES - 7 - NO - IBCocoaTouchFramework - 000 - - 1 - MSAxIDEAA - - - 1 - 10 - 1 - - 2 - 30 - - - Helvetica-Bold - 30 - 16 - - - - - 268 - {{113, 149}, {94, 27}} - - - - _NS:992 - NO - YES - IBCocoaTouchFramework - 0 - 0 - 100 - - - - 292 - {{154, 216}, {94, 27}} - - - - _NS:606 - NO - IBCocoaTouchFramework - 0 - 0 - YES - - - - 292 - {{20, 219}, {141, 21}} - - - - _NS:328 - NO - YES - 7 - NO - IBCocoaTouchFramework - Autorepeat - - - 1 - 10 - 2 - - 1 - 17 - - - Helvetica - 17 - 16 - - - - - 292 - {{154, 277}, {94, 27}} - - - _NS:606 - NO - IBCocoaTouchFramework - 0 - 0 - YES - - - - 292 - {{20, 280}, {141, 21}} - - - - _NS:328 - NO - YES - 7 - NO - IBCocoaTouchFramework - Continuous - - - 1 - 10 - 2 - - - - - - 292 - {{154, 340}, {94, 27}} - - - _NS:606 - NO - IBCocoaTouchFramework - 0 - 0 - YES - - - - 292 - {{20, 340}, {141, 21}} - - - - _NS:328 - NO - YES - 7 - NO - IBCocoaTouchFramework - Value wraps - - - 1 - 10 - 2 - - - - - {{0, 20}, {320, 460}} - - - - - 1 - MCAwLjUwMTk2MDgxNCAxAA - - NO - - IBCocoaTouchFramework - - - - - - - view - - - - 7 - - - - counter - - - - 12 - - - - stepper - - - - 22 - - - - stepperChanged: - - - 13 - - 11 - - - - autorepeatChanged: - - - 13 - - 19 - - - - continuousChanged: - - - 13 - - 20 - - - - wrapChanged: - - - 13 - - 21 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 6 - - - - - - - - - - - - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 13 - - - - - 14 - - - - - 15 - - - - - 16 - - - - - 17 - - - - - 18 - - - - - - - UYLViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 22 - - - - - UYLViewController - UIViewController - - UILabel - UIStepper - - - - counter - UILabel - - - stepper - UIStepper - - - - IBProjectSource - ./Classes/UYLViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 933 - - diff --git a/Swiper/Swiper.xcodeproj/project.pbxproj b/Swiper/Swiper.xcodeproj/project.pbxproj new file mode 100644 index 0000000..1b441bf --- /dev/null +++ b/Swiper/Swiper.xcodeproj/project.pbxproj @@ -0,0 +1,329 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 53AF5D0A1F2B662A00BBF2B8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53AF5D091F2B662A00BBF2B8 /* AppDelegate.swift */; }; + 53AF5D0C1F2B662A00BBF2B8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53AF5D0B1F2B662A00BBF2B8 /* ViewController.swift */; }; + 53AF5D0F1F2B662A00BBF2B8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53AF5D0D1F2B662A00BBF2B8 /* Main.storyboard */; }; + 53AF5D111F2B662A00BBF2B8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53AF5D101F2B662A00BBF2B8 /* Assets.xcassets */; }; + 53AF5D141F2B662A00BBF2B8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53AF5D121F2B662A00BBF2B8 /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53AF5D061F2B662A00BBF2B8 /* Swiper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Swiper.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53AF5D091F2B662A00BBF2B8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53AF5D0B1F2B662A00BBF2B8 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 53AF5D0E1F2B662A00BBF2B8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53AF5D101F2B662A00BBF2B8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53AF5D131F2B662A00BBF2B8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53AF5D151F2B662A00BBF2B8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53AF5D031F2B662A00BBF2B8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53AF5CFD1F2B662A00BBF2B8 = { + isa = PBXGroup; + children = ( + 53AF5D081F2B662A00BBF2B8 /* Swiper */, + 53AF5D071F2B662A00BBF2B8 /* Products */, + ); + sourceTree = ""; + }; + 53AF5D071F2B662A00BBF2B8 /* Products */ = { + isa = PBXGroup; + children = ( + 53AF5D061F2B662A00BBF2B8 /* Swiper.app */, + ); + name = Products; + sourceTree = ""; + }; + 53AF5D081F2B662A00BBF2B8 /* Swiper */ = { + isa = PBXGroup; + children = ( + 53AF5D091F2B662A00BBF2B8 /* AppDelegate.swift */, + 53AF5D0B1F2B662A00BBF2B8 /* ViewController.swift */, + 53AF5D0D1F2B662A00BBF2B8 /* Main.storyboard */, + 53AF5D101F2B662A00BBF2B8 /* Assets.xcassets */, + 53AF5D121F2B662A00BBF2B8 /* LaunchScreen.storyboard */, + 53AF5D151F2B662A00BBF2B8 /* Info.plist */, + ); + path = Swiper; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53AF5D051F2B662A00BBF2B8 /* Swiper */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53AF5D181F2B662A00BBF2B8 /* Build configuration list for PBXNativeTarget "Swiper" */; + buildPhases = ( + 53AF5D021F2B662A00BBF2B8 /* Sources */, + 53AF5D031F2B662A00BBF2B8 /* Frameworks */, + 53AF5D041F2B662A00BBF2B8 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Swiper; + productName = Swiper; + productReference = 53AF5D061F2B662A00BBF2B8 /* Swiper.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53AF5CFE1F2B662A00BBF2B8 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0900; + LastUpgradeCheck = 1120; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53AF5D051F2B662A00BBF2B8 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 1120; + }; + }; + }; + buildConfigurationList = 53AF5D011F2B662A00BBF2B8 /* Build configuration list for PBXProject "Swiper" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53AF5CFD1F2B662A00BBF2B8; + productRefGroup = 53AF5D071F2B662A00BBF2B8 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53AF5D051F2B662A00BBF2B8 /* Swiper */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53AF5D041F2B662A00BBF2B8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53AF5D141F2B662A00BBF2B8 /* LaunchScreen.storyboard in Resources */, + 53AF5D111F2B662A00BBF2B8 /* Assets.xcassets in Resources */, + 53AF5D0F1F2B662A00BBF2B8 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53AF5D021F2B662A00BBF2B8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53AF5D0C1F2B662A00BBF2B8 /* ViewController.swift in Sources */, + 53AF5D0A1F2B662A00BBF2B8 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53AF5D0D1F2B662A00BBF2B8 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53AF5D0E1F2B662A00BBF2B8 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53AF5D121F2B662A00BBF2B8 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53AF5D131F2B662A00BBF2B8 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53AF5D161F2B662A00BBF2B8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53AF5D171F2B662A00BBF2B8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53AF5D191F2B662A00BBF2B8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Swiper/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Swiper; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53AF5D1A1F2B662A00BBF2B8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Swiper/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Swiper; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53AF5D011F2B662A00BBF2B8 /* Build configuration list for PBXProject "Swiper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53AF5D161F2B662A00BBF2B8 /* Debug */, + 53AF5D171F2B662A00BBF2B8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53AF5D181F2B662A00BBF2B8 /* Build configuration list for PBXNativeTarget "Swiper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53AF5D191F2B662A00BBF2B8 /* Debug */, + 53AF5D1A1F2B662A00BBF2B8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53AF5CFE1F2B662A00BBF2B8 /* Project object */; +} diff --git a/Swiper/Swiper/AppDelegate.swift b/Swiper/Swiper/AppDelegate.swift new file mode 100644 index 0000000..6420758 --- /dev/null +++ b/Swiper/Swiper/AppDelegate.swift @@ -0,0 +1,35 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/Swiper/Swiper/Assets.xcassets/AppIcon.appiconset/Contents.json b/Swiper/Swiper/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/Swiper/Swiper/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Swiper/Swiper/Base.lproj/LaunchScreen.storyboard b/Swiper/Swiper/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..5654142 --- /dev/null +++ b/Swiper/Swiper/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Swiper/Swiper/Base.lproj/Main.storyboard b/Swiper/Swiper/Base.lproj/Main.storyboard new file mode 100644 index 0000000..022df81 --- /dev/null +++ b/Swiper/Swiper/Base.lproj/Main.storyboard @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Swiper/Swiper/Info.plist b/Swiper/Swiper/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/Swiper/Swiper/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Swiper/Swiper/ViewController.swift b/Swiper/Swiper/ViewController.swift new file mode 100644 index 0000000..877487b --- /dev/null +++ b/Swiper/Swiper/ViewController.swift @@ -0,0 +1,106 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class ViewController: UIViewController { + @IBOutlet private var fullScreenConstraints: [NSLayoutConstraint]! + @IBOutlet private var halfScreenConstraints: [NSLayoutConstraint]! + @IBOutlet private var modeSwitch: UISwitch! + @IBOutlet private var countDisplay: UILabel! + + override var prefersStatusBarHidden: Bool { + if #available(iOS 11.0, *) { + return super.prefersStatusBarHidden + } else { + return fullScreenMode || super.prefersStatusBarHidden + } + } + + override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge { + return fullScreenMode ? [.bottom, .top] : UIRectEdge() + } + + private var count = 0 { + didSet { + countDisplay.text = NumberFormatter.localizedString(from: NSNumber(value: count), number: .decimal) + } + } + + private var fullScreenMode: Bool = false { + didSet { + updateAppearance() + } + } + + private func updateAppearance() { + view.layoutIfNeeded() + updateConstraints() + UIView.animate(withDuration: 0.25) { + self.updateDeferringSystemGestures() + self.view.layoutIfNeeded() + } + } + + private func updateDeferringSystemGestures() { + if #available(iOS 11.0, *) { + setNeedsUpdateOfScreenEdgesDeferringSystemGestures() + } else { + setNeedsStatusBarAppearanceUpdate() + } + } + + private func updateConstraints() { + if fullScreenMode { + halfScreenConstraints.forEach { $0.isActive = false } + fullScreenConstraints.forEach { $0.isActive = true } + } else { + fullScreenConstraints.forEach { $0.isActive = false } + halfScreenConstraints.forEach { $0.isActive = true } + } + } + + @IBAction func fullScreen(_ sender: UISwitch) { + fullScreenMode = sender.isOn + } + + @IBAction func swipeUp(_ sender: UISwipeGestureRecognizer) { + count += 1 + } + + @IBAction func swipeDown(_ sender: UISwipeGestureRecognizer) { + count -= 1 + } + + override func viewDidLoad() { + super.viewDidLoad() + modeSwitch.isOn = fullScreenMode + updateAppearance() + } +} diff --git a/TCNibLoad/Classes/OldViewController.xib b/TCNibLoad/Classes/OldViewController.xib deleted file mode 100644 index feaf2e1..0000000 --- a/TCNibLoad/Classes/OldViewController.xib +++ /dev/null @@ -1,173 +0,0 @@ - - - - 784 - 10B500 - 732 - 1038.2 - 437.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 62 - - - YES - - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - YES - - - - YES - - IBFilesOwner - - - IBFirstResponder - - - - 274 - {320, 460} - - - 3 - MQA - - NO - YES - NO - - NO - 1 - 0 - YES - 44 - 22 - 22 - - - - - YES - - - view - - - - 5 - - - - dataSource - - - - 6 - - - - delegate - - - - 7 - - - - - YES - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - - - YES - - YES - -1.CustomClassName - -2.CustomClassName - 4.IBEditorWindowLastContentRect - 4.IBPluginDependency - - - YES - OldViewController - UIResponder - {{329, 504}, {320, 480}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 7 - - - - YES - - OldViewController - UIViewController - - IBProjectSource - OldViewController.h - - - - - 0 - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - - 3 - 3.1 - - diff --git a/TCNibLoad/LabelCell.xib b/TCNibLoad/LabelCell.xib deleted file mode 100644 index 7ad96df..0000000 --- a/TCNibLoad/LabelCell.xib +++ /dev/null @@ -1,445 +0,0 @@ - - - - 1056 - 10J567 - 823 - 1038.35 - 462.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 132 - - - - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 292 - - - - 256 - - - - 292 - {{20, 9}, {135, 21}} - - NO - YES - 7 - 101 - NO - IBCocoaTouchFramework - Label 1 - - 1 - MCAwIDAAA - - - 3 - MQA - - 1 - 10 - - - - 289 - {{163, 3}, {137, 21}} - - NO - YES - 7 - 102 - NO - IBCocoaTouchFramework - Label 2 - - Helvetica-Oblique - 12 - 16 - - - 1 - MCAwIDEAA - - - 1 - 10 - - - - 289 - {{163, 20}, {137, 16}} - - NO - YES - 7 - 103 - NO - IBCocoaTouchFramework - Label 3 - - Helvetica-Bold - 12 - 16 - - - 1 - MSAwIDAAA - - - 1 - 10 - - - {320, 44} - - - 3 - MCAwAA - - NO - YES - 4 - YES - IBCocoaTouchFramework - - - {320, 44} - - - 1 - MSAxIDEAA - - IBCocoaTouchFramework - 1 - - - LabelCell - - - - - - - labelCell - - - - 12 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 3 - - - - - - - - - - 4 - - - - - 10 - - - - - 11 - - - - - - - OldViewController - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - P4AAAL+AAABDIwAAwgAAAA - - {{125, 502}, {320, 44}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - P4AAAL+AAABBoAAAwgAAAA - - - - - - - 12 - - - - - OldViewController - UITableViewController - - labelCell - UITableViewCell - - - labelCell - - labelCell - UITableViewCell - - - - IBProjectSource - Classes/OldViewController.h - - - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIAccessibility.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UINibLoading.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIResponder.h - - - - UILabel - UIView - - IBFrameworkSource - UIKit.framework/Headers/UILabel.h - - - - UIResponder - NSObject - - - - UISearchBar - UIView - - IBFrameworkSource - UIKit.framework/Headers/UISearchBar.h - - - - UISearchDisplayController - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UISearchDisplayController.h - - - - UITableViewCell - UIView - - IBFrameworkSource - UIKit.framework/Headers/UITableViewCell.h - - - - UITableViewController - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UITableViewController.h - - - - UIView - - IBFrameworkSource - UIKit.framework/Headers/UIPrintFormatter.h - - - - UIView - - IBFrameworkSource - UIKit.framework/Headers/UITextField.h - - - - UIView - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIView.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UINavigationController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UIPopoverController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UISplitViewController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UITabBarController.h - - - - UIViewController - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - TCNibLoad.xcodeproj - 3 - 132 - - diff --git a/TCNibLoad/MainWindow.xib b/TCNibLoad/MainWindow.xib deleted file mode 100644 index d8f4852..0000000 --- a/TCNibLoad/MainWindow.xib +++ /dev/null @@ -1,614 +0,0 @@ - - - - 1056 - 10J567 - 823 - 1038.35 - 462.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 132 - - - YES - - - - YES - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - YES - - YES - - - YES - - - - YES - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - IBCocoaTouchFramework - - - - 1316 - - {320, 480} - - 1 - MSAxIDEAA - - NO - NO - - IBCocoaTouchFramework - YES - - - - - - 1 - - IBCocoaTouchFramework - NO - - - NSBundle - IBCocoaTouchFramework - - - - OldViewController - - 1 - - IBCocoaTouchFramework - NO - - - YES - - - - UINib - IBCocoaTouchFramework - - - - OldViewController - - 1 - - IBCocoaTouchFramework - NO - - - - - 266 - {{129, 330}, {163, 49}} - - 3 - MCAwAA - - NO - IBCocoaTouchFramework - - - - - - YES - - - window - - - - 9 - - - - delegate - - - - 99 - - - - tabBarController - - - - 113 - - - - - YES - - 0 - - - - - - 2 - - - YES - - - - - -1 - - - File's Owner - - - 3 - - - - - 106 - - - YES - - - - - - - - 107 - - - - - 108 - - - YES - - - - NSBundle - - - 109 - - - YES - - - - UINib - - - 110 - - - - - 111 - - - - - -2 - - - - - - - YES - - YES - -1.CustomClassName - -2.CustomClassName - 106.IBEditorWindowLastContentRect - 106.IBPluginDependency - 107.IBPluginDependency - 108.CustomClassName - 108.IBPluginDependency - 109.CustomClassName - 109.IBPluginDependency - 110.IBPluginDependency - 111.IBPluginDependency - 2.IBAttributePlaceholdersKey - 2.IBEditorWindowLastContentRect - 2.IBPluginDependency - 3.CustomClassName - 3.IBPluginDependency - - - YES - UIApplication - UIResponder - {{1125, 676}, {320, 480}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - OldViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - NewViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - YES - - - YES - - - {{229, 373}, {320, 480}} - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - TCNibLoadAppDelegate - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 124 - - - - YES - - NewViewController - OldViewController - - IBProjectSource - Classes/NewViewController.h - - - - OldViewController - UITableViewController - - labelCell - UITableViewCell - - - labelCell - - labelCell - UITableViewCell - - - - IBProjectSource - Classes/OldViewController.h - - - - TCNibLoadAppDelegate - NSObject - - YES - - YES - tabBarController - window - - - YES - UITabBarController - UIWindow - - - - YES - - YES - tabBarController - window - - - YES - - tabBarController - UITabBarController - - - window - UIWindow - - - - - IBProjectSource - Classes/TCNibLoadAppDelegate.h - - - - UIWindow - UIView - - IBUserSource - - - - - - YES - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIAccessibility.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UINibLoading.h - - - - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIResponder.h - - - - UIApplication - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIApplication.h - - - - UIBarItem - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UIBarItem.h - - - - UIResponder - NSObject - - - - UISearchBar - UIView - - IBFrameworkSource - UIKit.framework/Headers/UISearchBar.h - - - - UISearchDisplayController - NSObject - - IBFrameworkSource - UIKit.framework/Headers/UISearchDisplayController.h - - - - UITabBar - UIView - - IBFrameworkSource - UIKit.framework/Headers/UITabBar.h - - - - UITabBarController - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UITabBarController.h - - - - UITabBarItem - UIBarItem - - IBFrameworkSource - UIKit.framework/Headers/UITabBarItem.h - - - - UITableViewCell - UIView - - IBFrameworkSource - UIKit.framework/Headers/UITableViewCell.h - - - - UITableViewController - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UITableViewController.h - - - - UIView - - IBFrameworkSource - UIKit.framework/Headers/UIPrintFormatter.h - - - - UIView - - IBFrameworkSource - UIKit.framework/Headers/UITextField.h - - - - UIView - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIView.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UINavigationController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UIPopoverController.h - - - - UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UISplitViewController.h - - - - UIViewController - - - - UIViewController - UIResponder - - IBFrameworkSource - UIKit.framework/Headers/UIViewController.h - - - - UIWindow - UIView - - IBFrameworkSource - UIKit.framework/Headers/UIWindow.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - - com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 - - - YES - TCNibLoad.xcodeproj - 3 - 132 - - diff --git a/TableHeader/README.md b/TableHeader/README.md new file mode 100644 index 0000000..56fc831 --- /dev/null +++ b/TableHeader/README.md @@ -0,0 +1,14 @@ +### Container + +Example of creating a table view header with a variable height sized to fit +a text label subview. This folder contains both Swift and Objective-C projects. + +#### Further Information + +See the following blog post: + ++ [Variable Height Table View Header](https://useyourloaf.com/blog/variable-height-table-view-header/) + +#### Version History + ++ Version 1.0 17 Mar 2017 Initial release diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC.xcodeproj/project.pbxproj b/TableHeader/TableHeaderObjC/TableHeaderObjC.xcodeproj/project.pbxproj new file mode 100644 index 0000000..aed1668 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC.xcodeproj/project.pbxproj @@ -0,0 +1,382 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 5362BE9C1E7C042700204B31 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5362BE9B1E7C042700204B31 /* main.m */; }; + 5362BE9F1E7C042700204B31 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5362BE9E1E7C042700204B31 /* AppDelegate.m */; }; + 5362BEA51E7C042700204B31 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5362BEA31E7C042700204B31 /* Main.storyboard */; }; + 5362BEA71E7C042700204B31 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5362BEA61E7C042700204B31 /* Assets.xcassets */; }; + 5362BEAA1E7C042700204B31 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5362BEA81E7C042700204B31 /* LaunchScreen.storyboard */; }; + 5362BEB51E7C04BC00204B31 /* ListTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5362BEB41E7C04BC00204B31 /* ListTableViewController.m */; }; + 5362BEB91E7C050E00204B31 /* ListDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 5362BEB81E7C050E00204B31 /* ListDataSource.m */; }; + 5362BEBC1E7C1B3800204B31 /* DataCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5362BEBB1E7C1B3800204B31 /* DataCell.m */; }; + 5362BEBF1E7C239100204B31 /* TextTableHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5362BEBE1E7C239100204B31 /* TextTableHeader.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 5362BE971E7C042700204B31 /* TableHeaderObjC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TableHeaderObjC.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5362BE9B1E7C042700204B31 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 5362BE9D1E7C042700204B31 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 5362BE9E1E7C042700204B31 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 5362BEA41E7C042700204B31 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5362BEA61E7C042700204B31 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5362BEA91E7C042700204B31 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5362BEAB1E7C042700204B31 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5362BEB31E7C04BC00204B31 /* ListTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListTableViewController.h; sourceTree = ""; }; + 5362BEB41E7C04BC00204B31 /* ListTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ListTableViewController.m; sourceTree = ""; }; + 5362BEB71E7C050E00204B31 /* ListDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListDataSource.h; sourceTree = ""; }; + 5362BEB81E7C050E00204B31 /* ListDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ListDataSource.m; sourceTree = ""; }; + 5362BEBA1E7C1B3800204B31 /* DataCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataCell.h; sourceTree = ""; }; + 5362BEBB1E7C1B3800204B31 /* DataCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataCell.m; sourceTree = ""; }; + 5362BEBD1E7C239100204B31 /* TextTableHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTableHeader.h; sourceTree = ""; }; + 5362BEBE1E7C239100204B31 /* TextTableHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextTableHeader.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5362BE941E7C042700204B31 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5362BE8E1E7C042700204B31 = { + isa = PBXGroup; + children = ( + 5362BE991E7C042700204B31 /* TableHeaderObjC */, + 5362BE981E7C042700204B31 /* Products */, + ); + sourceTree = ""; + }; + 5362BE981E7C042700204B31 /* Products */ = { + isa = PBXGroup; + children = ( + 5362BE971E7C042700204B31 /* TableHeaderObjC.app */, + ); + name = Products; + sourceTree = ""; + }; + 5362BE991E7C042700204B31 /* TableHeaderObjC */ = { + isa = PBXGroup; + children = ( + 5362BEB61E7C04CB00204B31 /* Controllers */, + 5362BEB11E7C044A00204B31 /* Delegates */, + 5362BEB21E7C049800204B31 /* Views */, + 5362BE9A1E7C042700204B31 /* Supporting Files */, + ); + path = TableHeaderObjC; + sourceTree = ""; + }; + 5362BE9A1E7C042700204B31 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 5362BEA61E7C042700204B31 /* Assets.xcassets */, + 5362BEAB1E7C042700204B31 /* Info.plist */, + 5362BE9B1E7C042700204B31 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 5362BEB11E7C044A00204B31 /* Delegates */ = { + isa = PBXGroup; + children = ( + 5362BE9D1E7C042700204B31 /* AppDelegate.h */, + 5362BE9E1E7C042700204B31 /* AppDelegate.m */, + 5362BEB71E7C050E00204B31 /* ListDataSource.h */, + 5362BEB81E7C050E00204B31 /* ListDataSource.m */, + ); + name = Delegates; + sourceTree = ""; + }; + 5362BEB21E7C049800204B31 /* Views */ = { + isa = PBXGroup; + children = ( + 5362BEA31E7C042700204B31 /* Main.storyboard */, + 5362BEA81E7C042700204B31 /* LaunchScreen.storyboard */, + 5362BEBA1E7C1B3800204B31 /* DataCell.h */, + 5362BEBB1E7C1B3800204B31 /* DataCell.m */, + 5362BEBD1E7C239100204B31 /* TextTableHeader.h */, + 5362BEBE1E7C239100204B31 /* TextTableHeader.m */, + ); + name = Views; + sourceTree = ""; + }; + 5362BEB61E7C04CB00204B31 /* Controllers */ = { + isa = PBXGroup; + children = ( + 5362BEB31E7C04BC00204B31 /* ListTableViewController.h */, + 5362BEB41E7C04BC00204B31 /* ListTableViewController.m */, + ); + name = Controllers; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5362BE961E7C042700204B31 /* TableHeaderObjC */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5362BEAE1E7C042700204B31 /* Build configuration list for PBXNativeTarget "TableHeaderObjC" */; + buildPhases = ( + 5362BE931E7C042700204B31 /* Sources */, + 5362BE941E7C042700204B31 /* Frameworks */, + 5362BE951E7C042700204B31 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TableHeaderObjC; + productName = TableHeaderObjC; + productReference = 5362BE971E7C042700204B31 /* TableHeaderObjC.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 5362BE8F1E7C042700204B31 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 5362BE961E7C042700204B31 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 5362BE921E7C042700204B31 /* Build configuration list for PBXProject "TableHeaderObjC" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 5362BE8E1E7C042700204B31; + productRefGroup = 5362BE981E7C042700204B31 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5362BE961E7C042700204B31 /* TableHeaderObjC */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5362BE951E7C042700204B31 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5362BEAA1E7C042700204B31 /* LaunchScreen.storyboard in Resources */, + 5362BEA71E7C042700204B31 /* Assets.xcassets in Resources */, + 5362BEA51E7C042700204B31 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5362BE931E7C042700204B31 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5362BE9F1E7C042700204B31 /* AppDelegate.m in Sources */, + 5362BEBC1E7C1B3800204B31 /* DataCell.m in Sources */, + 5362BEBF1E7C239100204B31 /* TextTableHeader.m in Sources */, + 5362BE9C1E7C042700204B31 /* main.m in Sources */, + 5362BEB91E7C050E00204B31 /* ListDataSource.m in Sources */, + 5362BEB51E7C04BC00204B31 /* ListTableViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 5362BEA31E7C042700204B31 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5362BEA41E7C042700204B31 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5362BEA81E7C042700204B31 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5362BEA91E7C042700204B31 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5362BEAC1E7C042700204B31 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5362BEAD1E7C042700204B31 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 5362BEAF1E7C042700204B31 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = TableHeaderObjC/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TableHeaderObjC; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5362BEB01E7C042700204B31 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = TableHeaderObjC/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TableHeaderObjC; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5362BE921E7C042700204B31 /* Build configuration list for PBXProject "TableHeaderObjC" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5362BEAC1E7C042700204B31 /* Debug */, + 5362BEAD1E7C042700204B31 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5362BEAE1E7C042700204B31 /* Build configuration list for PBXNativeTarget "TableHeaderObjC" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5362BEAF1E7C042700204B31 /* Debug */, + 5362BEB01E7C042700204B31 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 5362BE8F1E7C042700204B31 /* Project object */; +} diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/AppDelegate.h b/TableHeader/TableHeaderObjC/TableHeaderObjC/AppDelegate.h new file mode 100644 index 0000000..0c8fe76 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/AppDelegate.h @@ -0,0 +1,39 @@ +// +// AppDelegate.h +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface AppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/AppDelegate.m b/TableHeader/TableHeaderObjC/TableHeaderObjC/AppDelegate.m new file mode 100644 index 0000000..eba1f80 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/AppDelegate.m @@ -0,0 +1,38 @@ +// +// AppDelegate.m +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "AppDelegate.h" + +@implementation AppDelegate +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/Assets.xcassets/AppIcon.appiconset/Contents.json b/TableHeader/TableHeaderObjC/TableHeaderObjC/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/Base.lproj/LaunchScreen.storyboard b/TableHeader/TableHeaderObjC/TableHeaderObjC/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/Base.lproj/Main.storyboard b/TableHeader/TableHeaderObjC/TableHeaderObjC/Base.lproj/Main.storyboard new file mode 100644 index 0000000..dec5842 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/Base.lproj/Main.storyboard @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/DataCell.h b/TableHeader/TableHeaderObjC/TableHeaderObjC/DataCell.h new file mode 100644 index 0000000..70414f1 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/DataCell.h @@ -0,0 +1,42 @@ +// +// DataCell.h +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@interface DataCell : UITableViewCell + ++ (NSString *)reuseIdentifier; +- (void)configure:(NSString *)title; + +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/DataCell.m b/TableHeader/TableHeaderObjC/TableHeaderObjC/DataCell.m new file mode 100644 index 0000000..40e9941 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/DataCell.m @@ -0,0 +1,54 @@ +// +// DataCell.m +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "DataCell.h" + +@interface DataCell () +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@end + +@implementation DataCell + ++ (NSString *)reuseIdentifier { + return NSStringFromClass([self class]); +} + +- (void)configure:(NSString *)title { + self.titleLabel.text = title; + + // Still need to do this manually for iOS 9 + self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; +} + +@end + diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/Info.plist b/TableHeader/TableHeaderObjC/TableHeaderObjC/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/ListDataSource.h b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListDataSource.h new file mode 100644 index 0000000..7dca1fa --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListDataSource.h @@ -0,0 +1,39 @@ +// +// ListDataSource.h +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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; + +@interface ListDataSource : NSObject +- (instancetype)init:(UITableView *)tableView; +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/ListDataSource.m b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListDataSource.m new file mode 100644 index 0000000..a863135 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListDataSource.m @@ -0,0 +1,76 @@ +// +// ListDataSource.m +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "ListDataSource.h" +#import "DataCell.h" + +@interface ListDataSource () +@property (nonatomic, strong) UITableView *tableView; +@end + +@implementation ListDataSource + +- (instancetype)init:(UITableView *)tableView { + self = [super init]; + if (self) { + self.tableView = tableView; + tableView.dataSource = self; + [tableView reloadData]; + } + return self; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return 50; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:[DataCell reuseIdentifier] forIndexPath:indexPath]; + [self configure:cell forIndexPath:indexPath]; + return cell; +} + +- (void)configure:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath { + if ([cell isKindOfClass:[DataCell class]]) { + DataCell *dataCell = (DataCell *)cell; + NSString *title = [NSString stringWithFormat:@"Title for row %ld",(long)indexPath.row]; + [dataCell configure:title]; + } +} + +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/ListTableViewController.h b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListTableViewController.h new file mode 100644 index 0000000..0219e37 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListTableViewController.h @@ -0,0 +1,39 @@ +// +// ListTableViewController.h +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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; + +@interface ListTableViewController : UITableViewController + +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/ListTableViewController.m b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListTableViewController.m new file mode 100644 index 0000000..ed89ea5 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/ListTableViewController.m @@ -0,0 +1,110 @@ +// +// ListTableViewController.m +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "ListTableViewController.h" +#import "ListDataSource.h" + +@interface ListTableViewController () +@property (nonatomic,strong) ListDataSource *listDataSource; +@end + +@implementation ListTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.listDataSource = [[ListDataSource alloc] init:self.tableView]; + self.tableView.dataSource = self.listDataSource; + self.tableView.rowHeight = UITableViewAutomaticDimension; + self.tableView.estimatedRowHeight = UITableViewAutomaticDimension; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentSizeDidChange:) name:UIContentSizeCategoryDidChangeNotification object:nil]; +} + +- (void)contentSizeDidChange:(NSNotification *)notification { + [self.tableView reloadData]; +} + +// viewDidLayoutSubviews() +// Called to notify the view controller that its view has just laid out its +// subviews. + +// When the bounds change for a view controller'€™s view, the view adjusts +// the positions of its subviews and then the system calls this method. +// However, this method being called does not indicate that the individual +// layouts of the view'€™s subviews have been adjusted. Each subview is +// responsible for adjusting its own layout. + +// Your view controller can override this method to make changes after the +// view lays out its subviews. + +// The default implementation of this method does nothing. + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + + UIView *headerView = self.tableView.tableHeaderView; + if (headerView != nil) { + + // The table view header is created with the frame size set in + // the Storyboard. Calculate the new size and reset the header + // view to trigger the layout. + + // Calculate the minimum height of the header view that allows + // the text label to fit its preferred width. + + CGSize size = [headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; + + if (headerView.frame.size.height != size.height) { + CGRect frame = headerView.frame; + frame.size.height = size.height; + headerView.frame = frame; + + // Need to set the header view property of the table view + // to trigger the new layout. Be careful to only do this + // once when the height changes or we get stuck in a layout loop. + + self.tableView.tableHeaderView = headerView; + + // Now that the table view header is sized correctly have + // the table view redo its layout so that the cells are + // correcly positioned for the new header size. + + // This only seems to be necessary on iOS 9. + + [self.tableView layoutIfNeeded]; + } + } +} + +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/TextTableHeader.h b/TableHeader/TableHeaderObjC/TableHeaderObjC/TextTableHeader.h new file mode 100644 index 0000000..faf7414 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/TextTableHeader.h @@ -0,0 +1,39 @@ +// +// TextTableHeader.h +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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; + +@interface TextTableHeader : UIView + +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/TextTableHeader.m b/TableHeader/TableHeaderObjC/TableHeaderObjC/TextTableHeader.m new file mode 100644 index 0000000..e0f7746 --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/TextTableHeader.m @@ -0,0 +1,53 @@ +// +// TextTableHeader.m +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 "TextTableHeader.h" + +@interface TextTableHeader () +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@end + +@implementation TextTableHeader + +- (void)awakeFromNib { + [super awakeFromNib]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentSizeDidChange:) name:UIContentSizeCategoryDidChangeNotification object:nil]; +} + +- (void)contentSizeDidChange:(NSNotification *)notification { + self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle3]; +} + +@end diff --git a/TableHeader/TableHeaderObjC/TableHeaderObjC/main.m b/TableHeader/TableHeaderObjC/TableHeaderObjC/main.m new file mode 100644 index 0000000..b4ccdaf --- /dev/null +++ b/TableHeader/TableHeaderObjC/TableHeaderObjC/main.m @@ -0,0 +1,42 @@ +// +// main.m +// TableHeaderObjC +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/TableHeader/TableHeaderSwift/TableHeader.xcodeproj/project.pbxproj b/TableHeader/TableHeaderSwift/TableHeader.xcodeproj/project.pbxproj new file mode 100644 index 0000000..acbab84 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader.xcodeproj/project.pbxproj @@ -0,0 +1,390 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 53F945981E780436002E1728 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945971E780436002E1728 /* AppDelegate.swift */; }; + 53F9459D1E780436002E1728 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F9459B1E780436002E1728 /* Main.storyboard */; }; + 53F9459F1E780436002E1728 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53F9459E1E780436002E1728 /* Assets.xcassets */; }; + 53F945A21E780436002E1728 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53F945A01E780436002E1728 /* LaunchScreen.storyboard */; }; + 53F945AD1E7805AB002E1728 /* ListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945AC1E7805AB002E1728 /* ListTableViewController.swift */; }; + 53F945B01E7805E8002E1728 /* ListDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945AF1E7805E8002E1728 /* ListDataSource.swift */; }; + 53F945B21E7806F6002E1728 /* DataCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945B11E7806F6002E1728 /* DataCell.swift */; }; + 53F945B51E780713002E1728 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945B31E780713002E1728 /* ConfigurableCell.swift */; }; + 53F945B61E780713002E1728 /* ReusableIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945B41E780713002E1728 /* ReusableIdentifier.swift */; }; + 53F945B91E780AE3002E1728 /* TextTableHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F945B81E780AE3002E1728 /* TextTableHeader.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53F945941E780436002E1728 /* TableHeader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TableHeader.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53F945971E780436002E1728 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53F9459C1E780436002E1728 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53F9459E1E780436002E1728 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53F945A11E780436002E1728 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53F945A31E780436002E1728 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53F945AC1E7805AB002E1728 /* ListTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTableViewController.swift; sourceTree = ""; }; + 53F945AF1E7805E8002E1728 /* ListDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListDataSource.swift; sourceTree = ""; }; + 53F945B11E7806F6002E1728 /* DataCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataCell.swift; sourceTree = ""; }; + 53F945B31E780713002E1728 /* ConfigurableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurableCell.swift; sourceTree = ""; }; + 53F945B41E780713002E1728 /* ReusableIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReusableIdentifier.swift; sourceTree = ""; }; + 53F945B81E780AE3002E1728 /* TextTableHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextTableHeader.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53F945911E780436002E1728 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53F9458B1E780436002E1728 = { + isa = PBXGroup; + children = ( + 53F945961E780436002E1728 /* TableHeader */, + 53F945951E780436002E1728 /* Products */, + ); + sourceTree = ""; + }; + 53F945951E780436002E1728 /* Products */ = { + isa = PBXGroup; + children = ( + 53F945941E780436002E1728 /* TableHeader.app */, + ); + name = Products; + sourceTree = ""; + }; + 53F945961E780436002E1728 /* TableHeader */ = { + isa = PBXGroup; + children = ( + 53F945B71E780719002E1728 /* Protocols and Extensions */, + 53F945A91E780562002E1728 /* Delegates */, + 53F945AE1E7805B6002E1728 /* Controllers */, + 53F945AA1E780570002E1728 /* Views */, + 53F945AB1E780583002E1728 /* Supporting Files */, + ); + path = TableHeader; + sourceTree = ""; + }; + 53F945A91E780562002E1728 /* Delegates */ = { + isa = PBXGroup; + children = ( + 53F945971E780436002E1728 /* AppDelegate.swift */, + 53F945AF1E7805E8002E1728 /* ListDataSource.swift */, + ); + name = Delegates; + sourceTree = ""; + }; + 53F945AA1E780570002E1728 /* Views */ = { + isa = PBXGroup; + children = ( + 53F945B11E7806F6002E1728 /* DataCell.swift */, + 53F945A01E780436002E1728 /* LaunchScreen.storyboard */, + 53F9459B1E780436002E1728 /* Main.storyboard */, + 53F945B81E780AE3002E1728 /* TextTableHeader.swift */, + ); + name = Views; + sourceTree = ""; + }; + 53F945AB1E780583002E1728 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 53F9459E1E780436002E1728 /* Assets.xcassets */, + 53F945A31E780436002E1728 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 53F945AE1E7805B6002E1728 /* Controllers */ = { + isa = PBXGroup; + children = ( + 53F945AC1E7805AB002E1728 /* ListTableViewController.swift */, + ); + name = Controllers; + sourceTree = ""; + }; + 53F945B71E780719002E1728 /* Protocols and Extensions */ = { + isa = PBXGroup; + children = ( + 53F945B31E780713002E1728 /* ConfigurableCell.swift */, + 53F945B41E780713002E1728 /* ReusableIdentifier.swift */, + ); + name = "Protocols and Extensions"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53F945931E780436002E1728 /* TableHeader */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53F945A61E780436002E1728 /* Build configuration list for PBXNativeTarget "TableHeader" */; + buildPhases = ( + 53F945901E780436002E1728 /* Sources */, + 53F945911E780436002E1728 /* Frameworks */, + 53F945921E780436002E1728 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TableHeader; + productName = TableHeader; + productReference = 53F945941E780436002E1728 /* TableHeader.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53F9458C1E780436002E1728 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53F945931E780436002E1728 = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = LCC2J94N44; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 53F9458F1E780436002E1728 /* Build configuration list for PBXProject "TableHeader" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53F9458B1E780436002E1728; + productRefGroup = 53F945951E780436002E1728 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53F945931E780436002E1728 /* TableHeader */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53F945921E780436002E1728 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53F945A21E780436002E1728 /* LaunchScreen.storyboard in Resources */, + 53F9459F1E780436002E1728 /* Assets.xcassets in Resources */, + 53F9459D1E780436002E1728 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53F945901E780436002E1728 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53F945B51E780713002E1728 /* ConfigurableCell.swift in Sources */, + 53F945B61E780713002E1728 /* ReusableIdentifier.swift in Sources */, + 53F945981E780436002E1728 /* AppDelegate.swift in Sources */, + 53F945B91E780AE3002E1728 /* TextTableHeader.swift in Sources */, + 53F945B01E7805E8002E1728 /* ListDataSource.swift in Sources */, + 53F945AD1E7805AB002E1728 /* ListTableViewController.swift in Sources */, + 53F945B21E7806F6002E1728 /* DataCell.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53F9459B1E780436002E1728 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53F9459C1E780436002E1728 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53F945A01E780436002E1728 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53F945A11E780436002E1728 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53F945A41E780436002E1728 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53F945A51E780436002E1728 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53F945A71E780436002E1728 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = TableHeader/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TableHeader; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 53F945A81E780436002E1728 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = TableHeader/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.TableHeader; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53F9458F1E780436002E1728 /* Build configuration list for PBXProject "TableHeader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53F945A41E780436002E1728 /* Debug */, + 53F945A51E780436002E1728 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53F945A61E780436002E1728 /* Build configuration list for PBXNativeTarget "TableHeader" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53F945A71E780436002E1728 /* Debug */, + 53F945A81E780436002E1728 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53F9458C1E780436002E1728 /* Project object */; +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/AppDelegate.swift b/TableHeader/TableHeaderSwift/TableHeader/AppDelegate.swift new file mode 100644 index 0000000..b76494e --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/AppDelegate.swift @@ -0,0 +1,39 @@ +// +// AppDelegate.swift +// TableHeader +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/Assets.xcassets/AppIcon.appiconset/Contents.json b/TableHeader/TableHeaderSwift/TableHeader/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..1d060ed --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TableHeader/TableHeaderSwift/TableHeader/Base.lproj/LaunchScreen.storyboard b/TableHeader/TableHeaderSwift/TableHeader/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..fdf3f97 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TableHeader/TableHeaderSwift/TableHeader/Base.lproj/Main.storyboard b/TableHeader/TableHeaderSwift/TableHeader/Base.lproj/Main.storyboard new file mode 100644 index 0000000..25ef409 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/Base.lproj/Main.storyboard @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TableHeader/TableHeaderSwift/TableHeader/ConfigurableCell.swift b/TableHeader/TableHeaderSwift/TableHeader/ConfigurableCell.swift new file mode 100644 index 0000000..eced6d5 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/ConfigurableCell.swift @@ -0,0 +1,38 @@ +// +// ConfigurableCell.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol ConfigurableCell { + associatedtype Object + func configure(object: Object) +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/DataCell.swift b/TableHeader/TableHeaderSwift/TableHeader/DataCell.swift new file mode 100644 index 0000000..b5a0bad --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/DataCell.swift @@ -0,0 +1,54 @@ +// +// DataCell.swift +// AdjustScroll +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +class DataCell: UITableViewCell, ReusableIdentifier { + @IBOutlet fileprivate var title: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + if #available(iOS 10.0, *) { + title.adjustsFontForContentSizeCategory = true + } + } +} + +extension DataCell: ConfigurableCell { + func configure(object: String) { + title.text = object + + // Still need to do this manually for iOS 9 + title.font = UIFont.preferredFont(forTextStyle: .body) + } +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/Info.plist b/TableHeader/TableHeaderSwift/TableHeader/Info.plist new file mode 100644 index 0000000..d052473 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/TableHeader/TableHeaderSwift/TableHeader/ListDataSource.swift b/TableHeader/TableHeaderSwift/TableHeader/ListDataSource.swift new file mode 100644 index 0000000..d59f1b2 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/ListDataSource.swift @@ -0,0 +1,67 @@ +// +// ListDataSource.swift +// TableHeader +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class ListDataSource: NSObject { + private let tableView: UITableView + + init(tableView: UITableView) { + self.tableView = tableView + super.init() + tableView.dataSource = self + tableView.reloadData() + } +} + +extension ListDataSource: UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 50 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: DataCell.reuseIdentifier, for: indexPath) + configure(cell: cell, indexPath: indexPath) + return cell + } + + private func configure(cell: UITableViewCell, indexPath: IndexPath) { + if let cell = cell as? DataCell { + cell.configure(object: "Title for row \(indexPath.row)") + } + } +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/ListTableViewController.swift b/TableHeader/TableHeaderSwift/TableHeader/ListTableViewController.swift new file mode 100644 index 0000000..1f4a1ff --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/ListTableViewController.swift @@ -0,0 +1,108 @@ +// +// ListTableViewController.swift +// TableHeader +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class ListTableViewController: UITableViewController { + private var listDataSource: ListDataSource? + + override func viewDidLoad() { + super.viewDidLoad() + listDataSource = ListDataSource(tableView: tableView) + tableView.dataSource = listDataSource + tableView.rowHeight = UITableView.automaticDimension + tableView.estimatedRowHeight = UITableView.automaticDimension + + guard #available(iOS 10.0, *) else { + // Manually observe the UIContentSizeCategoryDidChange + // notification for iOS 9. + + NotificationCenter.default.addObserver(self, selector: #selector(contentSizeDidChange(_:)), name: UIContentSizeCategory.didChangeNotification, object: nil) + return + } + } + + @objc private func contentSizeDidChange(_ notification: NSNotification) { + tableView.reloadData() + } + + // viewDidLayoutSubviews() + // Called to notify the view controller that its view has just laid out its + // subviews. + + // When the bounds change for a view controller'€™s view, the view adjusts + // the positions of its subviews and then the system calls this method. + // However, this method being called does not indicate that the individual + // layouts of the view'€™s subviews have been adjusted. Each subview is + // responsible for adjusting its own layout. + + // Your view controller can override this method to make changes after the + // view lays out its subviews. + + // The default implementation of this method does nothing. + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + guard let headerView = tableView.tableHeaderView else { + return + } + + // The table view header is created with the frame size set in + // the Storyboard. Calculate the new size and reset the header + // view to trigger the layout. + + // Calculate the minimum height of the header view that allows + // the text label to fit its preferred width. + + let size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) + + if headerView.frame.size.height != size.height { + headerView.frame.size.height = size.height + + // Need to set the header view property of the table view + // to trigger the new layout. Be careful to only do this + // once when the height changes or we get stuck in a layout loop. + + tableView.tableHeaderView = headerView + + // Now that the table view header is sized correctly have + // the table view redo its layout so that the cells are + // correcly positioned for the new header size. + + // This only seems to be necessary on iOS 9. + + tableView.layoutIfNeeded() + } + } +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/ReusableIdentifier.swift b/TableHeader/TableHeaderSwift/TableHeader/ReusableIdentifier.swift new file mode 100644 index 0000000..893e7f4 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/ReusableIdentifier.swift @@ -0,0 +1,43 @@ +// +// ReusableIdentifier.swift +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2016-2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +protocol ReusableIdentifier: class { + static var reuseIdentifier: String { get } +} + +extension ReusableIdentifier { + static var reuseIdentifier: String { + return "\(self)" + } +} diff --git a/TableHeader/TableHeaderSwift/TableHeader/TextTableHeader.swift b/TableHeader/TableHeaderSwift/TableHeader/TextTableHeader.swift new file mode 100644 index 0000000..24ff3f9 --- /dev/null +++ b/TableHeader/TableHeaderSwift/TableHeader/TextTableHeader.swift @@ -0,0 +1,52 @@ +// +// TextTableHeader.swift +// TableHeader +// +// Created by Keith Harrison http://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class TextTableHeader: UIView { + @IBOutlet private var title: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + if #available(iOS 10.0, *) { + title.adjustsFontForContentSizeCategory = true + } else { + NotificationCenter.default.addObserver(self, selector: #selector(contentSizeDidChange(_:)), name: UIContentSizeCategory.didChangeNotification, object: nil) + } + } + + // Still need to do this manually for iOS 9 + @objc private func contentSizeDidChange(_ notification: NSNotification) { + title.font = UIFont.preferredFont(forTextStyle: .title3) + } +} diff --git a/TaskTimer/TaskTimer/en.lproj/InfoPlist.strings b/TaskTimer/TaskTimer/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/TaskTimer/TaskTimer/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/TaskTimer/TaskTimer/en.lproj/UYLTaskListViewController_iPad.xib b/TaskTimer/TaskTimer/en.lproj/UYLTaskListViewController_iPad.xib deleted file mode 100644 index 3948b16..0000000 --- a/TaskTimer/TaskTimer/en.lproj/UYLTaskListViewController_iPad.xib +++ /dev/null @@ -1,166 +0,0 @@ - - - - 1296 - 11D50 - 2182 - 1138.32 - 568.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBProxyObject - IBUITableView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - - 274 - {{0, 20}, {320, 832}} - - - - 3 - MQA - - YES - - 2 - - - IBUISplitViewMasterSimulatedSizeMetrics - - YES - - - - - - {320, 852} - {320, 768} - - - IBIPadFramework - Master - IBUISplitViewController - - IBUISplitViewControllerContentSizeLocation - IBUISplitViewControllerContentSizeLocationMaster - - - IBIPadFramework - YES - 1 - 0 - YES - 56 - 22 - 22 - - - - - - - view - - - - 3 - - - - dataSource - - - - 4 - - - - delegate - - - - 5 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 2 - - - - - - - UYLTaskListViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 5 - - - - - UYLTaskListViewController - UITableViewController - - IBProjectSource - ./Classes/UYLTaskListViewController.h - - - - - 0 - IBIPadFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1181 - - diff --git a/TaskTimer/TaskTimer/en.lproj/UYLTaskListViewController_iPhone.xib b/TaskTimer/TaskTimer/en.lproj/UYLTaskListViewController_iPhone.xib deleted file mode 100644 index 0087cf4..0000000 --- a/TaskTimer/TaskTimer/en.lproj/UYLTaskListViewController_iPhone.xib +++ /dev/null @@ -1,143 +0,0 @@ - - - - 1296 - 11D50 - 2182 - 1138.32 - 568.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBProxyObject - IBUITableView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - {{0, 20}, {320, 460}} - - - - 3 - MQA - - YES - - IBCocoaTouchFramework - YES - 1 - 0 - YES - 56 - 22 - 22 - - - - - - - view - - - - 3 - - - - dataSource - - - - 4 - - - - delegate - - - - 5 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 2 - - - - - - - UYLTaskListViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 5 - - - - - UYLTaskListViewController - UITableViewController - - IBProjectSource - ./Classes/UYLTaskListViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - 1181 - - diff --git a/TaskTimer/TaskTimer/en.lproj/UYLTaskViewController_iPad.xib b/TaskTimer/TaskTimer/en.lproj/UYLTaskViewController_iPad.xib deleted file mode 100644 index 0fc013c..0000000 --- a/TaskTimer/TaskTimer/en.lproj/UYLTaskViewController_iPad.xib +++ /dev/null @@ -1,331 +0,0 @@ - - - - 1296 - 11E53 - 2182 - 1138.47 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBUIButton - IBUIView - IBUITextField - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBIPadFramework - - - IBFirstResponder - IBIPadFramework - - - - 274 - - - - 290 - {{20, 95}, {728, 31}} - - - - _NS:9 - NO - YES - IBIPadFramework - 0 - - 3 - - 3 - MAA - - 2 - - - YES - 17 - - 2 - 9 - YES - IBCocoaTouchFramework - - 1 - - 1 - 14 - - - Helvetica - 14 - 16 - - - - - 290 - {{20, 176}, {728, 174}} - - - _NS:9 - - 3 - MC42NjY2NjY2NjY3AA - - 3 - IBIPadFramework - - - - -2147483355 - {{314, 462}, {140, 37}} - - - _NS:9 - NO - - Reset - - IBIPadFramework - 0 - 0 - Reset - - 3 - MQA - - - 1 - MSAxIDEAA - - - 3 - MC41AA - - - NSImage - redbutton.png - - - 2 - 2 - - - Helvetica-Bold - 18 - 16 - - - - {{0, 64}, {768, 960}} - - - - - NO - - 2 - - - NO - - IBIPadFramework - - - - - - - view - - - - 12 - - - - taskNote - - - - 69 - - - - taskCounterView - - - - 72 - - - - taskResetButton - - - - 87 - - - - delegate - - - - 68 - - - - taskResetAction - - - 7 - - 88 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 8 - - - - - - - - - - 67 - - - - - 70 - - - - - - 86 - - - - - - - UYLTaskViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UYLCounterView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - - 88 - - - - - UYLCounterView - UIView - - IBProjectSource - ./Classes/UYLCounterView.h - - - - UYLTaskViewController - UIViewController - - taskResetAction - id - - - taskResetAction - - taskResetAction - id - - - - UYLCounterView - UITextField - UIButton - - - - taskCounterView - UYLCounterView - - - taskNote - UITextField - - - taskResetButton - UIButton - - - - IBProjectSource - ./Classes/UYLTaskViewController.h - - - - - 0 - IBIPadFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - - redbutton.png - {140, 40} - - 1181 - - diff --git a/TaskTimer/TaskTimer/en.lproj/UYLTaskViewController_iPhone.xib b/TaskTimer/TaskTimer/en.lproj/UYLTaskViewController_iPhone.xib deleted file mode 100644 index d65f751..0000000 --- a/TaskTimer/TaskTimer/en.lproj/UYLTaskViewController_iPhone.xib +++ /dev/null @@ -1,334 +0,0 @@ - - - - 1296 - 11E53 - 2182 - 1138.47 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBUIButton - IBUIView - IBUITextField - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 290 - {{20, 59}, {280, 60}} - - - - _NS:9 - - 3 - MC42NjY2NjY2NjY3AA - - 3 - IBCocoaTouchFramework - - - - 290 - {{20, 18}, {280, 31}} - - - - _NS:9 - NO - YES - IBCocoaTouchFramework - 0 - - 3 - Enter task description - - 3 - MAA - - 2 - - - YES - 17 - - 2 - 9 - YES - IBCocoaTouchFramework - - 1 - - 1 - 14 - - - Helvetica - 14 - 16 - - - - - -2147483355 - {{90, 140}, {140, 37}} - - - _NS:9 - NO - - Reset - - IBCocoaTouchFramework - 0 - 0 - Reset - - 3 - MQA - - - 1 - MSAxIDEAA - - - 3 - MC41AA - - - NSImage - redbutton.png - - - 2 - 2 - - - Helvetica-Bold - 18 - 16 - - - - {{0, 64}, {320, 416}} - - - - - 3 - MQA - - - - - NO - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - taskNote - - - - 20 - - - - taskCounterView - - - - 23 - - - - taskResetButton - - - - 39 - - - - delegate - - - - 22 - - - - taskResetAction - - - 7 - - 40 - - - - - - 0 - - - - - - 1 - - - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 17 - - - - - - 19 - - - - - 38 - - - - - - - UYLTaskViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UYLCounterView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - - 40 - - - - - UYLCounterView - UIView - - IBProjectSource - ./Classes/UYLCounterView.h - - - - UYLTaskViewController - UIViewController - - taskResetAction - id - - - taskResetAction - - taskResetAction - id - - - - UYLCounterView - UITextField - UIButton - - - - taskCounterView - UYLCounterView - - - taskNote - UITextField - - - taskResetButton - UIButton - - - - IBProjectSource - ./Classes/UYLTaskViewController.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - - redbutton.png - {140, 40} - - 1181 - - diff --git a/TwitterSearch/TwitterSearch/en.lproj/InfoPlist.strings b/TwitterSearch/TwitterSearch/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28f..0000000 --- a/TwitterSearch/TwitterSearch/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/Validate/README.md b/Validate/README.md new file mode 100644 index 0000000..4329027 --- /dev/null +++ b/Validate/README.md @@ -0,0 +1,11 @@ +# Getting Started with Combine + +A gentle introduction to using Combine to validate user input. + +See the following blog post for more details: + ++ [Getting Started with Combine](https://useyourloaf.com/blog/getting-started-with-combine/) + +For details on using Xcode previews with UIKit view controllers see: + ++ [Xcode Previews for View Controllers](https:/useyourloaf.com/blog/xcode-previews-for-view-controllers/) diff --git a/Validate/Validate.xcodeproj/project.pbxproj b/Validate/Validate.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f2273c2 --- /dev/null +++ b/Validate/Validate.xcodeproj/project.pbxproj @@ -0,0 +1,357 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 532A2F1D2425823D00A0005F /* String+Blank.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532A2F1C2425823D00A0005F /* String+Blank.swift */; }; + 5371387A243202D6006CB01D /* TermsViewControllerPreviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53713879243202D6006CB01D /* TermsViewControllerPreviews.swift */; }; + 5385DF762427C259001E63E0 /* AdaptiveScroll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5385DF752427C259001E63E0 /* AdaptiveScroll.swift */; }; + 539CD53024250D75000E2699 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539CD52F24250D75000E2699 /* AppDelegate.swift */; }; + 539CD53224250D75000E2699 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539CD53124250D75000E2699 /* SceneDelegate.swift */; }; + 539CD53724250D75000E2699 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539CD53524250D75000E2699 /* Main.storyboard */; }; + 539CD53924250D76000E2699 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 539CD53824250D76000E2699 /* Assets.xcassets */; }; + 539CD53C24250D76000E2699 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539CD53A24250D76000E2699 /* LaunchScreen.storyboard */; }; + 539CD5442425109F000E2699 /* TermsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539CD5432425109F000E2699 /* TermsViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 532A2F1C2425823D00A0005F /* String+Blank.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Blank.swift"; sourceTree = ""; }; + 53713879243202D6006CB01D /* TermsViewControllerPreviews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsViewControllerPreviews.swift; sourceTree = ""; }; + 5385DF752427C259001E63E0 /* AdaptiveScroll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdaptiveScroll.swift; sourceTree = ""; }; + 539CD52C24250D75000E2699 /* Validate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Validate.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 539CD52F24250D75000E2699 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 539CD53124250D75000E2699 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 539CD53624250D75000E2699 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 539CD53824250D76000E2699 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 539CD53B24250D76000E2699 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 539CD53D24250D76000E2699 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 539CD5432425109F000E2699 /* TermsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TermsViewController.swift; sourceTree = ""; }; + 53D7D6D52429223700ACD670 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 539CD52924250D75000E2699 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 539CD52324250D75000E2699 = { + isa = PBXGroup; + children = ( + 53D7D6D52429223700ACD670 /* README.md */, + 539CD52E24250D75000E2699 /* Validate */, + 539CD52D24250D75000E2699 /* Products */, + ); + sourceTree = ""; + }; + 539CD52D24250D75000E2699 /* Products */ = { + isa = PBXGroup; + children = ( + 539CD52C24250D75000E2699 /* Validate.app */, + ); + name = Products; + sourceTree = ""; + }; + 539CD52E24250D75000E2699 /* Validate */ = { + isa = PBXGroup; + children = ( + 539CD5432425109F000E2699 /* TermsViewController.swift */, + 53713879243202D6006CB01D /* TermsViewControllerPreviews.swift */, + 5385DF752427C259001E63E0 /* AdaptiveScroll.swift */, + 532A2F1C2425823D00A0005F /* String+Blank.swift */, + 539CD52F24250D75000E2699 /* AppDelegate.swift */, + 539CD53124250D75000E2699 /* SceneDelegate.swift */, + 539CD53524250D75000E2699 /* Main.storyboard */, + 539CD53824250D76000E2699 /* Assets.xcassets */, + 539CD53A24250D76000E2699 /* LaunchScreen.storyboard */, + 539CD53D24250D76000E2699 /* Info.plist */, + ); + path = Validate; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 539CD52B24250D75000E2699 /* Validate */ = { + isa = PBXNativeTarget; + buildConfigurationList = 539CD54024250D76000E2699 /* Build configuration list for PBXNativeTarget "Validate" */; + buildPhases = ( + 539CD52824250D75000E2699 /* Sources */, + 539CD52924250D75000E2699 /* Frameworks */, + 539CD52A24250D75000E2699 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Validate; + productName = Validate; + productReference = 539CD52C24250D75000E2699 /* Validate.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 539CD52424250D75000E2699 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1140; + LastUpgradeCheck = 1140; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 539CD52B24250D75000E2699 = { + CreatedOnToolsVersion = 11.4; + }; + }; + }; + buildConfigurationList = 539CD52724250D75000E2699 /* Build configuration list for PBXProject "Validate" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 539CD52324250D75000E2699; + productRefGroup = 539CD52D24250D75000E2699 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 539CD52B24250D75000E2699 /* Validate */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 539CD52A24250D75000E2699 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 539CD53C24250D76000E2699 /* LaunchScreen.storyboard in Resources */, + 539CD53924250D76000E2699 /* Assets.xcassets in Resources */, + 539CD53724250D75000E2699 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 539CD52824250D75000E2699 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 539CD53024250D75000E2699 /* AppDelegate.swift in Sources */, + 5371387A243202D6006CB01D /* TermsViewControllerPreviews.swift in Sources */, + 5385DF762427C259001E63E0 /* AdaptiveScroll.swift in Sources */, + 539CD5442425109F000E2699 /* TermsViewController.swift in Sources */, + 539CD53224250D75000E2699 /* SceneDelegate.swift in Sources */, + 532A2F1D2425823D00A0005F /* String+Blank.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 539CD53524250D75000E2699 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 539CD53624250D75000E2699 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 539CD53A24250D76000E2699 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 539CD53B24250D76000E2699 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 539CD53E24250D76000E2699 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 539CD53F24250D76000E2699 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 539CD54124250D76000E2699 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Validate/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Validate; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 539CD54224250D76000E2699 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Validate/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Validate; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 539CD52724250D75000E2699 /* Build configuration list for PBXProject "Validate" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 539CD53E24250D76000E2699 /* Debug */, + 539CD53F24250D76000E2699 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 539CD54024250D76000E2699 /* Build configuration list for PBXNativeTarget "Validate" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 539CD54124250D76000E2699 /* Debug */, + 539CD54224250D76000E2699 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 539CD52424250D75000E2699 /* Project object */; +} diff --git a/Validate/Validate/AdaptiveScroll.swift b/Validate/Validate/AdaptiveScroll.swift new file mode 100644 index 0000000..5f43115 --- /dev/null +++ b/Validate/Validate/AdaptiveScroll.swift @@ -0,0 +1,67 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class AdaptiveScrollView: UIScrollView { + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setup() + } + + private func setup() { + NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow(_:)), name: UIResponder.keyboardDidShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) + } + + @objc private func keyboardDidShow(_ notification: Notification) { + guard let userInfo = notification.userInfo, + let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { + return + } + + let keyboardSize = keyboardFrame.cgRectValue.size + let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0) + adjustContentInsets(contentInsets) + } + + @objc private func keyboardWillHide(_ notification: Notification) { + adjustContentInsets(.zero) + } + + private func adjustContentInsets(_ contentInsets: UIEdgeInsets) { + contentInset = contentInsets + scrollIndicatorInsets = contentInsets + } +} diff --git a/Validate/Validate/AppDelegate.swift b/Validate/Validate/AppDelegate.swift new file mode 100644 index 0000000..2d32c08 --- /dev/null +++ b/Validate/Validate/AppDelegate.swift @@ -0,0 +1,34 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { +} diff --git a/Validate/Validate/Assets.xcassets/AppIcon.appiconset/Contents.json b/Validate/Validate/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/Validate/Validate/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Validate/Validate/Assets.xcassets/Contents.json b/Validate/Validate/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Validate/Validate/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Validate/Validate/Assets.xcassets/disabledButton.imageset/Contents.json b/Validate/Validate/Assets.xcassets/disabledButton.imageset/Contents.json new file mode 100644 index 0000000..bf86622 --- /dev/null +++ b/Validate/Validate/Assets.xcassets/disabledButton.imageset/Contents.json @@ -0,0 +1,29 @@ +{ + "images" : [ + { + "filename" : "grey.pdf", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "bottom" : 10, + "left" : 10, + "right" : 10, + "top" : 10 + }, + "center" : { + "height" : 1, + "mode" : "tile", + "width" : 1 + }, + "mode" : "9-part" + } + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Validate/Validate/Assets.xcassets/disabledButton.imageset/grey.pdf b/Validate/Validate/Assets.xcassets/disabledButton.imageset/grey.pdf new file mode 100644 index 0000000..759973b Binary files /dev/null and b/Validate/Validate/Assets.xcassets/disabledButton.imageset/grey.pdf differ diff --git a/Validate/Validate/Assets.xcassets/selectedSubmit.imageset/Contents.json b/Validate/Validate/Assets.xcassets/selectedSubmit.imageset/Contents.json new file mode 100644 index 0000000..a9f61c7 --- /dev/null +++ b/Validate/Validate/Assets.xcassets/selectedSubmit.imageset/Contents.json @@ -0,0 +1,29 @@ +{ + "images" : [ + { + "filename" : "greensel.pdf", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "bottom" : 10, + "left" : 10, + "right" : 10, + "top" : 10 + }, + "center" : { + "height" : 1, + "mode" : "tile", + "width" : 1 + }, + "mode" : "9-part" + } + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Validate/Validate/Assets.xcassets/selectedSubmit.imageset/greensel.pdf b/Validate/Validate/Assets.xcassets/selectedSubmit.imageset/greensel.pdf new file mode 100644 index 0000000..7b4ae44 Binary files /dev/null and b/Validate/Validate/Assets.xcassets/selectedSubmit.imageset/greensel.pdf differ diff --git a/Validate/Validate/Assets.xcassets/submitButton.imageset/Contents.json b/Validate/Validate/Assets.xcassets/submitButton.imageset/Contents.json new file mode 100644 index 0000000..fec438a --- /dev/null +++ b/Validate/Validate/Assets.xcassets/submitButton.imageset/Contents.json @@ -0,0 +1,29 @@ +{ + "images" : [ + { + "filename" : "green.pdf", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "bottom" : 12, + "left" : 10, + "right" : 10, + "top" : 12 + }, + "center" : { + "height" : 1, + "mode" : "tile", + "width" : 1 + }, + "mode" : "9-part" + } + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/Validate/Validate/Assets.xcassets/submitButton.imageset/green.pdf b/Validate/Validate/Assets.xcassets/submitButton.imageset/green.pdf new file mode 100644 index 0000000..b3fa12c Binary files /dev/null and b/Validate/Validate/Assets.xcassets/submitButton.imageset/green.pdf differ diff --git a/Validate/Validate/Base.lproj/LaunchScreen.storyboard b/Validate/Validate/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Validate/Validate/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Validate/Validate/Base.lproj/Main.storyboard b/Validate/Validate/Base.lproj/Main.storyboard new file mode 100644 index 0000000..9b9f35e --- /dev/null +++ b/Validate/Validate/Base.lproj/Main.storyboard @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + You must accept these terms and conditions before continuing: + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nec posuere nulla, sit amet fermentum tellus. Pellentesque bibendum eros sed mi ultricies hendrerit quis id mi. Curabitur quis sodales eros. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Validate/Validate/Info.plist b/Validate/Validate/Info.plist new file mode 100644 index 0000000..2a3483c --- /dev/null +++ b/Validate/Validate/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Validate/Validate/SceneDelegate.swift b/Validate/Validate/SceneDelegate.swift new file mode 100644 index 0000000..d6c5aaa --- /dev/null +++ b/Validate/Validate/SceneDelegate.swift @@ -0,0 +1,34 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +final class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? +} diff --git a/Validate/Validate/String+Blank.swift b/Validate/Validate/String+Blank.swift new file mode 100644 index 0000000..22fb8f3 --- /dev/null +++ b/Validate/Validate/String+Blank.swift @@ -0,0 +1,46 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +extension String { + /// A Boolean value indicating whether a String is blank. + /// The string is blank if it is empty or only contains whitespace. + var isBlank: Bool { + return allSatisfy { $0.isWhitespace } + } +} + +extension Optional where Wrapped == String { + /// A Boolean value indicating whether an Optional String is blank. + /// The optional string is blank if it is nil, empty or only contains whitespace. + var isBlank: Bool { + return self?.isBlank ?? true + } +} diff --git a/Validate/Validate/TermsViewController.swift b/Validate/Validate/TermsViewController.swift new file mode 100644 index 0000000..3ca2409 --- /dev/null +++ b/Validate/Validate/TermsViewController.swift @@ -0,0 +1,115 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 Combine +import UIKit + +final class TermsViewController: UIViewController { + @IBOutlet private var termsSwitch: UISwitch! + @IBOutlet private var privacySwitch: UISwitch! + @IBOutlet private var nameField: UITextField! + @IBOutlet private var submitButton: UIButton! + + @Published private var acceptedTerms: Bool = false + @Published private var acceptedPrivacy: Bool = false + @Published private var name: String = "" + + private var stream: AnyCancellable? + + override func viewDidLoad() { + super.viewDidLoad() + stream = validToSubmit + .receive(on: RunLoop.main) + .assign(to: \.isEnabled, on: submitButton) + } + + @IBAction private func acceptTerms(_ sender: UISwitch) { + acceptedTerms = sender.isOn + } + + @IBAction private func acceptPrivacy(_ sender: UISwitch) { + acceptedPrivacy = sender.isOn + } + + @IBAction private func nameChanged(_ sender: UITextField) { + name = sender.text ?? "" + } + + @IBAction private func submitAction(_ sender: UIButton) { + print("Submit... \(name)") + print(view.value(forKey: "_autolayoutTrace")!) + } + + private var validToSubmit: AnyPublisher { + return Publishers.CombineLatest3($acceptedTerms, $acceptedPrivacy, $name) + .map { terms, privacy, name in + terms && privacy && !name.isBlank + }.eraseToAnyPublisher() + } + + // A longer approach just for fun: + // + // private var validName: AnyPublisher { + // return $name.map { name in + // guard !name.isBlank && name.count > 2 else { return nil } + // return name + // }.eraseToAnyPublisher() + // } + // + // private var acceptedAll: AnyPublisher { + // return Publishers.CombineLatest($acceptedTerms, $acceptedPrivacy) + // .map { terms, privacy in + // terms && privacy + // }.eraseToAnyPublisher() + // } + // + // private var validToSubmit: AnyPublisher { + // return Publishers.CombineLatest(acceptedAll, validName) + // .map { terms, name in + // terms && name != nil + // }.eraseToAnyPublisher() + // } +} + +#if DEBUG +import SwiftUI + +extension TermsViewController: UIViewControllerRepresentable { + func makeUIViewController(context: Context) -> TermsViewController { + let storyboard = UIStoryboard(name: "Main", bundle: nil) + guard let viewController = storyboard.instantiateViewController(identifier: "TermsViewController") as? TermsViewController else { + fatalError("Cannot load from storyboard") + } + return viewController + } + + func updateUIViewController(_ uiViewController: TermsViewController, context: Context) { + } +} +#endif diff --git a/Validate/Validate/TermsViewControllerPreviews.swift b/Validate/Validate/TermsViewControllerPreviews.swift new file mode 100644 index 0000000..d32af21 --- /dev/null +++ b/Validate/Validate/TermsViewControllerPreviews.swift @@ -0,0 +1,71 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright © 2020 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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. + +#if DEBUG +import SwiftUI + +let devices = [ + "iPhone SE", + "iPhone 11", + "iPad Pro (11-inch) (2nd generation)" +] + +let sizeCategories: [ContentSizeCategory] = [ + .extraSmall, + .extraExtraExtraLarge, + .accessibilityExtraExtraExtraLarge +] + +struct TermsViewControllerPreviews: PreviewProvider { + static var previews: some View { + Group { + TermsViewController() + .previewDisplayName("Default") + + ForEach(devices, id: \.self) { name in + TermsViewController() + .previewDevice(PreviewDevice(rawValue: name)) + .previewDisplayName(name) + } + + ForEach(ColorScheme.allCases, id: \.self) { scheme in + TermsViewController() + .environment(\.colorScheme, scheme) + .previewDisplayName("\(scheme)") + } + + ForEach(sizeCategories, id: \.self) { size in + TermsViewController() + .environment(\.sizeCategory, size) + .previewDisplayName("\(size)") + } + } + } +} +#endif diff --git a/Vector/README.md b/Vector/README.md new file mode 100644 index 0000000..fcf48ea --- /dev/null +++ b/Vector/README.md @@ -0,0 +1,12 @@ +# Vector + +## Scaled Vector Images + +Examples of using the new *Preserve Vector Data* asset catalog feature, introduced with Xcode 9, to create smooth scaling images. This also makes it easy to support two new accessibility features in iOS 11: + ++ Adjusing Image Sizes For Accessibility ++ Large Content Size Images For Bar Items + +For full details see the blog post: + ++ [Xcode 9 Vector Images](https://useyourloaf.com/blog/xcode-9-vector-images/) diff --git a/Vector/Vector.xcodeproj/project.pbxproj b/Vector/Vector.xcodeproj/project.pbxproj new file mode 100644 index 0000000..2589db3 --- /dev/null +++ b/Vector/Vector.xcodeproj/project.pbxproj @@ -0,0 +1,330 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 53D182791F669CBB001F1840 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D182781F669CBB001F1840 /* AppDelegate.swift */; }; + 53D182801F669CBB001F1840 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53D1827E1F669CBB001F1840 /* Main.storyboard */; }; + 53D182821F669CBB001F1840 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 53D182811F669CBB001F1840 /* Assets.xcassets */; }; + 53D182851F669CBB001F1840 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53D182831F669CBB001F1840 /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 53D182751F669CBB001F1840 /* Vector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Vector.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 53D182781F669CBB001F1840 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 53D1827F1F669CBB001F1840 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 53D182811F669CBB001F1840 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 53D182841F669CBB001F1840 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 53D182861F669CBB001F1840 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53D1828C1F66A024001F1840 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 53D182721F669CBB001F1840 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 53D1826C1F669CBB001F1840 = { + isa = PBXGroup; + children = ( + 53D1828C1F66A024001F1840 /* README.md */, + 53D182771F669CBB001F1840 /* Vector */, + 53D182761F669CBB001F1840 /* Products */, + ); + sourceTree = ""; + }; + 53D182761F669CBB001F1840 /* Products */ = { + isa = PBXGroup; + children = ( + 53D182751F669CBB001F1840 /* Vector.app */, + ); + name = Products; + sourceTree = ""; + }; + 53D182771F669CBB001F1840 /* Vector */ = { + isa = PBXGroup; + children = ( + 53D182781F669CBB001F1840 /* AppDelegate.swift */, + 53D1827E1F669CBB001F1840 /* Main.storyboard */, + 53D182811F669CBB001F1840 /* Assets.xcassets */, + 53D182831F669CBB001F1840 /* LaunchScreen.storyboard */, + 53D182861F669CBB001F1840 /* Info.plist */, + ); + path = Vector; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 53D182741F669CBB001F1840 /* Vector */ = { + isa = PBXNativeTarget; + buildConfigurationList = 53D182891F669CBB001F1840 /* Build configuration list for PBXNativeTarget "Vector" */; + buildPhases = ( + 53D182711F669CBB001F1840 /* Sources */, + 53D182721F669CBB001F1840 /* Frameworks */, + 53D182731F669CBB001F1840 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Vector; + productName = Vector; + productReference = 53D182751F669CBB001F1840 /* Vector.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 53D1826D1F669CBB001F1840 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0900; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "Keith Harrison"; + TargetAttributes = { + 53D182741F669CBB001F1840 = { + CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 1120; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 53D182701F669CBB001F1840 /* Build configuration list for PBXProject "Vector" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 53D1826C1F669CBB001F1840; + productRefGroup = 53D182761F669CBB001F1840 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 53D182741F669CBB001F1840 /* Vector */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 53D182731F669CBB001F1840 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53D182851F669CBB001F1840 /* LaunchScreen.storyboard in Resources */, + 53D182821F669CBB001F1840 /* Assets.xcassets in Resources */, + 53D182801F669CBB001F1840 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 53D182711F669CBB001F1840 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 53D182791F669CBB001F1840 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 53D1827E1F669CBB001F1840 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53D1827F1F669CBB001F1840 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 53D182831F669CBB001F1840 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 53D182841F669CBB001F1840 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 53D182871F669CBB001F1840 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 53D182881F669CBB001F1840 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 53D1828A1F669CBB001F1840 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Vector/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Vector; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 53D1828B1F669CBB001F1840 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = LCC2J94N44; + INFOPLIST_FILE = Vector/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.useyourloaf.Vector; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 53D182701F669CBB001F1840 /* Build configuration list for PBXProject "Vector" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53D182871F669CBB001F1840 /* Debug */, + 53D182881F669CBB001F1840 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 53D182891F669CBB001F1840 /* Build configuration list for PBXNativeTarget "Vector" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 53D1828A1F669CBB001F1840 /* Debug */, + 53D1828B1F669CBB001F1840 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 53D1826D1F669CBB001F1840 /* Project object */; +} diff --git a/Vector/Vector/AppDelegate.swift b/Vector/Vector/AppDelegate.swift new file mode 100644 index 0000000..6420758 --- /dev/null +++ b/Vector/Vector/AppDelegate.swift @@ -0,0 +1,35 @@ +// Created by Keith Harrison https://useyourloaf.com +// Copyright (c) 2017 Keith Harrison. 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 nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// 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 HOLDER 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 + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? +} diff --git a/Vector/Vector/Assets.xcassets/AppIcon.appiconset/Contents.json b/Vector/Vector/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/Contents.json b/Vector/Vector/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/arrow-fill.imageset/Contents.json b/Vector/Vector/Assets.xcassets/arrow-fill.imageset/Contents.json new file mode 100644 index 0000000..b54f13d --- /dev/null +++ b/Vector/Vector/Assets.xcassets/arrow-fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "arrow30-fill.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/arrow-fill.imageset/arrow30-fill.pdf b/Vector/Vector/Assets.xcassets/arrow-fill.imageset/arrow30-fill.pdf new file mode 100644 index 0000000..e218476 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/arrow-fill.imageset/arrow30-fill.pdf differ diff --git a/Vector/Vector/Assets.xcassets/arrow-large.imageset/Contents.json b/Vector/Vector/Assets.xcassets/arrow-large.imageset/Contents.json new file mode 100644 index 0000000..b54f13d --- /dev/null +++ b/Vector/Vector/Assets.xcassets/arrow-large.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "arrow30-fill.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/arrow-large.imageset/arrow30-fill.pdf b/Vector/Vector/Assets.xcassets/arrow-large.imageset/arrow30-fill.pdf new file mode 100644 index 0000000..e218476 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/arrow-large.imageset/arrow30-fill.pdf differ diff --git a/Vector/Vector/Assets.xcassets/arrow.imageset/Contents.json b/Vector/Vector/Assets.xcassets/arrow.imageset/Contents.json new file mode 100644 index 0000000..cd093a4 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/arrow.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "arrow30.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/arrow.imageset/arrow30.pdf b/Vector/Vector/Assets.xcassets/arrow.imageset/arrow30.pdf new file mode 100644 index 0000000..d1e947b Binary files /dev/null and b/Vector/Vector/Assets.xcassets/arrow.imageset/arrow30.pdf differ diff --git a/Vector/Vector/Assets.xcassets/cross-fill.imageset/Contents.json b/Vector/Vector/Assets.xcassets/cross-fill.imageset/Contents.json new file mode 100644 index 0000000..c4d92d6 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/cross-fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "cross30-fill.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/cross-fill.imageset/cross30-fill.pdf b/Vector/Vector/Assets.xcassets/cross-fill.imageset/cross30-fill.pdf new file mode 100644 index 0000000..4a8a20b Binary files /dev/null and b/Vector/Vector/Assets.xcassets/cross-fill.imageset/cross30-fill.pdf differ diff --git a/Vector/Vector/Assets.xcassets/cross-large.imageset/Contents.json b/Vector/Vector/Assets.xcassets/cross-large.imageset/Contents.json new file mode 100644 index 0000000..a00e719 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/cross-large.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "cross75.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/cross-large.imageset/cross75.pdf b/Vector/Vector/Assets.xcassets/cross-large.imageset/cross75.pdf new file mode 100644 index 0000000..7611740 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/cross-large.imageset/cross75.pdf differ diff --git a/Vector/Vector/Assets.xcassets/cross.imageset/Contents.json b/Vector/Vector/Assets.xcassets/cross.imageset/Contents.json new file mode 100644 index 0000000..1835714 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/cross.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "cross30.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/cross.imageset/cross30.pdf b/Vector/Vector/Assets.xcassets/cross.imageset/cross30.pdf new file mode 100644 index 0000000..51eb165 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/cross.imageset/cross30.pdf differ diff --git a/Vector/Vector/Assets.xcassets/star-vector.imageset/Contents.json b/Vector/Vector/Assets.xcassets/star-vector.imageset/Contents.json new file mode 100644 index 0000000..3bc6cd0 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/star-vector.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "star100.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/star-vector.imageset/star100.pdf b/Vector/Vector/Assets.xcassets/star-vector.imageset/star100.pdf new file mode 100644 index 0000000..ae25014 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/star-vector.imageset/star100.pdf differ diff --git a/Vector/Vector/Assets.xcassets/star.imageset/Contents.json b/Vector/Vector/Assets.xcassets/star.imageset/Contents.json new file mode 100644 index 0000000..0875f21 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/star.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "star100.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/star.imageset/star100.pdf b/Vector/Vector/Assets.xcassets/star.imageset/star100.pdf new file mode 100644 index 0000000..ae25014 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/star.imageset/star100.pdf differ diff --git a/Vector/Vector/Assets.xcassets/tick-fill.imageset/Contents.json b/Vector/Vector/Assets.xcassets/tick-fill.imageset/Contents.json new file mode 100644 index 0000000..59e7bc9 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/tick-fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tick30-fill.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/tick-fill.imageset/tick30-fill.pdf b/Vector/Vector/Assets.xcassets/tick-fill.imageset/tick30-fill.pdf new file mode 100644 index 0000000..c3ac5b1 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/tick-fill.imageset/tick30-fill.pdf differ diff --git a/Vector/Vector/Assets.xcassets/tick-large.imageset/Contents.json b/Vector/Vector/Assets.xcassets/tick-large.imageset/Contents.json new file mode 100644 index 0000000..f323f00 --- /dev/null +++ b/Vector/Vector/Assets.xcassets/tick-large.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tick75.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/tick-large.imageset/tick75.pdf b/Vector/Vector/Assets.xcassets/tick-large.imageset/tick75.pdf new file mode 100644 index 0000000..1f3904c Binary files /dev/null and b/Vector/Vector/Assets.xcassets/tick-large.imageset/tick75.pdf differ diff --git a/Vector/Vector/Assets.xcassets/tick.imageset/Contents.json b/Vector/Vector/Assets.xcassets/tick.imageset/Contents.json new file mode 100644 index 0000000..266590c --- /dev/null +++ b/Vector/Vector/Assets.xcassets/tick.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tick30.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Vector/Vector/Assets.xcassets/tick.imageset/tick30.pdf b/Vector/Vector/Assets.xcassets/tick.imageset/tick30.pdf new file mode 100644 index 0000000..4249d58 Binary files /dev/null and b/Vector/Vector/Assets.xcassets/tick.imageset/tick30.pdf differ diff --git a/Vector/Vector/Base.lproj/LaunchScreen.storyboard b/Vector/Vector/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f83f6fd --- /dev/null +++ b/Vector/Vector/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vector/Vector/Base.lproj/Main.storyboard b/Vector/Vector/Base.lproj/Main.storyboard new file mode 100644 index 0000000..4c052d6 --- /dev/null +++ b/Vector/Vector/Base.lproj/Main.storyboard @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vector/Vector/Info.plist b/Vector/Vector/Info.plist new file mode 100644 index 0000000..6873106 --- /dev/null +++ b/Vector/Vector/Info.plist @@ -0,0 +1,55 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/WorldFacts/README b/WorldFacts/README.md similarity index 53% rename from WorldFacts/README rename to WorldFacts/README.md index dd6c39d..f108fed 100644 --- a/WorldFacts/README +++ b/WorldFacts/README.md @@ -1,35 +1,25 @@ -======================================================================= -WorldFacts - -Version 3.2 12 Oct 2015 Add 3D Touch peek and pop preview -Version 3.1 25 May 2015 Increase width of split view master view -Version 3.0 27 Mar 2015 Add OS X application to create core data -Version 2.0 16 Feb 2014 Update for iOS 8 and UISearchController -Version 1.5 20 Feb 2013 Move core data file to App Support dir -Version 1.4 31 Dec 2012 Add default launch images to support retina - 4 inch display -Version 1.3 6 Sep 2012 Add a search bar -Version 1.2 1 Aug 2012 Use default synthesis of ivars -Version 1.1 21 June 2012 Add Storyboard segue to country view -Version 1.0 6 June 2012 Initial Version -======================================================================= +## WorldFacts The WorldFacts App has gone through a number of iterations over the years as the capabilities of iOS have changed. Originally it started as an example of how to construct custom table view cells with a -storyboard. For further details see the post: +storyboard. Some of the earlier posts are likely only of historical interest +now but I think it is interesting to show how much iOS apps need to change +over the years. + +For further details see the following posts: -useyourloaf.com/blog/2012/06/07/prototype-cells-and-storyboards.html +* [Prototype Table Cells and Storyboards](https://useyourloaf.com/blog/prototype-table-cells-and-storyboards/) For details on adding a storyboard segue to show the country detailed view see the following post: -useyourloaf.com/blog/2012/06/21/storyboard-segues.html +* [Storyboard Segues](https://useyourloaf.com/blog/storyboard-segues/) The steps to add a search bar to the table view controller are covered in the following post: -useyourloaf.com/blog/2012/09/06/search-bar-table-view-storyboard.html +* [Adding A Search Bar To A Table View With Storyboards](https://useyourloaf.com/blog/search-bar-table-view-storyboard/) The release of iOS 8 saw a number of changes to update and modernise the code: @@ -49,72 +39,80 @@ An OS X companion app has also been added to create and maintain the core data stack. Full details on how to use Cocoa Bindings to create a simple interface to Core Data are covered in the following post: -useyourloaf.com/blog/2015/03/25/creating-an-os-x-core-data-helper-app.html +* [Creating an OS X Core Data Helper App](https://useyourloaf.com/blog/creating-an-os-x-core-data-helper-app/) To see details on how to increase the width of the master view of the split view controller see the following post: -useyourloaf.com/blog/2015/05/25/change-the-width-of-master-view-in-split-view-controller.html +* [Change the Width of Master View in Split View Controller](https://useyourloaf.com//blog/change-the-width-of-master-view-in-split-view-controller/) The geographic data used in this App is from GeoNames and used under -the Creative Commons Attributions License (see www.geonames.org). +the Creative Commons Attributions License. See [www.geonames.org](www.geonames.org). -======================================================================= -Model -======================================================================= +### Model -WorldFacts.xcdatamodeld +* `WorldFacts.xcdatamodeld` -The core data model definition contains a single entity for the Country + The core data model definition contains a single entity for the Country managed object. -Country.h -Country.m +* `Country.h` +* `Country.m` -The generated NSManagedObject subclass + The generated `NSManagedObject` subclass -Country+Extensions.h -Country+Extensions.m +* `Country+Extensions.h` +* `Country+Extensions.m` -Private class extensions for the Country NSManagedObject subclass to + Private class extensions for the Country NSManagedObject subclass to generate the section title used by the NSFetchedResultsController and to import an initial set of geographic data from countries.plist. -======================================================================= -View -======================================================================= +### View -Main.storyboard -The universal storyboard file used to create the table and details view +* `Main.storyboard` + The universal storyboard file used to create the table and details view -======================================================================= -Controllers -======================================================================= +### Controllers -UYLCountryTableViewController.h -UYLCountryTableViewController.m +* `UYLCountryTableViewController.h` +* `UYLCountryTableViewController.m` -The table view controller used to show the list of countries with + The table view controller used to show the list of countries with details on the capital and population and manage the search interface. The table view controller implementation is a standard implementation -of an NSFetchResultsController. +of an `NSFetchResultsController`. -UYLCountryViewController.h -UYLCountryViewController.m +* `UYLCountryViewController.h` +* `UYLCountryViewController.m` -The view controller used to show the detailed country view. This view + The view controller used to show the detailed country view. This view controller does almost nothing other than set up the view from the Country object it is passed. -======================================================================= -App Delegate -======================================================================= +### App Delegate -UYLAppDelegate.h -UYLAppDelegate.m +* `UYLAppDelegate.h` +* `UYLAppDelegate.m` -The App delegate is largely unmodified from the template code. It creates + The App delegate is largely unmodified from the template code. It creates the root view controller using a storyboard and initialises the core data -stack. \ No newline at end of file +stack. + +### Version History + +Version 3.3 19 Jan 2018 Update for Xcode 9, minimum target is iOS 9 +Version 3.2 12 Oct 2015 Add 3D Touch peek and pop preview +Version 3.1 25 May 2015 Increase width of split view master view +Version 3.0 27 Mar 2015 Add OS X application to create core data +Version 2.0 16 Feb 2014 Update for iOS 8 and UISearchController +Version 1.5 20 Feb 2013 Move core data file to App Support dir +Version 1.4 31 Dec 2012 Add default launch images to support retina +4 inch display +Version 1.3 6 Sep 2012 Add a search bar +Version 1.2 1 Aug 2012 Use default synthesis of ivars +Version 1.1 21 June 2012 Add Storyboard segue to country view +Version 1.0 6 June 2012 Initial Version + diff --git a/WorldFacts/WorldFacts.xcodeproj/project.pbxproj b/WorldFacts/WorldFacts.xcodeproj/project.pbxproj index 801835d..dc570e8 100644 --- a/WorldFacts/WorldFacts.xcodeproj/project.pbxproj +++ b/WorldFacts/WorldFacts.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -12,7 +12,6 @@ 531D96151AB62FEF00913A78 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 531D96141AB62FEF00913A78 /* main.m */; }; 531D961D1AB62FEF00913A78 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 531D961C1AB62FEF00913A78 /* Images.xcassets */; }; 531D96201AB62FEF00913A78 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 531D961E1AB62FEF00913A78 /* Main.storyboard */; }; - 532CADEB158D1286002BEDC8 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 532CADEA158D1286002BEDC8 /* README */; }; 532CADF5158D19D1002BEDC8 /* UYLCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 532CADF4158D19D1002BEDC8 /* UYLCountryViewController.m */; }; 534EBDA01AC4B0F90014AD9D /* WorldFacts.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 534EBD9F1AC4B0F90014AD9D /* WorldFacts.sqlite */; }; 536346AE1AC0BE440087214A /* CountryTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 536346AD1AC0BE440087214A /* CountryTableViewController.m */; }; @@ -43,7 +42,7 @@ 531D96141AB62FEF00913A78 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 531D961C1AB62FEF00913A78 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 531D961F1AB62FEF00913A78 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 532CADEA158D1286002BEDC8 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 532CADEA158D1286002BEDC8 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 532CADF3158D19D1002BEDC8 /* UYLCountryViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UYLCountryViewController.h; sourceTree = ""; }; 532CADF4158D19D1002BEDC8 /* UYLCountryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UYLCountryViewController.m; sourceTree = ""; }; 534EBD9F1AC4B0F90014AD9D /* WorldFacts.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = WorldFacts.sqlite; sourceTree = ""; }; @@ -116,7 +115,7 @@ 538A796D157E567E0007B8A5 = { isa = PBXGroup; children = ( - 532CADEA158D1286002BEDC8 /* README */, + 532CADEA158D1286002BEDC8 /* README.md */, 538A7984157E567F0007B8A5 /* WorldFacts */, 531D960E1AB62FEF00913A78 /* WorldFactsBuilder */, 538A7979157E567F0007B8A5 /* Products */, @@ -236,16 +235,19 @@ isa = PBXProject; attributes = { CLASSPREFIX = UYL; - LastUpgradeCheck = 0630; + LastUpgradeCheck = 1100; TargetAttributes = { 531D960C1AB62FEF00913A78 = { CreatedOnToolsVersion = 6.2; }; + 538A7977157E567F0007B8A5 = { + DevelopmentTeam = LCC2J94N44; + }; }; }; buildConfigurationList = 538A7972157E567E0007B8A5 /* Build configuration list for PBXProject "WorldFacts" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 11.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -282,7 +284,6 @@ 53B691731A3A5AE500DDFBE2 /* Localizable.strings in Resources */, 53E782701A365AE60075A619 /* Main.storyboard in Resources */, 53EEC7E71A4B6254000EB901 /* LaunchScreen.storyboard in Resources */, - 532CADEB158D1286002BEDC8 /* README in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -363,9 +364,13 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = WorldFactsBuilder/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; }; @@ -385,9 +390,13 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = WorldFactsBuilder/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; }; @@ -397,21 +406,33 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -428,7 +449,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; ONLY_ACTIVE_ARCH = YES; PROVISIONING_PROFILE = ""; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; @@ -440,15 +461,26 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -464,7 +496,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; PROVISIONING_PROFILE = ""; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; @@ -477,9 +509,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CURRENT_PROJECT_VERSION = 12; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = NO; INFOPLIST_FILE = "WorldFacts/WorldFacts-Info.plist"; + MARKETING_VERSION = 3.4; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; @@ -490,9 +525,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CURRENT_PROJECT_VERSION = 12; + DEVELOPMENT_TEAM = LCC2J94N44; GCC_PRECOMPILE_PREFIX_HEADER = NO; INFOPLIST_FILE = "WorldFacts/WorldFacts-Info.plist"; + MARKETING_VERSION = 3.4; + PRODUCT_BUNDLE_IDENTIFIER = "com.useyourloaf.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; diff --git a/WorldFacts/WorldFacts/Base.lproj/Main.storyboard b/WorldFacts/WorldFacts/Base.lproj/Main.storyboard index 231a79f..2cdc686 100644 --- a/WorldFacts/WorldFacts/Base.lproj/Main.storyboard +++ b/WorldFacts/WorldFacts/Base.lproj/Main.storyboard @@ -1,9 +1,11 @@ - - + + + - - + + + @@ -11,8 +13,8 @@ + - @@ -26,115 +28,96 @@ - - - - - + - - + @@ -160,7 +143,7 @@ - + @@ -177,7 +160,7 @@ - + @@ -186,6 +169,7 @@ + @@ -236,41 +220,36 @@ - + - - + - + - + - @@ -284,8 +263,7 @@ - - + @@ -311,8 +289,8 @@ + - diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Contents.json b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Contents.json index 6ef7107..c3a6f2d 100644 --- a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,17 +1,41 @@ { "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon2-20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "icon2-20@3x.png", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-Small@2x.png", "scale" : "2x" }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon2-29@3x.png", + "scale" : "3x" + }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-80-1.png", "scale" : "2x" }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon2-60@2x.png", + "scale" : "3x" + }, { "size" : "60x60", "idiom" : "iphone", @@ -24,6 +48,18 @@ "filename" : "Icon-180.png", "scale" : "3x" }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon2-20.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "icon2-20@2x-1.png", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", @@ -59,6 +95,18 @@ "idiom" : "ipad", "filename" : "icon-152.png", "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon2-835@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "icon2-1024.png", + "scale" : "1x" } ], "info" : { diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png new file mode 100644 index 0000000..d828562 Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-29@3x.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-60@2x.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-60@2x.png new file mode 100644 index 0000000..ffb0d74 Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-60@2x.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png new file mode 100644 index 0000000..eb4d728 Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/Icon2-835@2x.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-1024.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-1024.png new file mode 100644 index 0000000..b628b9e Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-1024.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20.png new file mode 100644 index 0000000..08dee7a Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@2x-1.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@2x-1.png new file mode 100644 index 0000000..d6fccd4 Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@2x-1.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@2x.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@2x.png new file mode 100644 index 0000000..d6fccd4 Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@2x.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@3x.png b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@3x.png new file mode 100644 index 0000000..fafe147 Binary files /dev/null and b/WorldFacts/WorldFacts/Images.xcassets/AppIcon.appiconset/icon2-20@3x.png differ diff --git a/WorldFacts/WorldFacts/Images.xcassets/Contents.json b/WorldFacts/WorldFacts/Images.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/WorldFacts/WorldFacts/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/WorldFacts/WorldFacts/Images.xcassets/LaunchImage.launchimage/Contents.json b/WorldFacts/WorldFacts/Images.xcassets/LaunchImage.launchimage/Contents.json deleted file mode 100644 index 6da7c45..0000000 --- a/WorldFacts/WorldFacts/Images.xcassets/LaunchImage.launchimage/Contents.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "images" : [ - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "iphone", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "subtype" : "retina4", - "scale" : "2x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/WorldFacts/WorldFacts/LaunchScreen.storyboard b/WorldFacts/WorldFacts/LaunchScreen.storyboard index 58daca0..fe2e48d 100644 --- a/WorldFacts/WorldFacts/LaunchScreen.storyboard +++ b/WorldFacts/WorldFacts/LaunchScreen.storyboard @@ -1,7 +1,10 @@ - - + + + - + + + @@ -13,9 +16,9 @@ - + - + @@ -29,7 +32,7 @@ - + diff --git a/WorldFacts/WorldFacts/UYLAppDelegate.m b/WorldFacts/WorldFacts/UYLAppDelegate.m index 28b25ed..d6fd8e0 100644 --- a/WorldFacts/WorldFacts/UYLAppDelegate.m +++ b/WorldFacts/WorldFacts/UYLAppDelegate.m @@ -107,7 +107,7 @@ - (NSManagedObjectContext *)managedObjectContext NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { - _managedObjectContext = [[NSManagedObjectContext alloc] init]; + _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext; diff --git a/WorldFacts/WorldFacts/UYLCountryTableViewController.m b/WorldFacts/WorldFacts/UYLCountryTableViewController.m index 5a60765..8d0b389 100644 --- a/WorldFacts/WorldFacts/UYLCountryTableViewController.m +++ b/WorldFacts/WorldFacts/UYLCountryTableViewController.m @@ -82,8 +82,12 @@ - (void)viewDidLoad NSLocalizedString(@"ScopeButtonCapital",@"Capital")]; self.searchController.searchBar.delegate = self; - self.tableView.tableHeaderView = self.searchController.searchBar; - + if (@available(iOS 11.0, *)) { + self.navigationItem.searchController = self.searchController; + self.navigationItem.hidesSearchBarWhenScrolling = NO; + } else { + self.tableView.tableHeaderView = self.searchController.searchBar; + } self.definesPresentationContext = YES; // The search bar does not seem to set its size automatically diff --git a/WorldFacts/WorldFacts/WorldFacts-Info.plist b/WorldFacts/WorldFacts/WorldFacts-Info.plist index 721523f..528a05a 100644 --- a/WorldFacts/WorldFacts/WorldFacts-Info.plist +++ b/WorldFacts/WorldFacts/WorldFacts-Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.useyourloaf.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.2 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 10 + $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/WorldFacts/WorldFactsBuilder/Info.plist b/WorldFacts/WorldFactsBuilder/Info.plist index cdc67a1..cb0cc0d 100644 --- a/WorldFacts/WorldFactsBuilder/Info.plist +++ b/WorldFacts/WorldFactsBuilder/Info.plist @@ -9,7 +9,7 @@ CFBundleIconFile CFBundleIdentifier - com.useyourloaf.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName