commit d2cc0bb69605e510ac72396daf7ec15cae858884
Author: Apple <>
Date: Tue Aug 28 13:42:15 2018 -0700
Initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8463840
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+# See LICENSE folder for this sample’s licensing information.
+#
+# Apple sample code gitignore configuration.
+
+# Finder
+.DS_Store
+
+# Xcode - User files
+xcuserdata/
+*.xcworkspace
diff --git a/Configuration/SampleCode.xcconfig b/Configuration/SampleCode.xcconfig
new file mode 100644
index 0000000..db86c06
--- /dev/null
+++ b/Configuration/SampleCode.xcconfig
@@ -0,0 +1,13 @@
+//
+// See LICENSE folder for this sample’s licensing information.
+//
+// SampleCode.xcconfig
+//
+
+// The `SAMPLE_CODE_DISAMBIGUATOR` configuration is to make it easier to build
+// and run a sample code project. Once you set your project's development team,
+// you'll have a unique bundle identifier. This is because the bundle identifier
+// is derived based on the 'SAMPLE_CODE_DISAMBIGUATOR' value. Do not use this
+// approach in your own projects—it's only useful for sample code projects because
+// they are frequently downloaded and don't have a development team set.
+SAMPLE_CODE_DISAMBIGUATOR=${DEVELOPMENT_TEAM}
diff --git a/LICENSE/LICENSE.txt b/LICENSE/LICENSE.txt
new file mode 100644
index 0000000..f6a0587
--- /dev/null
+++ b/LICENSE/LICENSE.txt
@@ -0,0 +1,8 @@
+Copyright © 2018 Apple Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..46a073f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,202 @@
+# UIKitCatalog: Creating and Customizing Views and Controls
+
+Customize your app's user interface by using views and controls in UIKit.
+
+## Overview
+
+This sample guides you through several types of customizations that you can do in your iOS app. The sample uses a split view controller architecture for navigating UIKit views and controls. The primary view controller (`MasterViewController`) shows the available views and controls. Selecting one shows the secondary view controller associated with it.
+
+The name of each secondary view controller reflects its *target item*. For example, the `AlertControllerViewController` class shows how to use a `UIAlertController` object. The only exceptions to this rule are `UISearchBar` and `UIToolbar`; these APIs are demonstrated in multiple view controllers to explain how their controls function and how to customize them. To demonstrate how to manage the complexity of your storyboards, all view controllers are hosted in a separate storyboard and loaded when needed.
+
+This sample demonstrates the following views and controls (several of which are referenced in the sections below):
+
+* [`UIActivityIndicatorView`](https://developer.apple.com/documentation/uikit/uiactivityindicatorview)
+* [`UIAlertController`](https://developer.apple.com/documentation/uikit/uialertcontroller)
+* [`UIButton`](https://developer.apple.com/documentation/uikit/uibutton)
+* [`UIDatePicker`](https://developer.apple.com/documentation/uikit/uidatepicker)
+* [`UIImageView`](https://developer.apple.com/documentation/uikit/uiimageview)
+* [`UIPageControl`](https://developer.apple.com/documentation/uikit/uipagecontrol)
+* [`UIPickerView`](https://developer.apple.com/documentation/uikit/uipickerview)
+* [`UIProgressView`](https://developer.apple.com/documentation/uikit/uiprogressview)
+* [`UISearchBar`](https://developer.apple.com/documentation/uikit/uisearchbar)
+* [`UISegmentedControl`](https://developer.apple.com/documentation/uikit/uisegmentedcontrol)
+* [`UISlider`](https://developer.apple.com/documentation/uikit/uislider)
+* [`UIStackView`](https://developer.apple.com/documentation/uikit/uistackview)
+* [`UIStepper`](https://developer.apple.com/documentation/uikit/uistepper)
+* [`UISwitch`](https://developer.apple.com/documentation/uikit/uiswitch)
+* [`UITextField`](https://developer.apple.com/documentation/uikit/uitextfield)
+* [`UITextView`](https://developer.apple.com/documentation/uikit/uitextview)
+* [`UIToolbar`](https://developer.apple.com/documentation/uikit/uitoolbar)
+* [`WKWebView`](https://developer.apple.com/documentation/webkit/wkwebview)
+
+## Add Accessibility Support to Your Views
+
+VoiceOver and other system accessibility technologies use the information provided by your views and controls to help all users navigate your content. UIKit views include default accessibility support, but you can improve the user experience by providing custom accessibility information.
+
+In this UIKitCatalog sample, several view controllers configure the `accessibilityType` and `accessibilityLabel` properties of their associated view. Picker view columns don't have labels, so the picker view asks its delegate for the corresponding accessibility information:
+
+``` swift
+func pickerView(_ pickerView: UIPickerView, accessibilityLabelForComponent component: Int) -> String? {
+
+ switch ColorComponent(rawValue: component)! {
+ case .red:
+ return NSLocalizedString("Red color component value", comment: "")
+
+ case .green:
+ return NSLocalizedString("Green color component value", comment: "")
+
+ case .blue:
+ return NSLocalizedString("Blue color component value", comment: "")
+ }
+}
+```
+
+## Display a Custom Alert
+
+`AlertControllerViewController` demonstrates several techniques for displaying modal alerts and action sheets from your interface. The configuration process is similar for all alerts:
+
+1. Determine the message you want to display in the alert.
+2. Create and configure a `UIAlertController` object.
+3. Add handlers for actions that the user may take.
+4. Present the alert controller.
+
+The `showSimpleAlert` function uses the `NSLocalizedString` function to retrieve the alert messages in the user’s preferred language. This function uses those strings to create and configure the `UIAlertController` object. Although the button in the alert has the title OK, the sample uses a cancel action to ensure that the alert controller applies the proper styling to the button:
+
+``` swift
+func showSimpleAlert() {
+ let title = NSLocalizedString("A Short Title is Best", comment: "")
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("OK", comment: "")
+
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ // Create the action.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The simple alert's cancel action occurred.")
+ }
+
+ // Add the action.
+ alertController.addAction(cancelAction)
+
+ present(alertController, animated: true, completion: nil)
+}
+```
+
+## Customize the Appearance of Sliders
+
+This sample demonstrates different ways to display a `UISlider`, a control used to select a single value from a continuous range of values. You customize the appearance of a slider by assigning stretchable images for left-side tracking, right-side tracking, and the thumb. In this example, the track image is stretchable and is one pixel wide. Make the track images wider to provide rounded corners, but be sure to set these images' `capInsets` property to allow for them.
+
+The `configureCustomSlider` function sets up a custom slider:
+
+``` swift
+func configureCustomSlider() {
+ let leftTrackImage = UIImage(named: "slider_blue_track")
+ customSlider.setMinimumTrackImage(leftTrackImage, for: .normal)
+
+ let rightTrackImage = UIImage(named: "slider_green_track")
+ customSlider.setMaximumTrackImage(rightTrackImage, for: .normal)
+
+ let thumbImage = UIImage(named: "slider_thumb")
+ customSlider.setThumbImage(thumbImage, for: .normal)
+
+ customSlider.minimumValue = 0
+ customSlider.maximumValue = 100
+ customSlider.isContinuous = false
+ customSlider.value = 84
+
+ customSlider.addTarget(self, action: #selector(SliderViewController.sliderValueDidChange(_:)), for: .valueChanged)
+}
+```
+
+## Add a Search Bar to Your Interface
+
+Use a `UISearchBar` for receiving search-related information from the user. There are various ways to customize the look of the search bar:
+
+* Add a cancel button.
+* Add a bookmark button.
+* Set the bookmark image, both normal and highlighted states.
+* Change the tint color that applies to key elements in the search bar.
+* Set the search bar's background image.
+
+The `configureSearchBar` function sets up a custom search bar:
+
+``` swift
+func configureSearchBar() {
+ searchBar.showsCancelButton = true
+ searchBar.showsBookmarkButton = true
+
+ searchBar.tintColor = UIColor(named: "Tint_Purple_Color")
+
+ searchBar.backgroundImage = UIImage(named: "search_bar_background")
+
+ // Set the bookmark image for both normal and highlighted states.
+ let bookmarkImage = #imageLiteral(resourceName: "bookmark_icon")
+ searchBar.setImage(bookmarkImage, for: .bookmark, state: .normal)
+
+ let bookmarkHighlightedImage = #imageLiteral(resourceName: "bookmark_icon_highlighted")
+ searchBar.setImage(bookmarkHighlightedImage, for: .bookmark, state: .highlighted)
+}
+```
+
+## Customize the Appearance of Toolbars
+
+This sample shows how to customize a `UIToolbar`, a specialized view that displays one or more buttons along the bottom edge of your interface. Customize a toolbar by determining its bar style (black or default), translucency, tint color, and background color.
+
+The following `viewDidLoad` function in `CustomToolbarViewController` sets up a tinted tool bar:
+
+``` swift
+override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // See the `UIBarStyle` enum for more styles, including `.Default`.
+ toolbar.barStyle = .black
+ toolbar.isTranslucent = true
+
+ toolbar.tintColor = UIColor(named: "Tint_Green_Color")
+ toolbar.backgroundColor = UIColor(named: "Tint_Blue_Color")
+
+ let toolbarButtonItems = [
+ refreshBarButtonItem,
+ flexibleSpaceBarButtonItem,
+ actionBarButtonItem
+ ]
+ toolbar.setItems(toolbarButtonItems, animated: true)
+}
+```
+
+`CustomToolbarViewController` demonstrates further customization by changing the toolbar's background image:
+
+``` swift
+override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let toolbarBackgroundImage = UIImage(named: "toolbar_background")
+ toolbar.setBackgroundImage(toolbarBackgroundImage, forToolbarPosition: .bottom, barMetrics: .default)
+
+ let toolbarButtonItems = [
+ customImageBarButtonItem,
+ flexibleSpaceBarButtonItem,
+ customBarButtonItem
+ ]
+ toolbar.setItems(toolbarButtonItems, animated: true)
+}
+```
+
+## Add a Page Control Interface
+
+Use a `UIPageControl` to structure your app's user interface. A page control is a specialized control that displays a horizontal series of dots, each of which corresponds to a page in the app’s document or other data-model entity. You customize a page control by setting its tint color for all the page indicator dots, and for the current page indicator dot.
+
+The `configurePageControl` function sets up a customized page control:
+
+``` swift
+func configurePageControl() {
+ // The total number of available pages is based on the number of available colors.
+ pageControl.numberOfPages = colors.count
+ pageControl.currentPage = 2
+
+ pageControl.pageIndicatorTintColor = UIColor(named: "Tint_Green_Color")
+ pageControl.currentPageIndicatorTintColor = UIColor(named: "Tint_Purple_Color")
+
+ pageControl.addTarget(self, action: #selector(PageControlViewController.pageControlValueDidChange), for: .valueChanged)
+}
+```
diff --git a/UIKitCatalog.xcodeproj/.xcodesamplecode.plist b/UIKitCatalog.xcodeproj/.xcodesamplecode.plist
new file mode 100644
index 0000000..5dd5da8
--- /dev/null
+++ b/UIKitCatalog.xcodeproj/.xcodesamplecode.plist
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/UIKitCatalog.xcodeproj/project.pbxproj b/UIKitCatalog.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..0794631
--- /dev/null
+++ b/UIKitCatalog.xcodeproj/project.pbxproj
@@ -0,0 +1,756 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 2200541E18BC54E8002A6E8B /* ActivityIndicatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200541A18BC54E8002A6E8B /* ActivityIndicatorViewController.swift */; };
+ 2200541F18BC54E8002A6E8B /* AlertControllerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200541B18BC54E8002A6E8B /* AlertControllerViewController.swift */; };
+ 2200542018BC54E8002A6E8B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200541C18BC54E8002A6E8B /* AppDelegate.swift */; };
+ 2200542718BC54EC002A6E8B /* ButtonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542118BC54EC002A6E8B /* ButtonViewController.swift */; };
+ 2200542818BC54EC002A6E8B /* CustomSearchBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542218BC54EC002A6E8B /* CustomSearchBarViewController.swift */; };
+ 2200542918BC54EC002A6E8B /* CustomToolbarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542318BC54EC002A6E8B /* CustomToolbarViewController.swift */; };
+ 2200542A18BC54EC002A6E8B /* DatePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542418BC54EC002A6E8B /* DatePickerController.swift */; };
+ 2200542B18BC54EC002A6E8B /* DefaultSearchBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542518BC54EC002A6E8B /* DefaultSearchBarViewController.swift */; };
+ 2200542C18BC54EC002A6E8B /* DefaultToolbarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542618BC54EC002A6E8B /* DefaultToolbarViewController.swift */; };
+ 2200543C18BC54F5002A6E8B /* ImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200542D18BC54F5002A6E8B /* ImageViewController.swift */; };
+ 2200543F18BC54F5002A6E8B /* PageControlViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543018BC54F5002A6E8B /* PageControlViewController.swift */; };
+ 2200544018BC54F5002A6E8B /* PickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543118BC54F5002A6E8B /* PickerViewController.swift */; };
+ 2200544118BC54F5002A6E8B /* ProgressViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543218BC54F5002A6E8B /* ProgressViewController.swift */; };
+ 2200544218BC54F5002A6E8B /* SegmentedControlViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543318BC54F5002A6E8B /* SegmentedControlViewController.swift */; };
+ 2200544318BC54F5002A6E8B /* SliderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543418BC54F5002A6E8B /* SliderViewController.swift */; };
+ 2200544518BC54F5002A6E8B /* StepperViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543618BC54F5002A6E8B /* StepperViewController.swift */; };
+ 2200544618BC54F5002A6E8B /* SwitchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543718BC54F5002A6E8B /* SwitchViewController.swift */; };
+ 2200544718BC54F5002A6E8B /* TextFieldViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543818BC54F5002A6E8B /* TextFieldViewController.swift */; };
+ 2200544818BC54F5002A6E8B /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543918BC54F5002A6E8B /* TextViewController.swift */; };
+ 2200544918BC54F5002A6E8B /* TintedToolbarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543A18BC54F5002A6E8B /* TintedToolbarViewController.swift */; };
+ 2200544A18BC54F5002A6E8B /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2200543B18BC54F5002A6E8B /* WebViewController.swift */; };
+ 228DBA0818BC53F1002BA12A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 228DBA0718BC53F1002BA12A /* Assets.xcassets */; };
+ 3E5C084E1974991E00969DD7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3E5C08501974991E00969DD7 /* Main.storyboard */; };
+ 533BD78D1F8BE1A6007D5C3B /* DetailViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 533BD78C1F8BE1A6007D5C3B /* DetailViewManager.swift */; };
+ 533BD7951F8BF6A4007D5C3B /* UIViewController+SizeChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 533BD7941F8BF6A4007D5C3B /* UIViewController+SizeChange.swift */; };
+ 533BD7971F8BF8B0007D5C3B /* BaseTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 533BD7961F8BF8B0007D5C3B /* BaseTableViewController.swift */; };
+ 533BD7BC1F8D2B08007D5C3B /* SearchBarsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 533BD7BA1F8D2B07007D5C3B /* SearchBarsTableViewController.swift */; };
+ 533BD7BD1F8D2B08007D5C3B /* ToolbarsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 533BD7BB1F8D2B07007D5C3B /* ToolbarsTableViewController.swift */; };
+ 5341627C1F291F310007BCCA /* ToolbarViewControllers.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5341627A1F291F310007BCCA /* ToolbarViewControllers.storyboard */; };
+ 537357141F291E6700FAB742 /* SearchViewControllers.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 537357121F291E6700FAB742 /* SearchViewControllers.storyboard */; };
+ 538B36F41F2A8E06002AE100 /* DatePickerController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 538B36F21F2A8D97002AE100 /* DatePickerController.storyboard */; };
+ 538B36F71F2A8E8A002AE100 /* TextViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 538B36F51F2A8E66002AE100 /* TextViewController.storyboard */; };
+ 539029FF1F2A53AD009775E3 /* AlertControllerViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539029FD1F2A53AD009775E3 /* AlertControllerViewController.storyboard */; };
+ 539C6BAE1F27F4980006C5A9 /* ActivityIndicatorViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539C6BA81F27F4980006C5A9 /* ActivityIndicatorViewController.storyboard */; };
+ 539C6BAF1F27F4980006C5A9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539C6BAA1F27F4980006C5A9 /* LaunchScreen.storyboard */; };
+ 539C6BB01F27F4980006C5A9 /* WebViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 539C6BAC1F27F4980006C5A9 /* WebViewController.storyboard */; };
+ 539C6BB21F27F4A70006C5A9 /* MasterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539C6BB11F27F4A70006C5A9 /* MasterViewController.swift */; };
+ 53B791DA1F85505400AB2FA6 /* content.html in Resources */ = {isa = PBXBuildFile; fileRef = 53B791D41F854B4700AB2FA6 /* content.html */; };
+ 53B791DB1F85505700AB2FA6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53B791D61F854B4700AB2FA6 /* InfoPlist.strings */; };
+ 53B791DC1F85505A00AB2FA6 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53B791D81F854B4800AB2FA6 /* Localizable.strings */; };
+ 53CE5AD81F2A89E500D8A656 /* ButtonViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AD61F2A89E500D8A656 /* ButtonViewController.storyboard */; };
+ 53CE5ADE1F2A8A3D00D8A656 /* ImageViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5ADC1F2A8A3D00D8A656 /* ImageViewController.storyboard */; };
+ 53CE5AE31F2A8AD200D8A656 /* PageControlViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AE11F2A8AD200D8A656 /* PageControlViewController.storyboard */; };
+ 53CE5AE61F2A8AEF00D8A656 /* PickerViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AE41F2A8AEF00D8A656 /* PickerViewController.storyboard */; };
+ 53CE5AE91F2A8B1000D8A656 /* ProgressViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AE71F2A8B1000D8A656 /* ProgressViewController.storyboard */; };
+ 53CE5AEC1F2A8B2F00D8A656 /* SegmentedControlViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AEA1F2A8B2F00D8A656 /* SegmentedControlViewController.storyboard */; };
+ 53CE5AEF1F2A8B4F00D8A656 /* SliderViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AED1F2A8B4F00D8A656 /* SliderViewController.storyboard */; };
+ 53CE5AF21F2A8B8300D8A656 /* StackViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AF01F2A8B8300D8A656 /* StackViewController.storyboard */; };
+ 53CE5AF51F2A8BB000D8A656 /* StepperViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AF31F2A8BB000D8A656 /* StepperViewController.storyboard */; };
+ 53CE5AF81F2A8BD000D8A656 /* SwitchViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AF61F2A8BD000D8A656 /* SwitchViewController.storyboard */; };
+ 53CE5AFB1F2A8BEB00D8A656 /* TextFieldViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 53CE5AF91F2A8BEB00D8A656 /* TextFieldViewController.storyboard */; };
+ B50F41081B1D284700E5147D /* StackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50F41071B1D284700E5147D /* StackViewController.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 2200541A18BC54E8002A6E8B /* ActivityIndicatorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorViewController.swift; sourceTree = ""; };
+ 2200541B18BC54E8002A6E8B /* AlertControllerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AlertControllerViewController.swift; sourceTree = ""; };
+ 2200541C18BC54E8002A6E8B /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 2200542118BC54EC002A6E8B /* ButtonViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ButtonViewController.swift; sourceTree = ""; };
+ 2200542218BC54EC002A6E8B /* CustomSearchBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CustomSearchBarViewController.swift; sourceTree = ""; };
+ 2200542318BC54EC002A6E8B /* CustomToolbarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CustomToolbarViewController.swift; sourceTree = ""; };
+ 2200542418BC54EC002A6E8B /* DatePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DatePickerController.swift; sourceTree = ""; };
+ 2200542518BC54EC002A6E8B /* DefaultSearchBarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultSearchBarViewController.swift; sourceTree = ""; };
+ 2200542618BC54EC002A6E8B /* DefaultToolbarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DefaultToolbarViewController.swift; sourceTree = ""; };
+ 2200542D18BC54F5002A6E8B /* ImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ImageViewController.swift; sourceTree = ""; };
+ 2200543018BC54F5002A6E8B /* PageControlViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PageControlViewController.swift; sourceTree = ""; };
+ 2200543118BC54F5002A6E8B /* PickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = PickerViewController.swift; sourceTree = ""; };
+ 2200543218BC54F5002A6E8B /* ProgressViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ProgressViewController.swift; sourceTree = ""; };
+ 2200543318BC54F5002A6E8B /* SegmentedControlViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = SegmentedControlViewController.swift; sourceTree = ""; };
+ 2200543418BC54F5002A6E8B /* SliderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = SliderViewController.swift; sourceTree = ""; };
+ 2200543618BC54F5002A6E8B /* StepperViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = StepperViewController.swift; sourceTree = ""; };
+ 2200543718BC54F5002A6E8B /* SwitchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = SwitchViewController.swift; sourceTree = ""; };
+ 2200543818BC54F5002A6E8B /* TextFieldViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldViewController.swift; sourceTree = ""; };
+ 2200543918BC54F5002A6E8B /* TextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = TextViewController.swift; sourceTree = ""; };
+ 2200543A18BC54F5002A6E8B /* TintedToolbarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TintedToolbarViewController.swift; sourceTree = ""; };
+ 2200543B18BC54F5002A6E8B /* WebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebViewController.swift; sourceTree = ""; };
+ 228DB9F318BC53F1002BA12A /* UIKitCatalog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UIKitCatalog.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 228DB9F718BC53F1002BA12A /* UIKitCatalog-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UIKitCatalog-Info.plist"; sourceTree = ""; };
+ 228DBA0718BC53F1002BA12A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 3E5C084F1974991E00969DD7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 533BD78C1F8BE1A6007D5C3B /* DetailViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewManager.swift; sourceTree = ""; };
+ 533BD7941F8BF6A4007D5C3B /* UIViewController+SizeChange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+SizeChange.swift"; sourceTree = ""; };
+ 533BD7961F8BF8B0007D5C3B /* BaseTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTableViewController.swift; sourceTree = ""; };
+ 533BD7BA1F8D2B07007D5C3B /* SearchBarsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchBarsTableViewController.swift; sourceTree = ""; };
+ 533BD7BB1F8D2B07007D5C3B /* ToolbarsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarsTableViewController.swift; sourceTree = ""; };
+ 5341627B1F291F310007BCCA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/ToolbarViewControllers.storyboard; sourceTree = ""; };
+ 5359C3081F194CF0007F0EC7 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
+ 537357131F291E6700FAB742 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/SearchViewControllers.storyboard; sourceTree = ""; };
+ 538B36F31F2A8D97002AE100 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/DatePickerController.storyboard; sourceTree = ""; };
+ 538B36F61F2A8E66002AE100 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/TextViewController.storyboard; sourceTree = ""; };
+ 539029FE1F2A53AD009775E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/AlertControllerViewController.storyboard; sourceTree = ""; };
+ 539C6BA91F27F4980006C5A9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/ActivityIndicatorViewController.storyboard; sourceTree = ""; };
+ 539C6BAB1F27F4980006C5A9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 539C6BAD1F27F4980006C5A9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/WebViewController.storyboard; sourceTree = ""; };
+ 539C6BB11F27F4A70006C5A9 /* MasterViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MasterViewController.swift; sourceTree = ""; };
+ 53B791D51F854B4700AB2FA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = Base; path = Base.lproj/content.html; sourceTree = ""; };
+ 53B791D71F854B4700AB2FA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = ""; };
+ 53B791D91F854B4800AB2FA6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; };
+ 53CE5AD71F2A89E500D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/ButtonViewController.storyboard; sourceTree = ""; };
+ 53CE5ADD1F2A8A3D00D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/ImageViewController.storyboard; sourceTree = ""; };
+ 53CE5AE21F2A8AD200D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/PageControlViewController.storyboard; sourceTree = ""; };
+ 53CE5AE51F2A8AEF00D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/PickerViewController.storyboard; sourceTree = ""; };
+ 53CE5AE81F2A8B1000D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/ProgressViewController.storyboard; sourceTree = ""; };
+ 53CE5AEB1F2A8B2F00D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/SegmentedControlViewController.storyboard; sourceTree = ""; };
+ 53CE5AEE1F2A8B4F00D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/SliderViewController.storyboard; sourceTree = ""; };
+ 53CE5AF11F2A8B8300D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/StackViewController.storyboard; sourceTree = ""; };
+ 53CE5AF41F2A8BB000D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/StepperViewController.storyboard; sourceTree = ""; };
+ 53CE5AF71F2A8BD000D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/SwitchViewController.storyboard; sourceTree = ""; };
+ 53CE5AFA1F2A8BEB00D8A656 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/TextFieldViewController.storyboard; sourceTree = ""; };
+ B50F41071B1D284700E5147D /* StackViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackViewController.swift; sourceTree = ""; };
+ E05970B0E05971D000000001 /* SampleCode.xcconfig */ = {isa = PBXFileReference; name = SampleCode.xcconfig; path = Configuration/SampleCode.xcconfig; sourceTree = ""; };
+ E2DECA10E2DE8B8000000001 /* LICENSE.txt */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE.txt; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 228DB9F018BC53F1002BA12A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 228DB9EA18BC53F1002BA12A = {
+ isa = PBXGroup;
+ children = (
+ 5359C3081F194CF0007F0EC7 /* README.md */,
+ 228DB9F518BC53F1002BA12A /* UIKitCatalog */,
+ 228DB9F418BC53F1002BA12A /* Products */,
+ E05975F0E0597BF000000001 /* Configuration */,
+ E2DE9120E2DEC9A000000001 /* LICENSE */,
+ );
+ sourceTree = "";
+ };
+ 228DB9F418BC53F1002BA12A /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 228DB9F318BC53F1002BA12A /* UIKitCatalog.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 228DB9F518BC53F1002BA12A /* UIKitCatalog */ = {
+ isa = PBXGroup;
+ children = (
+ 3E2459D41931CCB5002D3369 /* Application */,
+ 3E1DA7601931CC99000114A9 /* View Controllers */,
+ 228DBA0718BC53F1002BA12A /* Assets.xcassets */,
+ 228DB9F618BC53F1002BA12A /* Supporting Files */,
+ );
+ path = UIKitCatalog;
+ sourceTree = "";
+ };
+ 228DB9F618BC53F1002BA12A /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 228DB9F718BC53F1002BA12A /* UIKitCatalog-Info.plist */,
+ 3E5C08501974991E00969DD7 /* Main.storyboard */,
+ 539C6BAA1F27F4980006C5A9 /* LaunchScreen.storyboard */,
+ 53B791D41F854B4700AB2FA6 /* content.html */,
+ 53B791D61F854B4700AB2FA6 /* InfoPlist.strings */,
+ 53B791D81F854B4800AB2FA6 /* Localizable.strings */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+ 22B7BB9718BC601D006C4AD5 /* Search */ = {
+ isa = PBXGroup;
+ children = (
+ 533BD7BA1F8D2B07007D5C3B /* SearchBarsTableViewController.swift */,
+ 3E6AE84D196B1FC10062A3E1 /* Search Bar */,
+ 537357121F291E6700FAB742 /* SearchViewControllers.storyboard */,
+ );
+ name = Search;
+ sourceTree = "";
+ };
+ 22B7BB9818BC6024006C4AD5 /* Toolbar */ = {
+ isa = PBXGroup;
+ children = (
+ 533BD7BB1F8D2B07007D5C3B /* ToolbarsTableViewController.swift */,
+ 2200542618BC54EC002A6E8B /* DefaultToolbarViewController.swift */,
+ 2200543A18BC54F5002A6E8B /* TintedToolbarViewController.swift */,
+ 2200542318BC54EC002A6E8B /* CustomToolbarViewController.swift */,
+ 5341627A1F291F310007BCCA /* ToolbarViewControllers.storyboard */,
+ );
+ name = Toolbar;
+ sourceTree = "";
+ };
+ 3E1DA7601931CC99000114A9 /* View Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ 2200541A18BC54E8002A6E8B /* ActivityIndicatorViewController.swift */,
+ 539C6BA81F27F4980006C5A9 /* ActivityIndicatorViewController.storyboard */,
+ 2200541B18BC54E8002A6E8B /* AlertControllerViewController.swift */,
+ 539029FD1F2A53AD009775E3 /* AlertControllerViewController.storyboard */,
+ 2200542118BC54EC002A6E8B /* ButtonViewController.swift */,
+ 53CE5AD61F2A89E500D8A656 /* ButtonViewController.storyboard */,
+ 2200542418BC54EC002A6E8B /* DatePickerController.swift */,
+ 538B36F21F2A8D97002AE100 /* DatePickerController.storyboard */,
+ 2200542D18BC54F5002A6E8B /* ImageViewController.swift */,
+ 53CE5ADC1F2A8A3D00D8A656 /* ImageViewController.storyboard */,
+ 2200543018BC54F5002A6E8B /* PageControlViewController.swift */,
+ 53CE5AE11F2A8AD200D8A656 /* PageControlViewController.storyboard */,
+ 2200543118BC54F5002A6E8B /* PickerViewController.swift */,
+ 53CE5AE41F2A8AEF00D8A656 /* PickerViewController.storyboard */,
+ 2200543218BC54F5002A6E8B /* ProgressViewController.swift */,
+ 53CE5AE71F2A8B1000D8A656 /* ProgressViewController.storyboard */,
+ 2200543318BC54F5002A6E8B /* SegmentedControlViewController.swift */,
+ 53CE5AEA1F2A8B2F00D8A656 /* SegmentedControlViewController.storyboard */,
+ 2200543418BC54F5002A6E8B /* SliderViewController.swift */,
+ 53CE5AED1F2A8B4F00D8A656 /* SliderViewController.storyboard */,
+ B50F41071B1D284700E5147D /* StackViewController.swift */,
+ 53CE5AF01F2A8B8300D8A656 /* StackViewController.storyboard */,
+ 2200543618BC54F5002A6E8B /* StepperViewController.swift */,
+ 53CE5AF31F2A8BB000D8A656 /* StepperViewController.storyboard */,
+ 2200543718BC54F5002A6E8B /* SwitchViewController.swift */,
+ 53CE5AF61F2A8BD000D8A656 /* SwitchViewController.storyboard */,
+ 2200543818BC54F5002A6E8B /* TextFieldViewController.swift */,
+ 53CE5AF91F2A8BEB00D8A656 /* TextFieldViewController.storyboard */,
+ 2200543918BC54F5002A6E8B /* TextViewController.swift */,
+ 538B36F51F2A8E66002AE100 /* TextViewController.storyboard */,
+ 2200543B18BC54F5002A6E8B /* WebViewController.swift */,
+ 539C6BAC1F27F4980006C5A9 /* WebViewController.storyboard */,
+ 22B7BB9718BC601D006C4AD5 /* Search */,
+ 22B7BB9818BC6024006C4AD5 /* Toolbar */,
+ );
+ name = "View Controllers";
+ sourceTree = "";
+ };
+ 3E2459D41931CCB5002D3369 /* Application */ = {
+ isa = PBXGroup;
+ children = (
+ 2200541C18BC54E8002A6E8B /* AppDelegate.swift */,
+ 533BD78C1F8BE1A6007D5C3B /* DetailViewManager.swift */,
+ 539C6BB11F27F4A70006C5A9 /* MasterViewController.swift */,
+ 533BD7941F8BF6A4007D5C3B /* UIViewController+SizeChange.swift */,
+ 533BD7961F8BF8B0007D5C3B /* BaseTableViewController.swift */,
+ );
+ name = Application;
+ sourceTree = "";
+ };
+ 3E6AE84D196B1FC10062A3E1 /* Search Bar */ = {
+ isa = PBXGroup;
+ children = (
+ 2200542518BC54EC002A6E8B /* DefaultSearchBarViewController.swift */,
+ 2200542218BC54EC002A6E8B /* CustomSearchBarViewController.swift */,
+ );
+ name = "Search Bar";
+ sourceTree = "";
+ };
+ E05975F0E0597BF000000001 /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ E05970B0E05971D000000001 /* SampleCode.xcconfig */,
+ );
+ name = Configuration;
+ sourceTree = "";
+ };
+ E2DE9120E2DEC9A000000001 /* LICENSE */ = {
+ isa = PBXGroup;
+ children = (
+ E2DECA10E2DE8B8000000001 /* LICENSE.txt */,
+ );
+ name = LICENSE;
+ path = LICENSE;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 228DB9F218BC53F1002BA12A /* UIKitCatalog */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 228DBA0B18BC53F1002BA12A /* Build configuration list for PBXNativeTarget "UIKitCatalog" */;
+ buildPhases = (
+ 228DB9EF18BC53F1002BA12A /* Sources */,
+ 228DB9F018BC53F1002BA12A /* Frameworks */,
+ 228DB9F118BC53F1002BA12A /* Resources */,
+ 5399BE86211B482A005809B6,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = UIKitCatalog;
+ productName = UIKitCatalog;
+ productReference = 228DB9F318BC53F1002BA12A /* UIKitCatalog.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 228DB9EB18BC53F1002BA12A /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0700;
+ LastUpgradeCheck = 0940;
+ ORGANIZATIONNAME = Apple;
+ TargetAttributes = {
+ 228DB9F218BC53F1002BA12A = {
+ LastSwiftMigration = 0900;
+ };
+ };
+ };
+ buildConfigurationList = 228DB9EE18BC53F1002BA12A /* Build configuration list for PBXProject "UIKitCatalog" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 228DB9EA18BC53F1002BA12A;
+ productRefGroup = 228DB9F418BC53F1002BA12A /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 228DB9F218BC53F1002BA12A /* UIKitCatalog */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 228DB9F118BC53F1002BA12A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 539C6BB01F27F4980006C5A9 /* WebViewController.storyboard in Resources */,
+ 53CE5AD81F2A89E500D8A656 /* ButtonViewController.storyboard in Resources */,
+ 53CE5AEF1F2A8B4F00D8A656 /* SliderViewController.storyboard in Resources */,
+ 537357141F291E6700FAB742 /* SearchViewControllers.storyboard in Resources */,
+ 53CE5AE91F2A8B1000D8A656 /* ProgressViewController.storyboard in Resources */,
+ 53CE5AE61F2A8AEF00D8A656 /* PickerViewController.storyboard in Resources */,
+ 53B791DA1F85505400AB2FA6 /* content.html in Resources */,
+ 3E5C084E1974991E00969DD7 /* Main.storyboard in Resources */,
+ 53CE5AEC1F2A8B2F00D8A656 /* SegmentedControlViewController.storyboard in Resources */,
+ 53B791DB1F85505700AB2FA6 /* InfoPlist.strings in Resources */,
+ 539C6BAE1F27F4980006C5A9 /* ActivityIndicatorViewController.storyboard in Resources */,
+ 53CE5AFB1F2A8BEB00D8A656 /* TextFieldViewController.storyboard in Resources */,
+ 5341627C1F291F310007BCCA /* ToolbarViewControllers.storyboard in Resources */,
+ 53B791DC1F85505A00AB2FA6 /* Localizable.strings in Resources */,
+ 228DBA0818BC53F1002BA12A /* Assets.xcassets in Resources */,
+ 538B36F41F2A8E06002AE100 /* DatePickerController.storyboard in Resources */,
+ 53CE5AE31F2A8AD200D8A656 /* PageControlViewController.storyboard in Resources */,
+ 53CE5AF21F2A8B8300D8A656 /* StackViewController.storyboard in Resources */,
+ 538B36F71F2A8E8A002AE100 /* TextViewController.storyboard in Resources */,
+ 539C6BAF1F27F4980006C5A9 /* LaunchScreen.storyboard in Resources */,
+ 539029FF1F2A53AD009775E3 /* AlertControllerViewController.storyboard in Resources */,
+ 53CE5AF51F2A8BB000D8A656 /* StepperViewController.storyboard in Resources */,
+ 53CE5AF81F2A8BD000D8A656 /* SwitchViewController.storyboard in Resources */,
+ 53CE5ADE1F2A8A3D00D8A656 /* ImageViewController.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 228DB9EF18BC53F1002BA12A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2200544018BC54F5002A6E8B /* PickerViewController.swift in Sources */,
+ 2200543F18BC54F5002A6E8B /* PageControlViewController.swift in Sources */,
+ 533BD7951F8BF6A4007D5C3B /* UIViewController+SizeChange.swift in Sources */,
+ 2200544918BC54F5002A6E8B /* TintedToolbarViewController.swift in Sources */,
+ 2200544318BC54F5002A6E8B /* SliderViewController.swift in Sources */,
+ 2200544218BC54F5002A6E8B /* SegmentedControlViewController.swift in Sources */,
+ 2200544A18BC54F5002A6E8B /* WebViewController.swift in Sources */,
+ 2200542018BC54E8002A6E8B /* AppDelegate.swift in Sources */,
+ 539C6BB21F27F4A70006C5A9 /* MasterViewController.swift in Sources */,
+ 2200541F18BC54E8002A6E8B /* AlertControllerViewController.swift in Sources */,
+ 2200542C18BC54EC002A6E8B /* DefaultToolbarViewController.swift in Sources */,
+ 2200543C18BC54F5002A6E8B /* ImageViewController.swift in Sources */,
+ 2200541E18BC54E8002A6E8B /* ActivityIndicatorViewController.swift in Sources */,
+ 533BD7BD1F8D2B08007D5C3B /* ToolbarsTableViewController.swift in Sources */,
+ 2200544618BC54F5002A6E8B /* SwitchViewController.swift in Sources */,
+ 533BD7971F8BF8B0007D5C3B /* BaseTableViewController.swift in Sources */,
+ B50F41081B1D284700E5147D /* StackViewController.swift in Sources */,
+ 2200544118BC54F5002A6E8B /* ProgressViewController.swift in Sources */,
+ 2200544718BC54F5002A6E8B /* TextFieldViewController.swift in Sources */,
+ 2200544818BC54F5002A6E8B /* TextViewController.swift in Sources */,
+ 2200542B18BC54EC002A6E8B /* DefaultSearchBarViewController.swift in Sources */,
+ 2200544518BC54F5002A6E8B /* StepperViewController.swift in Sources */,
+ 2200542818BC54EC002A6E8B /* CustomSearchBarViewController.swift in Sources */,
+ 533BD7BC1F8D2B08007D5C3B /* SearchBarsTableViewController.swift in Sources */,
+ 2200542918BC54EC002A6E8B /* CustomToolbarViewController.swift in Sources */,
+ 2200542A18BC54EC002A6E8B /* DatePickerController.swift in Sources */,
+ 2200542718BC54EC002A6E8B /* ButtonViewController.swift in Sources */,
+ 533BD78D1F8BE1A6007D5C3B /* DetailViewManager.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 3E5C08501974991E00969DD7 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 3E5C084F1974991E00969DD7 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 5341627A1F291F310007BCCA /* ToolbarViewControllers.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5341627B1F291F310007BCCA /* Base */,
+ );
+ name = ToolbarViewControllers.storyboard;
+ sourceTree = "";
+ };
+ 537357121F291E6700FAB742 /* SearchViewControllers.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 537357131F291E6700FAB742 /* Base */,
+ );
+ name = SearchViewControllers.storyboard;
+ sourceTree = "";
+ };
+ 538B36F21F2A8D97002AE100 /* DatePickerController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 538B36F31F2A8D97002AE100 /* Base */,
+ );
+ name = DatePickerController.storyboard;
+ sourceTree = "";
+ };
+ 538B36F51F2A8E66002AE100 /* TextViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 538B36F61F2A8E66002AE100 /* Base */,
+ );
+ name = TextViewController.storyboard;
+ sourceTree = "";
+ };
+ 539029FD1F2A53AD009775E3 /* AlertControllerViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 539029FE1F2A53AD009775E3 /* Base */,
+ );
+ name = AlertControllerViewController.storyboard;
+ sourceTree = "";
+ };
+ 539C6BA81F27F4980006C5A9 /* ActivityIndicatorViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 539C6BA91F27F4980006C5A9 /* Base */,
+ );
+ name = ActivityIndicatorViewController.storyboard;
+ sourceTree = "";
+ };
+ 539C6BAA1F27F4980006C5A9 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 539C6BAB1F27F4980006C5A9 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+ 539C6BAC1F27F4980006C5A9 /* WebViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 539C6BAD1F27F4980006C5A9 /* Base */,
+ );
+ name = WebViewController.storyboard;
+ sourceTree = "";
+ };
+ 53B791D41F854B4700AB2FA6 /* content.html */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53B791D51F854B4700AB2FA6 /* Base */,
+ );
+ name = content.html;
+ sourceTree = "";
+ };
+ 53B791D61F854B4700AB2FA6 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53B791D71F854B4700AB2FA6 /* Base */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "";
+ };
+ 53B791D81F854B4800AB2FA6 /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53B791D91F854B4800AB2FA6 /* Base */,
+ );
+ name = Localizable.strings;
+ sourceTree = "";
+ };
+ 53CE5AD61F2A89E500D8A656 /* ButtonViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AD71F2A89E500D8A656 /* Base */,
+ );
+ name = ButtonViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5ADC1F2A8A3D00D8A656 /* ImageViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5ADD1F2A8A3D00D8A656 /* Base */,
+ );
+ name = ImageViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AE11F2A8AD200D8A656 /* PageControlViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AE21F2A8AD200D8A656 /* Base */,
+ );
+ name = PageControlViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AE41F2A8AEF00D8A656 /* PickerViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AE51F2A8AEF00D8A656 /* Base */,
+ );
+ name = PickerViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AE71F2A8B1000D8A656 /* ProgressViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AE81F2A8B1000D8A656 /* Base */,
+ );
+ name = ProgressViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AEA1F2A8B2F00D8A656 /* SegmentedControlViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AEB1F2A8B2F00D8A656 /* Base */,
+ );
+ name = SegmentedControlViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AED1F2A8B4F00D8A656 /* SliderViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AEE1F2A8B4F00D8A656 /* Base */,
+ );
+ name = SliderViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AF01F2A8B8300D8A656 /* StackViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AF11F2A8B8300D8A656 /* Base */,
+ );
+ name = StackViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AF31F2A8BB000D8A656 /* StepperViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AF41F2A8BB000D8A656 /* Base */,
+ );
+ name = StepperViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AF61F2A8BD000D8A656 /* SwitchViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AF71F2A8BD000D8A656 /* Base */,
+ );
+ name = SwitchViewController.storyboard;
+ sourceTree = "";
+ };
+ 53CE5AF91F2A8BEB00D8A656 /* TextFieldViewController.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 53CE5AFA1F2A8BEB00D8A656 /* Base */,
+ );
+ name = TextFieldViewController.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 228DBA0918BC53F1002BA12A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E05970B0E05971D000000001 /* SampleCode.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ 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",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ 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.1;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_VERSION = "";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 228DBA0A18BC53F1002BA12A /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E05970B0E05971D000000001 /* SampleCode.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ 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 = 11.1;
+ SDKROOT = iphoneos;
+ SWIFT_VERSION = "";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 228DBA0C18BC53F1002BA12A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E05970B0E05971D000000001 /* SampleCode.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = "$(SRCROOT)/UIKitCatalog/UIKitCatalog-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 11.4;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.${PRODUCT_NAME:rfc1034identifier}${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_SWIFT3_OBJC_INFERENCE = Off;
+ SWIFT_VERSION = 4.0;
+ };
+ name = Debug;
+ };
+ 228DBA0D18BC53F1002BA12A /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E05970B0E05971D000000001 /* SampleCode.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ DEVELOPMENT_TEAM = "";
+ INFOPLIST_FILE = "$(SRCROOT)/UIKitCatalog/UIKitCatalog-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 11.4;
+ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = "com.example.apple-samplecode.${PRODUCT_NAME:rfc1034identifier}${SAMPLE_CODE_DISAMBIGUATOR}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SWIFT_SWIFT3_OBJC_INFERENCE = Off;
+ SWIFT_VERSION = 4.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 228DB9EE18BC53F1002BA12A /* Build configuration list for PBXProject "UIKitCatalog" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 228DBA0918BC53F1002BA12A /* Debug */,
+ 228DBA0A18BC53F1002BA12A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 228DBA0B18BC53F1002BA12A /* Build configuration list for PBXNativeTarget "UIKitCatalog" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 228DBA0C18BC53F1002BA12A /* Debug */,
+ 228DBA0D18BC53F1002BA12A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 228DB9EB18BC53F1002BA12A /* Project object */;
+}
diff --git a/UIKitCatalog/ActivityIndicatorViewController.swift b/UIKitCatalog/ActivityIndicatorViewController.swift
new file mode 100644
index 0000000..d681b63
--- /dev/null
+++ b/UIKitCatalog/ActivityIndicatorViewController.swift
@@ -0,0 +1,45 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIActivityIndicatorView`.
+*/
+
+import UIKit
+
+class ActivityIndicatorViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var grayStyleActivityIndicatorView: UIActivityIndicatorView!
+
+ @IBOutlet weak var tintedActivityIndicatorView: UIActivityIndicatorView!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureGrayActivityIndicatorView()
+ configureTintedActivityIndicatorView()
+
+ // When the activity is done, be sure to use UIActivityIndicatorView.stopAnimating().
+ }
+
+ // MARK: - Configuration
+
+ func configureGrayActivityIndicatorView() {
+ grayStyleActivityIndicatorView.activityIndicatorViewStyle = .gray
+
+ grayStyleActivityIndicatorView.startAnimating()
+
+ grayStyleActivityIndicatorView.hidesWhenStopped = true
+ }
+
+ func configureTintedActivityIndicatorView() {
+ tintedActivityIndicatorView.activityIndicatorViewStyle = .gray
+
+ tintedActivityIndicatorView.color = UIColor(named: "Tint_Purple_Color")
+
+ tintedActivityIndicatorView.startAnimating()
+ }
+}
diff --git a/UIKitCatalog/AlertControllerViewController.swift b/UIKitCatalog/AlertControllerViewController.swift
new file mode 100644
index 0000000..4b86c4d
--- /dev/null
+++ b/UIKitCatalog/AlertControllerViewController.swift
@@ -0,0 +1,310 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+The view controller that demonstrates how to use `UIAlertController`.
+*/
+
+import UIKit
+
+class AlertControllerViewController: UITableViewController {
+ // MARK: - Properties
+
+ weak var secureTextAlertAction: UIAlertAction?
+
+ private enum StyleSections: Int {
+ case alertStyleSection = 0
+ case actionStyleSection
+ }
+
+ private enum AlertStyleTest: Int {
+ // Alert style alerts.
+ case showSimpleAlert = 0
+ case showOkayCancelAlert
+ case showOtherAlert
+ case showTextEntryAlert
+ case showSecureTextEntryAlert
+ }
+
+ private enum ActionSheetStyleTest: Int {
+ // Action sheet style alerts.
+ case showOkayCancelActionSheet = 0
+ case howOtherActionSheet
+ }
+
+ private var textDidChangeObserver: NSObjectProtocol!
+
+ // MARK: - UIAlertControllerStyleAlert Style Alerts
+
+ /// Show an alert with an "OK" button.
+ func showSimpleAlert() {
+ let title = NSLocalizedString("A Short Title is Best", comment: "")
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("OK", comment: "")
+
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ // Create the action.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The simple alert's cancel action occurred.")
+ }
+
+ // Add the action.
+ alertController.addAction(cancelAction)
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ /// Show an alert with an "OK" and "Cancel" button.
+ func showOkayCancelAlert() {
+ let title = NSLocalizedString("A Short Title is Best", comment: "")
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
+ let otherButtonTitle = NSLocalizedString("OK", comment: "")
+
+ let alertCotroller = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ // Create the actions.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The \"OK/Cancel\" alert's cancel action occurred.")
+ }
+
+ let otherAction = UIAlertAction(title: otherButtonTitle, style: .default) { _ in
+ print("The \"OK/Cancel\" alert's other action occurred.")
+ }
+
+ // Add the actions.
+ alertCotroller.addAction(cancelAction)
+ alertCotroller.addAction(otherAction)
+
+ present(alertCotroller, animated: true, completion: nil)
+ }
+
+ /// Show an alert with two custom buttons.
+ func showOtherAlert() {
+ let title = NSLocalizedString("A Short Title is Best", comment: "")
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
+ let otherButtonTitleOne = NSLocalizedString("Choice One", comment: "")
+ let otherButtonTitleTwo = NSLocalizedString("Choice Two", comment: "")
+
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ // Create the actions.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The \"Other\" alert's cancel action occurred.")
+ }
+
+ let otherButtonOneAction = UIAlertAction(title: otherButtonTitleOne, style: .default) { _ in
+ print("The \"Other\" alert's other button one action occurred.")
+ }
+
+ let otherButtonTwoAction = UIAlertAction(title: otherButtonTitleTwo, style: .default) { _ in
+ print("The \"Other\" alert's other button two action occurred.")
+ }
+
+ // Add the actions.
+ alertController.addAction(cancelAction)
+ alertController.addAction(otherButtonOneAction)
+ alertController.addAction(otherButtonTwoAction)
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ /// Show a text entry alert with two custom buttons.
+ func showTextEntryAlert() {
+ let title = NSLocalizedString("A Short Title is Best", comment: "")
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
+ let otherButtonTitle = NSLocalizedString("OK", comment: "")
+
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ // Add the text field for text entry.
+ alertController.addTextField { _ in
+ // If you need to customize the text field, you can do so here.
+ }
+
+ // Create the actions.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The \"Text Entry\" alert's cancel action occurred.")
+ }
+
+ let otherAction = UIAlertAction(title: otherButtonTitle, style: .default) { _ in
+ print("The \"Text Entry\" alert's other action occurred.")
+ }
+
+ // Add the actions.
+ alertController.addAction(cancelAction)
+ alertController.addAction(otherAction)
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ /// Show a secure text entry alert with two custom buttons.
+ func showSecureTextEntryAlert() {
+ let title = NSLocalizedString("A Short Title is Best", comment: "")
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
+ let otherButtonTitle = NSLocalizedString("OK", comment: "")
+
+ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+
+ // Add the text field for the secure text entry.
+ alertController.addTextField { textField in
+ /** Listen for changes to the text field's text so that we can toggle the current
+ action's enabled property based on whether the user has entered a sufficiently
+ secure entry.
+ */
+ self.textDidChangeObserver = NotificationCenter.default.addObserver(
+ forName: NSNotification.Name.UITextFieldTextDidChange,
+ object: textField,
+ queue: OperationQueue.main) { (notification) in
+ if let textField = notification.object as? UITextField {
+ // Enforce a minimum length of >= 5 characters for secure text alerts.
+ if let text = textField.text {
+ self.secureTextAlertAction!.isEnabled = text.count >= 5
+ } else {
+ self.secureTextAlertAction!.isEnabled = false
+ }
+ }
+ }
+
+ textField.isSecureTextEntry = true
+ }
+
+ // Create the actions.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The \"Secure Text Entry\" alert's cancel action occurred.")
+ }
+
+ let otherAction = UIAlertAction(title: otherButtonTitle, style: .default) { _ in
+ print("The \"Secure Text Entry\" alert's other action occurred.")
+ }
+
+ /** The text field initially has no text in the text field, so we'll disable it for now.
+ It will be re-enabled when the first character is typed.
+ */
+ otherAction.isEnabled = false
+
+ /** Hold onto the secure text alert action to toggle the enabled / disabled
+ state when the text changed.
+ */
+ secureTextAlertAction = otherAction
+
+ // Add the actions.
+ alertController.addAction(cancelAction)
+ alertController.addAction(otherAction)
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ // MARK: - UIAlertControllerStyleActionSheet Style Alerts
+
+ // Show a dialog with an "OK" and "Cancel" button.
+ func showOkayCancelActionSheet(_ selectedIndexPath: IndexPath) {
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
+ let destructiveButtonTitle = NSLocalizedString("Confirm", comment: "")
+
+ let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
+
+ // Create the actions.
+ let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { _ in
+ print("The \"OK/Cancel\" alert action sheet's cancel action occurred.")
+ }
+
+ let destructiveAction = UIAlertAction(title: destructiveButtonTitle, style: .default) { _ in
+ print("The \"Confirm\" alert action sheet's destructive action occurred.")
+ }
+
+ // Add the actions.
+ alertController.addAction(cancelAction)
+ alertController.addAction(destructiveAction)
+
+ // Configure the alert controller's popover presentation controller if it has one.
+ if let popoverPresentationController = alertController.popoverPresentationController {
+ // Note for popovers the Cancel button is hidden automatically.
+
+ // This method expects a valid cell to display from.
+ let selectedCell = tableView.cellForRow(at: selectedIndexPath)!
+ popoverPresentationController.sourceRect = selectedCell.frame
+ popoverPresentationController.sourceView = view
+ popoverPresentationController.permittedArrowDirections = .up
+ }
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+ // Show a dialog with two custom buttons.
+ func showOtherActionSheet(_ selectedIndexPath: IndexPath) {
+ let message = NSLocalizedString("A message should be a short, complete sentence.", comment: "")
+ let destructiveButtonTitle = NSLocalizedString("Destructive Choice", comment: "")
+ let otherButtonTitle = NSLocalizedString("Safe Choice", comment: "")
+
+ let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet)
+
+ // Create the actions.
+ let destructiveAction = UIAlertAction(title: destructiveButtonTitle, style: .destructive) { _ in
+ print("The \"Other\" alert action sheet's destructive action occurred.")
+ }
+ let otherAction = UIAlertAction(title: otherButtonTitle, style: .default) { _ in
+ print("The \"Other\" alert action sheet's other action occurred.")
+ }
+
+ // Add the actions.
+ alertController.addAction(destructiveAction)
+ alertController.addAction(otherAction)
+
+ // Configure the alert controller's popover presentation controller if it has one.
+ if let popoverPresentationController = alertController.popoverPresentationController {
+ // Note for popovers the Cancel button is hidden automatically.
+
+ // This method expects a valid cell to display from.
+ let selectedCell = tableView.cellForRow(at: selectedIndexPath)!
+ popoverPresentationController.sourceRect = selectedCell.frame
+ popoverPresentationController.sourceView = view
+ popoverPresentationController.permittedArrowDirections = .up
+ }
+
+ present(alertController, animated: true, completion: nil)
+ }
+
+}
+
+// MARK: - UITableViewDelegate
+
+extension AlertControllerViewController {
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ switch indexPath.section {
+ case StyleSections.alertStyleSection.rawValue:
+ // Alert style.
+ switch indexPath.row {
+ case AlertStyleTest.showSimpleAlert.rawValue:
+ showSimpleAlert()
+ case AlertStyleTest.showOkayCancelAlert.rawValue:
+ showOkayCancelAlert()
+ case AlertStyleTest.showOtherAlert.rawValue:
+ showOtherAlert()
+ case AlertStyleTest.showTextEntryAlert.rawValue:
+ showTextEntryAlert()
+ case AlertStyleTest.showSecureTextEntryAlert.rawValue:
+ showSecureTextEntryAlert()
+ default: break
+ }
+ case StyleSections.actionStyleSection.rawValue:
+ switch indexPath.row {
+ // Action sheet style.
+ case ActionSheetStyleTest.showOkayCancelActionSheet.rawValue:
+ showOkayCancelActionSheet(indexPath)
+ case ActionSheetStyleTest.howOtherActionSheet.rawValue:
+ showOtherActionSheet(indexPath)
+ default: break
+ }
+ default: break
+ }
+
+ tableView.deselectRow(at: indexPath, animated: true)
+ }
+
+}
diff --git a/UIKitCatalog/AppDelegate.swift b/UIKitCatalog/AppDelegate.swift
new file mode 100644
index 0000000..eb8830d
--- /dev/null
+++ b/UIKitCatalog/AppDelegate.swift
@@ -0,0 +1,32 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+The application-specific delegate class.
+*/
+
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: NSObject, UIApplicationDelegate, UISplitViewControllerDelegate {
+ // MARK: - Properties
+
+ var window: UIWindow?
+
+ /** The detailViewManager is responsible for maintaining the UISplitViewController delegation
+ and for managing the detail view controller of the split view.
+ */
+ var detailViewManager = DetailViewManager()
+
+ // MARK: - UIApplicationDelegate
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+ if let splitViewController = window!.rootViewController as? UISplitViewController {
+ splitViewController.preferredDisplayMode = .allVisible
+ splitViewController.delegate = detailViewManager
+ detailViewManager.splitViewController = splitViewController
+ }
+ return true
+ }
+
+}
diff --git a/UIKitCatalog/Assets.xcassets/AppIcon.appiconset/Contents.json b/UIKitCatalog/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d8db8d6
--- /dev/null
+++ b/UIKitCatalog/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/UIKitCatalog/Assets.xcassets/Contents.json b/UIKitCatalog/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_1.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/Flowers_1.imageset/Contents.json
new file mode 100644
index 0000000..4e892e1
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Flowers_1.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Flowers_1.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_1.imageset/Flowers_1.png b/UIKitCatalog/Assets.xcassets/Flowers_1.imageset/Flowers_1.png
new file mode 100644
index 0000000..a0b2e65
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/Flowers_1.imageset/Flowers_1.png differ
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_2.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/Flowers_2.imageset/Contents.json
new file mode 100644
index 0000000..f58b0f1
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Flowers_2.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Flowers_2.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_2.imageset/Flowers_2.png b/UIKitCatalog/Assets.xcassets/Flowers_2.imageset/Flowers_2.png
new file mode 100644
index 0000000..3646d88
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/Flowers_2.imageset/Flowers_2.png differ
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_3.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/Flowers_3.imageset/Contents.json
new file mode 100644
index 0000000..9b45f82
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Flowers_3.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Flowers_3.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_3.imageset/Flowers_3.png b/UIKitCatalog/Assets.xcassets/Flowers_3.imageset/Flowers_3.png
new file mode 100644
index 0000000..f2f6e2a
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/Flowers_3.imageset/Flowers_3.png differ
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_4.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/Flowers_4.imageset/Contents.json
new file mode 100644
index 0000000..188ca0b
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Flowers_4.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Flowers_4.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_4.imageset/Flowers_4.png b/UIKitCatalog/Assets.xcassets/Flowers_4.imageset/Flowers_4.png
new file mode 100644
index 0000000..96b6527
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/Flowers_4.imageset/Flowers_4.png differ
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_5.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/Flowers_5.imageset/Contents.json
new file mode 100644
index 0000000..b0a8ebc
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Flowers_5.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Flowers_5.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Flowers_5.imageset/Flowers_5.png b/UIKitCatalog/Assets.xcassets/Flowers_5.imageset/Flowers_5.png
new file mode 100644
index 0000000..0a67cd1
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/Flowers_5.imageset/Flowers_5.png differ
diff --git a/UIKitCatalog/Assets.xcassets/Tint_Blue_Color.colorset/Contents.json b/UIKitCatalog/Assets.xcassets/Tint_Blue_Color.colorset/Contents.json
new file mode 100644
index 0000000..ed6501d
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Tint_Blue_Color.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0.333",
+ "alpha" : "1.000",
+ "blue" : "1.000",
+ "green" : "0.784"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Tint_Green_Color.colorset/Contents.json b/UIKitCatalog/Assets.xcassets/Tint_Green_Color.colorset/Contents.json
new file mode 100644
index 0000000..80c4ff8
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Tint_Green_Color.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0.255",
+ "alpha" : "1.000",
+ "blue" : "0.470",
+ "green" : "0.804"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/Tint_Purple_Color.colorset/Contents.json b/UIKitCatalog/Assets.xcassets/Tint_Purple_Color.colorset/Contents.json
new file mode 100644
index 0000000..1bec8fc
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/Tint_Purple_Color.colorset/Contents.json
@@ -0,0 +1,20 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0.659",
+ "alpha" : "1.000",
+ "blue" : "0.988",
+ "green" : "0.271"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/Contents.json
new file mode 100644
index 0000000..86fc624
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "bookmark_icon_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "bookmark_icon_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "bookmark_icon_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_1x.png b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_1x.png
new file mode 100644
index 0000000..7fdb820
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_2x.png b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_2x.png
new file mode 100644
index 0000000..ee2b6c7
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_3x.png b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_3x.png
new file mode 100644
index 0000000..36f7dc5
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/bookmark_icon.imageset/bookmark_icon_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/Contents.json
new file mode 100644
index 0000000..2944503
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "bookmark_icon_highlighted_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "bookmark_icon_highlighted_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "bookmark_icon_highlighted_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_1x.png b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_1x.png
new file mode 100644
index 0000000..9763726
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_2x.png b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_2x.png
new file mode 100644
index 0000000..f6cb262
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_3x.png b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_3x.png
new file mode 100644
index 0000000..e654f0e
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/bookmark_icon_highlighted.imageset/bookmark_icon_highlighted_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/Contents.json
new file mode 100644
index 0000000..6f98023
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "checkmark_icon_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "checkmark_icon_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "checkmark_icon_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_1x.png b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_1x.png
new file mode 100644
index 0000000..8905a21
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_2x.png b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_2x.png
new file mode 100644
index 0000000..4392cb2
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_3x.png b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_3x.png
new file mode 100644
index 0000000..ecafedb
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/checkmark_icon.imageset/checkmark_icon_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/Contents.json
new file mode 100644
index 0000000..68464e9
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "search_bar_bg_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "search_bar_bg_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "search_bar_background_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_background_3x.png b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_background_3x.png
new file mode 100644
index 0000000..486f541
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_background_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_bg_1x.png b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_bg_1x.png
new file mode 100644
index 0000000..d20a0bb
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_bg_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_bg_2x.png b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_bg_2x.png
new file mode 100644
index 0000000..88ecb2f
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/search_bar_background.imageset/search_bar_bg_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/search_icon.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/search_icon.imageset/Contents.json
new file mode 100644
index 0000000..4c0295e
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/search_icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "search_icon_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "search_icon_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "search_icon_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_1x.png b/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_1x.png
new file mode 100644
index 0000000..74f9e9a
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_2x.png b/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_2x.png
new file mode 100644
index 0000000..5c7df70
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_3x.png b/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_3x.png
new file mode 100644
index 0000000..c3cc433
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/search_icon.imageset/search_icon_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/Contents.json
new file mode 100644
index 0000000..ea6fe64
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "slider_blue_track_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "slider_blue_track_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "slider_blue_track_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_1x.png b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_1x.png
new file mode 100644
index 0000000..3f10475
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_2x.png b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_2x.png
new file mode 100644
index 0000000..7ba3616
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_3x.png b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_3x.png
new file mode 100644
index 0000000..7f47c6e
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/Contents.json
new file mode 100644
index 0000000..bad8640
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "slider_green_track_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "slider_green_track_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "slider_green_track_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_1x.png b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_1x.png
new file mode 100644
index 0000000..dd6087d
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_2x.png b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_2x.png
new file mode 100644
index 0000000..5c6cd69
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_3x.png b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_3x.png
new file mode 100644
index 0000000..75a6915
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_green_track.imageset/slider_green_track_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/Contents.json
new file mode 100644
index 0000000..ff7f945
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "slider_thumb_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "slider_thumb_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "slider_thumb_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_1x.png b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_1x.png
new file mode 100644
index 0000000..44a2b0a
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_2x.png b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_2x.png
new file mode 100644
index 0000000..6f84378
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_3x.png b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_3x.png
new file mode 100644
index 0000000..9a46590
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/slider_thumb.imageset/slider_thumb_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/Contents.json
new file mode 100644
index 0000000..5e62406
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_1x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_1x.png
new file mode 100644
index 0000000..c65e396
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_2x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_2x.png
new file mode 100644
index 0000000..6e68c5b
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_3x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_3x.png
new file mode 100644
index 0000000..be14903
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background.imageset/stepper_and_segment_background_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/Contents.json
new file mode 100644
index 0000000..fdb1b66
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_disabled_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_disabled_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_disabled_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_1x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_1x.png
new file mode 100644
index 0000000..7abdc2b
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_2x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_2x.png
new file mode 100644
index 0000000..0580445
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_3x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_3x.png
new file mode 100644
index 0000000..29805f3
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_disabled.imageset/stepper_and_segment_background_disabled_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/Contents.json
new file mode 100644
index 0000000..bca57e8
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_highlighted_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_highlighted_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_background_highlighted_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_1x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_1x.png
new file mode 100644
index 0000000..c623650
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_2x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_2x.png
new file mode 100644
index 0000000..2a9ee5c
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_3x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_3x.png
new file mode 100644
index 0000000..cf0a17a
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_background_highlighted.imageset/stepper_and_segment_background_highlighted_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/Contents.json
new file mode 100644
index 0000000..1fdaeef
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_segment_divider_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_segment_divider_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_and_segment_divider_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_divider_3x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_divider_3x.png
new file mode 100644
index 0000000..1aabd6a
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_divider_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_segment_divider_1x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_segment_divider_1x.png
new file mode 100644
index 0000000..2d092bd
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_segment_divider_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_segment_divider_2x.png b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_segment_divider_2x.png
new file mode 100644
index 0000000..168bdfd
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_and_segment_segment_divider.imageset/stepper_and_segment_segment_divider_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/Contents.json
new file mode 100644
index 0000000..404bc3b
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "decrement_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "decrement_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_decrement_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/decrement_1x.png b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/decrement_1x.png
new file mode 100644
index 0000000..18969fd
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/decrement_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/decrement_2x.png b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/decrement_2x.png
new file mode 100644
index 0000000..53d3860
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/decrement_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/stepper_decrement_3x.png b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/stepper_decrement_3x.png
new file mode 100644
index 0000000..fa2db73
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_decrement.imageset/stepper_decrement_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/Contents.json
new file mode 100644
index 0000000..ac62061
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "increment_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "increment_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_increment_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/increment_1x.png b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/increment_1x.png
new file mode 100644
index 0000000..774f66c
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/increment_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/increment_2x.png b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/increment_2x.png
new file mode 100644
index 0000000..28eb035
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/increment_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/stepper_increment_3x.png b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/stepper_increment_3x.png
new file mode 100644
index 0000000..868bea2
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment.imageset/stepper_increment_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/Contents.json
new file mode 100644
index 0000000..b44a280
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "increment_disabled_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "increment_disabled_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_increment_disabled_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/increment_disabled_1x.png b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/increment_disabled_1x.png
new file mode 100644
index 0000000..7052591
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/increment_disabled_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/increment_disabled_2x.png b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/increment_disabled_2x.png
new file mode 100644
index 0000000..d263ac4
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/increment_disabled_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/stepper_increment_disabled_3x.png b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/stepper_increment_disabled_3x.png
new file mode 100644
index 0000000..a855e59
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment_disabled.imageset/stepper_increment_disabled_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/Contents.json
new file mode 100644
index 0000000..bb0fb61
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "increment_highlighted_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "increment_highlighted_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "stepper_increment_highlighted_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/increment_highlighted_1x.png b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/increment_highlighted_1x.png
new file mode 100644
index 0000000..f092afa
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/increment_highlighted_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/increment_highlighted_2x.png b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/increment_highlighted_2x.png
new file mode 100644
index 0000000..a3fcd53
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/increment_highlighted_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/stepper_increment_highlighted_3x.png b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/stepper_increment_highlighted_3x.png
new file mode 100644
index 0000000..3d416b3
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/stepper_increment_highlighted.imageset/stepper_increment_highlighted_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_field_background.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/Contents.json
new file mode 100644
index 0000000..7162851
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/Contents.json
@@ -0,0 +1,45 @@
+{
+ "images" : [
+ {
+ "resizing" : {
+ "mode" : "3-part-horizontal",
+ "center" : {
+ "mode" : "stretch",
+ "width" : 0
+ },
+ "cap-insets" : {
+ "right" : 1,
+ "left" : 1
+ }
+ },
+ "idiom" : "universal",
+ "filename" : "text_field_background_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "resizing" : {
+ "mode" : "3-part-horizontal",
+ "center" : {
+ "mode" : "stretch",
+ "width" : 0
+ },
+ "cap-insets" : {
+ "right" : 1,
+ "left" : 1
+ }
+ },
+ "idiom" : "universal",
+ "filename" : "text_field_background_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "text_field_background_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_1x.png b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_1x.png
new file mode 100644
index 0000000..5c3c3cf
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_2x.png b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_2x.png
new file mode 100644
index 0000000..abf9f0a
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_3x.png b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_3x.png
new file mode 100644
index 0000000..b121f9d
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_field_background.imageset/text_field_background_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/Contents.json
new file mode 100644
index 0000000..64a5b15
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "text_field_purple_right_view_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "text_field_purple_right_view_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "text_field_purple_right_view_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_1x.png b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_1x.png
new file mode 100644
index 0000000..c450af9
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_2x.png b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_2x.png
new file mode 100644
index 0000000..e81719e
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_3x.png b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_3x.png
new file mode 100644
index 0000000..2957cbb
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/text_view_attachment.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/text_view_attachment.imageset/Contents.json
new file mode 100644
index 0000000..fb8876d
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/text_view_attachment.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "Sunset_5.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/text_view_attachment.imageset/Sunset_5.png b/UIKitCatalog/Assets.xcassets/text_view_attachment.imageset/Sunset_5.png
new file mode 100644
index 0000000..3ce67df
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/text_view_attachment.imageset/Sunset_5.png differ
diff --git a/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/Contents.json
new file mode 100644
index 0000000..1756a03
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "toolbar_background_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "toolbar_background_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "toolbar_background_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_1x.png b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_1x.png
new file mode 100644
index 0000000..f37907f
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_2x.png b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_2x.png
new file mode 100644
index 0000000..a271d28
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_3x.png b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_3x.png
new file mode 100644
index 0000000..486f541
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/toolbar_background.imageset/toolbar_background_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/tools_icon.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/Contents.json
new file mode 100644
index 0000000..6e728cd
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "tools_icon_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "tools_icon_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "tools_icon_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_1x.png b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_1x.png
new file mode 100644
index 0000000..31491b1
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_2x.png b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_2x.png
new file mode 100644
index 0000000..e6eadf8
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_3x.png b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_3x.png
new file mode 100644
index 0000000..9e41751
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/tools_icon.imageset/tools_icon_3x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/x_icon.imageset/Contents.json b/UIKitCatalog/Assets.xcassets/x_icon.imageset/Contents.json
new file mode 100644
index 0000000..90ff9da
--- /dev/null
+++ b/UIKitCatalog/Assets.xcassets/x_icon.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "x_icon_1x.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "x_icon_2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "x_icon_3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_1x.png b/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_1x.png
new file mode 100644
index 0000000..84b6720
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_1x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_2x.png b/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_2x.png
new file mode 100644
index 0000000..71c09f4
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_2x.png differ
diff --git a/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_3x.png b/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_3x.png
new file mode 100644
index 0000000..968331d
Binary files /dev/null and b/UIKitCatalog/Assets.xcassets/x_icon.imageset/x_icon_3x.png differ
diff --git a/UIKitCatalog/Base.lproj/ActivityIndicatorViewController.storyboard b/UIKitCatalog/Base.lproj/ActivityIndicatorViewController.storyboard
new file mode 100644
index 0000000..580560c
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/ActivityIndicatorViewController.storyboard
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/AlertControllerViewController.storyboard b/UIKitCatalog/Base.lproj/AlertControllerViewController.storyboard
new file mode 100644
index 0000000..02c5c2c
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/AlertControllerViewController.storyboard
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/ButtonViewController.storyboard b/UIKitCatalog/Base.lproj/ButtonViewController.storyboard
new file mode 100644
index 0000000..9ece674
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/ButtonViewController.storyboard
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/DatePickerController.storyboard b/UIKitCatalog/Base.lproj/DatePickerController.storyboard
new file mode 100644
index 0000000..350b473
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/DatePickerController.storyboard
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/ImageViewController.storyboard b/UIKitCatalog/Base.lproj/ImageViewController.storyboard
new file mode 100644
index 0000000..796004d
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/ImageViewController.storyboard
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/InfoPlist.strings b/UIKitCatalog/Base.lproj/InfoPlist.strings
new file mode 100644
index 0000000..73c4a6e
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/InfoPlist.strings
@@ -0,0 +1,6 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Localized versions of Info.plist keys
+*/
diff --git a/UIKitCatalog/Base.lproj/LaunchScreen.storyboard b/UIKitCatalog/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..5e76aa0
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/Localizable.strings b/UIKitCatalog/Base.lproj/Localizable.strings
new file mode 100644
index 0000000..1da2680
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/Localizable.strings
@@ -0,0 +1,34 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Strings used across the application via the NSLocalizedString API.
+*/
+
+"OK" = "OK";
+"Cancel" = "Cancel";
+"Confirm" = "Confirm";
+"Destructive Choice" = "Destructive Choice";
+"Safe Choice" = "Safe Choice";
+"A Short Title Is Best" = "A Short Title Is Best";
+"A message should be a short, complete sentence." = "A message should be a short, complete sentence.";
+"Choice One" = "Choice One";
+"Choice Two" = "Choice Two";
+"Button" = "Button";
+"X Button" = "X Button";
+"Image" = "Image";
+"Action" = "Action";
+"bold" = "bold";
+"highlighted" = "highlighted";
+"underlined" = "underlined";
+"tinted" = "tinted";
+"Placeholder text" = "Placeholder text";
+"Red color component value" = "Red color component value";
+"Green color component value" = "Green color component value";
+"Blue color component value" = "Blue color component value";
+"Animated images" = "Animated images";
+"Done" = "Done";
+"Search" = "Search";
+"Settings" = "Settings";
+"UIKitCatalog" = "UIKitCatalog";
+"An error occurred:" = "An error occurred:";
diff --git a/UIKitCatalog/Base.lproj/Main.storyboard b/UIKitCatalog/Base.lproj/Main.storyboard
new file mode 100755
index 0000000..1e3ca33
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/Main.storyboard
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/PageControlViewController.storyboard b/UIKitCatalog/Base.lproj/PageControlViewController.storyboard
new file mode 100644
index 0000000..89785fd
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/PageControlViewController.storyboard
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/PickerViewController.storyboard b/UIKitCatalog/Base.lproj/PickerViewController.storyboard
new file mode 100644
index 0000000..2123c2a
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/PickerViewController.storyboard
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/ProgressViewController.storyboard b/UIKitCatalog/Base.lproj/ProgressViewController.storyboard
new file mode 100644
index 0000000..d111f1f
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/ProgressViewController.storyboard
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/SearchViewControllers.storyboard b/UIKitCatalog/Base.lproj/SearchViewControllers.storyboard
new file mode 100644
index 0000000..e42c5af
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/SearchViewControllers.storyboard
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/SegmentedControlViewController.storyboard b/UIKitCatalog/Base.lproj/SegmentedControlViewController.storyboard
new file mode 100644
index 0000000..9af9626
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/SegmentedControlViewController.storyboard
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/SliderViewController.storyboard b/UIKitCatalog/Base.lproj/SliderViewController.storyboard
new file mode 100644
index 0000000..8c437f8
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/SliderViewController.storyboard
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/StackViewController.storyboard b/UIKitCatalog/Base.lproj/StackViewController.storyboard
new file mode 100644
index 0000000..af759f9
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/StackViewController.storyboard
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/StepperViewController.storyboard b/UIKitCatalog/Base.lproj/StepperViewController.storyboard
new file mode 100644
index 0000000..83bf21f
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/StepperViewController.storyboard
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/SwitchViewController.storyboard b/UIKitCatalog/Base.lproj/SwitchViewController.storyboard
new file mode 100644
index 0000000..23973c0
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/SwitchViewController.storyboard
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/TextFieldViewController.storyboard b/UIKitCatalog/Base.lproj/TextFieldViewController.storyboard
new file mode 100644
index 0000000..f82c619
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/TextFieldViewController.storyboard
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/TextViewController.storyboard b/UIKitCatalog/Base.lproj/TextViewController.storyboard
new file mode 100644
index 0000000..18a71a6
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/TextViewController.storyboard
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This is a UITextView that uses attributed text. You can programmatically modify the display of the text by making it bold, highlighted, underlined, tinted, and more. These attributes are defined in NSAttributedString.h. You can even embed attachments in an NSAttributedString!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/ToolbarViewControllers.storyboard b/UIKitCatalog/Base.lproj/ToolbarViewControllers.storyboard
new file mode 100644
index 0000000..1be1d07
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/ToolbarViewControllers.storyboard
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/WebViewController.storyboard b/UIKitCatalog/Base.lproj/WebViewController.storyboard
new file mode 100644
index 0000000..217bad3
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/WebViewController.storyboard
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/UIKitCatalog/Base.lproj/content.html b/UIKitCatalog/Base.lproj/content.html
new file mode 100644
index 0000000..30dded1
--- /dev/null
+++ b/UIKitCatalog/Base.lproj/content.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+This is HTML content inside a WKWebView.
+
+
+
diff --git a/UIKitCatalog/BaseTableViewController.swift b/UIKitCatalog/BaseTableViewController.swift
new file mode 100644
index 0000000..4e06e87
--- /dev/null
+++ b/UIKitCatalog/BaseTableViewController.swift
@@ -0,0 +1,116 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Base class for any UITableViewController that is the master of the split view controller for
+ adaptability between regular and compact mode.
+*/
+
+import UIKit
+
+class BaseTableViewController: UITableViewController {
+ var savedSelectionIndexPath: IndexPath?
+ private var detailTargetChange: NSObjectProtocol!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ navigationController?.delegate = self // So we can listen when we come and go on the nav stack.
+
+ detailTargetChange = NotificationCenter.default.addObserver(
+ forName: NSNotification.Name.UIViewControllerShowDetailTargetDidChange,
+ object: nil,
+ queue: OperationQueue.main) { [unowned self] (_) in
+ // Whenever the target for showDetailViewController changes, update all of our cells
+ // to ensure they have the right accessory type.
+ //
+ for cell in self.tableView.visibleCells {
+ let indexPath = self.tableView.indexPath(for: cell)
+ self.tableView.delegate?.tableView!(self.tableView, willDisplay: cell, forRowAt: indexPath!)
+ }
+ }
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
+ super.viewWillAppear(animated)
+ }
+
+ deinit {
+ NotificationCenter.default.removeObserver(detailTargetChange)
+ }
+
+ // MARK: Utility functions
+
+ func configureCell(cell: UITableViewCell, indexPath: IndexPath) {
+ // For subclasses to override.
+ }
+
+ func isTwoLevelCell(indexPath: IndexPath) -> Bool {
+ // For subclasses to override.
+ return false
+ }
+
+ func splitViewWantsToShowDetail() -> Bool {
+ return splitViewController?.traitCollection.horizontalSizeClass == .regular
+ }
+
+ func pushOrPresentViewController(viewController: UIViewController, cellIndexPath: IndexPath) {
+ if splitViewWantsToShowDetail() {
+ if isTwoLevelCell(indexPath: cellIndexPath) {
+ navigationController?.pushViewController(viewController, animated: true) // Just push instead of replace.
+ tableView.deselectRow(at: cellIndexPath, animated: false)
+ } else {
+ let navVC = UINavigationController(rootViewController: viewController)
+ splitViewController?.showDetailViewController(navVC, sender: navVC) // Replace the detail view controller.
+ }
+ } else {
+ navigationController?.pushViewController(viewController, animated: true) // Just push instead of replace.
+ }
+ }
+
+ func pushOrPresentStoryboard(storyboardName: String, cellIndexPath: IndexPath) {
+ let exampleStoryboard = UIStoryboard(name: storyboardName, bundle: nil)
+ if let exampleViewController = exampleStoryboard.instantiateInitialViewController() {
+ pushOrPresentViewController(viewController: exampleViewController, cellIndexPath: cellIndexPath)
+ }
+ }
+
+}
+
+// MARK: - UITableViewDelegate
+
+extension BaseTableViewController {
+ override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
+ if splitViewWantsToShowDetail() {
+ cell.accessoryType = .none
+ if self.savedSelectionIndexPath != nil {
+ self.tableView.selectRow(at: savedSelectionIndexPath, animated: true, scrollPosition: .none)
+ }
+ } else {
+ cell.accessoryType = .disclosureIndicator
+ tableView.deselectRow(at: indexPath, animated: false)
+ }
+
+ configureCell(cell: cell, indexPath: indexPath as IndexPath)
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ savedSelectionIndexPath = indexPath
+ }
+
+}
+
+// MARK: - UINavigationControllerDelegate
+
+extension BaseTableViewController: UINavigationControllerDelegate {
+ func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
+ if viewController == self {
+ // We re-appeared on the nav stack (likely because we manually popped) so our saved selection should be cleared.
+ savedSelectionIndexPath = nil
+ }
+ }
+
+}
diff --git a/UIKitCatalog/ButtonViewController.swift b/UIKitCatalog/ButtonViewController.swift
new file mode 100644
index 0000000..1f1bb5e
--- /dev/null
+++ b/UIKitCatalog/ButtonViewController.swift
@@ -0,0 +1,108 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIButton`.
+ The buttons are created using storyboards, but each of the system buttons can be created in code by
+ using the UIButton.init(type buttonType: UIButtonType) initializer.
+
+ See the UIButton interface for a comprehensive list of the various UIButtonType values.
+*/
+
+import UIKit
+
+class ButtonViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var systemTextButton: UIButton!
+
+ @IBOutlet weak var systemContactAddButton: UIButton!
+
+ @IBOutlet weak var systemDetailDisclosureButton: UIButton!
+
+ @IBOutlet weak var imageButton: UIButton!
+
+ @IBOutlet weak var attributedTextButton: UIButton!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // All of the buttons are created in the storyboard, but configured below.
+ configureSystemTextButton()
+ configureSystemContactAddButton()
+ configureSystemDetailDisclosureButton()
+ configureImageButton()
+ configureAttributedTextSystemButton()
+ }
+
+ // MARK: - Configuration
+
+ func configureSystemTextButton() {
+ let buttonTitle = NSLocalizedString("Button", comment: "")
+
+ systemTextButton.setTitle(buttonTitle, for: .normal)
+
+ systemTextButton.addTarget(self, action: #selector(ButtonViewController.buttonClicked(_:)), for: .touchUpInside)
+ }
+
+ func configureSystemContactAddButton() {
+ systemContactAddButton.backgroundColor = UIColor.clear
+
+ systemContactAddButton.addTarget(self, action: #selector(ButtonViewController.buttonClicked(_:)), for: .touchUpInside)
+ }
+
+ func configureSystemDetailDisclosureButton() {
+ systemDetailDisclosureButton.backgroundColor = UIColor.clear
+
+ systemDetailDisclosureButton.addTarget(self, action: #selector(ButtonViewController.buttonClicked(_:)), for: .touchUpInside)
+ }
+
+ func configureImageButton() {
+ // To create this button in code you can use `UIButton.init(type: .system)`.
+
+ // Remove the title text.
+ imageButton.setTitle("", for: .normal)
+
+ imageButton.tintColor = UIColor(named: "Tint_Purple_Color")
+
+ let imageButtonNormalImage = #imageLiteral(resourceName: "x_icon")
+ imageButton.setImage(imageButtonNormalImage, for: .normal)
+
+ // Add an accessibility label to the image.
+ imageButton.accessibilityLabel = NSLocalizedString("X Button", comment: "")
+
+ imageButton.addTarget(self, action: #selector(ButtonViewController.buttonClicked(_:)), for: .touchUpInside)
+ }
+
+ func configureAttributedTextSystemButton() {
+ let buttonTitle = NSLocalizedString("Button", comment: "")
+
+ // Set the button's title for normal state.
+ let normalTitleAttributes: [NSAttributedStringKey: Any] = [
+ NSAttributedStringKey.foregroundColor: UIColor(named: "Tint_Blue_Color")!,
+ NSAttributedStringKey.strikethroughStyle: NSUnderlineStyle.styleSingle.rawValue
+ ]
+
+ let normalAttributedTitle = NSAttributedString(string: buttonTitle, attributes: normalTitleAttributes)
+ attributedTextButton.setAttributedTitle(normalAttributedTitle, for: .normal)
+
+ // Set the button's title for highlighted state.
+ let highlightedTitleAttributes = [
+ NSAttributedStringKey.foregroundColor: UIColor.green,
+ NSAttributedStringKey.strikethroughStyle: NSUnderlineStyle.styleThick.rawValue
+ ] as [NSAttributedStringKey: Any]
+ let highlightedAttributedTitle = NSAttributedString(string: buttonTitle, attributes: highlightedTitleAttributes)
+ attributedTextButton.setAttributedTitle(highlightedAttributedTitle, for: .highlighted)
+
+ attributedTextButton.addTarget(self, action: #selector(ButtonViewController.buttonClicked(_:)), for: .touchUpInside)
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func buttonClicked(_ sender: UIButton) {
+ print("A button was clicked: \(sender).")
+ }
+}
diff --git a/UIKitCatalog/CustomSearchBarViewController.swift b/UIKitCatalog/CustomSearchBarViewController.swift
new file mode 100644
index 0000000..f2033d9
--- /dev/null
+++ b/UIKitCatalog/CustomSearchBarViewController.swift
@@ -0,0 +1,61 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to customize a `UISearchBar`.
+*/
+
+import UIKit
+
+class CustomSearchBarViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var searchBar: UISearchBar!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureSearchBar()
+ }
+
+ // MARK: - Configuration
+
+ func configureSearchBar() {
+ searchBar.showsCancelButton = true
+ searchBar.showsBookmarkButton = true
+
+ searchBar.tintColor = UIColor(named: "Tint_Purple_Color")
+
+ searchBar.backgroundImage = UIImage(named: "search_bar_background")
+
+ // Set the bookmark image for both normal and highlighted states.
+ let bookmarkImage = #imageLiteral(resourceName: "bookmark_icon")
+ searchBar.setImage(bookmarkImage, for: .bookmark, state: .normal)
+
+ let bookmarkHighlightedImage = #imageLiteral(resourceName: "bookmark_icon_highlighted")
+ searchBar.setImage(bookmarkHighlightedImage, for: .bookmark, state: .highlighted)
+ }
+}
+
+// MARK: - UISearchBarDelegate
+
+extension CustomSearchBarViewController: UISearchBarDelegate {
+ func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
+ print("The custom search bar keyboard \"Search\" button was tapped.")
+
+ searchBar.resignFirstResponder()
+ }
+
+ func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
+ print("The custom search bar \"Cancel\" button was tapped.")
+
+ searchBar.resignFirstResponder()
+ }
+
+ func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) {
+ print("The custom \"bookmark button\" inside the search bar was tapped.")
+ }
+
+}
diff --git a/UIKitCatalog/CustomToolbarViewController.swift b/UIKitCatalog/CustomToolbarViewController.swift
new file mode 100644
index 0000000..7a321b9
--- /dev/null
+++ b/UIKitCatalog/CustomToolbarViewController.swift
@@ -0,0 +1,71 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to customize a `UIToolbar`.
+*/
+
+import UIKit
+
+class CustomToolbarViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var toolbar: UIToolbar!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let toolbarBackgroundImage = UIImage(named: "toolbar_background")
+ toolbar.setBackgroundImage(toolbarBackgroundImage, forToolbarPosition: .bottom, barMetrics: .default)
+
+ let toolbarButtonItems = [
+ customImageBarButtonItem,
+ flexibleSpaceBarButtonItem,
+ customBarButtonItem
+ ]
+ toolbar.setItems(toolbarButtonItems, animated: true)
+ }
+
+ // MARK: - UIBarButtonItem Creation and Configuration
+
+ var customImageBarButtonItem: UIBarButtonItem {
+ let customBarButtonItemImage = #imageLiteral(resourceName: "tools_icon")
+
+ let customImageBarButtonItem = UIBarButtonItem(image: customBarButtonItemImage,
+ style: .plain,
+ target: self,
+ action: #selector(CustomToolbarViewController.barButtonItemClicked(_:)))
+
+ customImageBarButtonItem.tintColor = UIColor(named: "Tint_Purple_Color")
+
+ return customImageBarButtonItem
+ }
+
+ var flexibleSpaceBarButtonItem: UIBarButtonItem {
+ // Note that there's no target/action since this represents empty space.
+ return UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
+ }
+
+ var customBarButtonItem: UIBarButtonItem {
+ let barButtonItem = UIBarButtonItem(title: NSLocalizedString("Button", comment: ""),
+ style: .plain,
+ target: self,
+ action: #selector(CustomToolbarViewController.barButtonItemClicked(_:)))
+
+ let attributes = [
+ NSAttributedStringKey.foregroundColor: UIColor(named: "Tint_Purple_Color")!
+ ]
+ barButtonItem.setTitleTextAttributes(attributes, for: .normal)
+
+ return barButtonItem
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func barButtonItemClicked(_ barButtonItem: UIBarButtonItem) {
+ print("A bar button item on the custom toolbar was clicked: \(barButtonItem).")
+ }
+}
diff --git a/UIKitCatalog/DatePickerController.swift b/UIKitCatalog/DatePickerController.swift
new file mode 100644
index 0000000..f131adf
--- /dev/null
+++ b/UIKitCatalog/DatePickerController.swift
@@ -0,0 +1,65 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIDatePicker`.
+*/
+
+import UIKit
+
+class DatePickerController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var datePicker: UIDatePicker!
+
+ @IBOutlet weak var dateLabel: UILabel!
+
+ // A date formatter to format the `date` property of `datePicker`.
+ lazy var dateFormatter: DateFormatter = {
+ let dateFormatter = DateFormatter()
+
+ dateFormatter.dateStyle = .medium
+ dateFormatter.timeStyle = .short
+
+ return dateFormatter
+ }()
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureDatePicker()
+ }
+
+ // MARK: - Configuration
+
+ func configureDatePicker() {
+ datePicker.datePickerMode = .dateAndTime
+
+ /** Set min/max date for the date picker. As an example we will limit the date between
+ now and 7 days from now.
+ */
+ let now = Date()
+ datePicker.minimumDate = now
+
+ var dateComponents = DateComponents()
+ dateComponents.day = 7
+
+ let sevenDaysFromNow = Calendar.current.date(byAdding: .day, value: 7, to: now)
+ datePicker.maximumDate = sevenDaysFromNow
+
+ datePicker.minuteInterval = 2
+
+ datePicker.addTarget(self, action: #selector(DatePickerController.updateDatePickerLabel), for: .valueChanged)
+
+ updateDatePickerLabel()
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func updateDatePickerLabel() {
+ dateLabel.text = dateFormatter.string(from: datePicker.date)
+ }
+}
diff --git a/UIKitCatalog/DefaultSearchBarViewController.swift b/UIKitCatalog/DefaultSearchBarViewController.swift
new file mode 100644
index 0000000..4b166f6
--- /dev/null
+++ b/UIKitCatalog/DefaultSearchBarViewController.swift
@@ -0,0 +1,56 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use a default `UISearchBar`.
+*/
+
+import UIKit
+
+class DefaultSearchBarViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var searchBar: UISearchBar!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureSearchBar()
+ }
+
+ // MARK: - Configuration
+
+ func configureSearchBar() {
+ searchBar.showsCancelButton = true
+ searchBar.showsScopeBar = true
+
+ searchBar.scopeButtonTitles = [
+ NSLocalizedString("Scope One", comment: ""),
+ NSLocalizedString("Scope Two", comment: "")
+ ]
+ }
+
+}
+
+// MARK: - UISearchBarDelegate
+
+extension DefaultSearchBarViewController: UISearchBarDelegate {
+ func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
+ print("The default search selected scope button index changed to \(selectedScope).")
+ }
+
+ func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
+ print("The default search bar keyboard search button was tapped: \(String(describing: searchBar.text)).")
+
+ searchBar.resignFirstResponder()
+ }
+
+ func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
+ print("The default search bar cancel button was tapped.")
+
+ searchBar.resignFirstResponder()
+ }
+
+}
diff --git a/UIKitCatalog/DefaultToolbarViewController.swift b/UIKitCatalog/DefaultToolbarViewController.swift
new file mode 100644
index 0000000..72aeea3
--- /dev/null
+++ b/UIKitCatalog/DefaultToolbarViewController.swift
@@ -0,0 +1,56 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use a default `UIToolbar`.
+*/
+
+import UIKit
+
+class DefaultToolbarViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var toolbar: UIToolbar!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let toolbarButtonItems = [
+ trashBarButtonItem,
+ flexibleSpaceBarButtonItem,
+ customTitleBarButtonItem
+ ]
+ toolbar.setItems(toolbarButtonItems, animated: true)
+ }
+
+ // MARK: - UIBarButtonItem Creation and Configuration
+
+ var trashBarButtonItem: UIBarButtonItem {
+ return UIBarButtonItem(barButtonSystemItem: .trash,
+ target: self,
+ action: #selector(DefaultToolbarViewController.barButtonItemClicked(_:)))
+ }
+
+ var flexibleSpaceBarButtonItem: UIBarButtonItem {
+ return UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
+ target: nil,
+ action: nil)
+ }
+
+ var customTitleBarButtonItem: UIBarButtonItem {
+ let customTitle = NSLocalizedString("Action", comment: "")
+ return UIBarButtonItem(title: customTitle,
+ style: .plain,
+ target: self,
+ action: #selector(DefaultToolbarViewController.barButtonItemClicked(_:)))
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func barButtonItemClicked(_ barButtonItem: UIBarButtonItem) {
+ print("A bar button item on the default toolbar was clicked: \(barButtonItem).")
+ }
+}
diff --git a/UIKitCatalog/DetailViewManager.swift b/UIKitCatalog/DetailViewManager.swift
new file mode 100644
index 0000000..b65afdc
--- /dev/null
+++ b/UIKitCatalog/DetailViewManager.swift
@@ -0,0 +1,76 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Manages how to handle the detail view controller for our split view controller.
+*/
+
+import UIKit
+
+class DetailViewManager: NSObject, UISplitViewControllerDelegate {
+ var splitViewController: UISplitViewController? = nil {
+ didSet {
+ splitViewController?.delegate = self
+ splitViewController?.preferredDisplayMode = .allVisible
+ }
+ }
+
+ /// Swaps out the detail for view controller for the Split View Controller this instance is managing.
+ func setDetailViewController(detailViewController: UIViewController) {
+ var viewControllers: [UIViewController] = (splitViewController?.viewControllers)!
+ if viewControllers.count > 1 {
+ viewControllers[1] = detailViewController
+ }
+ splitViewController?.viewControllers = viewControllers
+ }
+
+ /** Set the default plain detail view controller (called by PageOneViewController,
+ that is, in case a selected item is deleted in a split view controller)
+ */
+ func setDefaultDetailViewController() {
+ let initialDetailViewController = splitViewController?.storyboard?.instantiateViewController(withIdentifier: "navInitialDetail")
+ setDetailViewController(detailViewController: initialDetailViewController!)
+ }
+
+ // MARK: - UISplitViewControllerDelegate
+
+ func targetDisplayModeForAction(in splitViewController: UISplitViewController) -> UISplitViewControllerDisplayMode {
+ return .allVisible
+ }
+
+ func splitViewController(_ splitViewController: UISplitViewController,
+ collapseSecondary secondaryViewController: UIViewController,
+ onto primaryViewController: UIViewController) -> Bool {
+ return true
+ }
+
+ func splitViewController(_ splitViewController: UISplitViewController,
+ separateSecondaryFrom primaryViewController: UIViewController) -> UIViewController? {
+ var returnSecondaryVC: UIViewController? = nil
+
+ if let primaryVC = primaryViewController as? UINavigationController {
+ let selectedVC = primaryVC.topViewController
+ if selectedVC is UINavigationController {
+ if let navVC = selectedVC as? UINavigationController {
+ let currentVC = navVC.visibleViewController
+
+ if currentVC?.popDueToSizeChange != nil {
+ currentVC?.popDueToSizeChange()
+ }
+
+ // The currentVC has popped, now obtain it's ancestor vc in the table.
+ let currentVC2 = navVC.visibleViewController
+ if currentVC2 is BaseTableViewController {
+ let baseTableViewVC = currentVC2 as? BaseTableViewController
+ if baseTableViewVC?.tableView.indexPathForSelectedRow == nil {
+ // The table has no selection, make the detail empty.
+ returnSecondaryVC = splitViewController.storyboard?.instantiateViewController(withIdentifier: "navInitialDetail")
+ }
+ }
+ }
+ }
+ }
+
+ return returnSecondaryVC
+ }
+}
diff --git a/UIKitCatalog/ImageViewController.swift b/UIKitCatalog/ImageViewController.swift
new file mode 100644
index 0000000..de8aa9f
--- /dev/null
+++ b/UIKitCatalog/ImageViewController.swift
@@ -0,0 +1,42 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIImageView`.
+*/
+
+import UIKit
+
+class ImageViewController: UIViewController {
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureImageView()
+ }
+
+ // MARK: - Configuration
+
+ func configureImageView() {
+ // The root view of the view controller is set in Interface Builder and is an UIImageView.
+ if let imageView = view as? UIImageView {
+ // Fetch the images (each image is of the format Flowers_number).
+ imageView.animationImages = (1...5).map { UIImage(named: "Flowers_\($0)")! }
+
+ // We want the image to be scaled to the correct aspect ratio within imageView's bounds.
+ imageView.contentMode = .scaleAspectFit
+
+ /** If the image does not have the same aspect ratio as imageView's bounds,
+ then imageView's backgroundColor will be applied to the "empty" space.
+ */
+ imageView.backgroundColor = UIColor.white
+
+ imageView.animationDuration = 5
+ imageView.startAnimating()
+
+ imageView.isAccessibilityElement = true
+ imageView.accessibilityLabel = NSLocalizedString("Animated", comment: "")
+ }
+ }
+}
diff --git a/UIKitCatalog/MasterViewController.swift b/UIKitCatalog/MasterViewController.swift
new file mode 100644
index 0000000..8a79cdf
--- /dev/null
+++ b/UIKitCatalog/MasterViewController.swift
@@ -0,0 +1,87 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+The primary table view controller displaying all the UIKit examples.
+*/
+
+import UIKit
+
+class MasterViewController: BaseTableViewController {
+
+ struct Example {
+ var title: String
+ var subTitle: String
+ var twoLevel: Bool
+ }
+
+ var exampleList = [
+ // This is a list of examples offered by this sample.
+ Example(title: "Activity Indicators", subTitle: "ActivityIndicatorViewController", twoLevel: false),
+ Example(title: "Alert Controller", subTitle: "AlertControllerViewController", twoLevel: false),
+ Example(title: "Buttons", subTitle: "ButtonViewController", twoLevel: false),
+ Example(title: "Date Picker", subTitle: "DatePickerController", twoLevel: false),
+ Example(title: "Image View", subTitle: "ImageViewController", twoLevel: false),
+ Example(title: "Page Control", subTitle: "PageControlViewController", twoLevel: false),
+ Example(title: "Picker View", subTitle: "PickerViewController", twoLevel: false),
+ Example(title: "Progress Views", subTitle: "ProgressViewController", twoLevel: false),
+ Example(title: "Search", subTitle: "SearchViewControllers", twoLevel: true),
+ Example(title: "Segmented Controls", subTitle: "SegmentedControlViewController", twoLevel: false),
+ Example(title: "Sliders", subTitle: "SliderViewController", twoLevel: false),
+ Example(title: "Stack Views", subTitle: "StackViewController", twoLevel: false),
+ Example(title: "Steppers", subTitle: "StepperViewController", twoLevel: false),
+ Example(title: "Switches", subTitle: "SwitchViewController", twoLevel: false),
+ Example(title: "Text Fields", subTitle: "TextFieldViewController", twoLevel: false),
+ Example(title: "Text View", subTitle: "TextViewController", twoLevel: false),
+ Example(title: "Toolbars", subTitle: "ToolbarViewControllers", twoLevel: true),
+ Example(title: "Web View", subTitle: "WebViewController", twoLevel: false)
+ ]
+
+ override func isTwoLevelCell(indexPath: IndexPath) -> Bool {
+ var twoLevelCell = false
+ twoLevelCell = exampleList[indexPath.row].twoLevel
+ return twoLevelCell
+ }
+
+ override func configureCell(cell: UITableViewCell, indexPath: IndexPath) {
+ let splitViewWantsToShowDetail = splitViewController?.traitCollection.horizontalSizeClass == .regular
+ if splitViewWantsToShowDetail {
+ if isTwoLevelCell(indexPath: indexPath) {
+ cell.accessoryType = .disclosureIndicator
+ }
+ } else {
+ // For two level table views in split view master/detail mode we don't navigate but just present.
+ if isTwoLevelCell(indexPath: indexPath) {
+ cell.accessoryType = isTwoLevelCell(indexPath: indexPath) ? .disclosureIndicator : .none
+ }
+ }
+ }
+
+}
+
+// MARK: - UITableViewDataSource
+
+extension MasterViewController {
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return exampleList.count
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
+ let example = exampleList[indexPath.row]
+ cell.textLabel?.text = example.title
+ cell.detailTextLabel?.text = example.subTitle
+ return cell
+ }
+}
+
+// MARK: - UITableViewDelegate
+
+extension MasterViewController {
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let example = exampleList[indexPath.row]
+ pushOrPresentStoryboard(storyboardName: example.subTitle, cellIndexPath: indexPath)
+ }
+
+}
+
diff --git a/UIKitCatalog/PageControlViewController.swift b/UIKitCatalog/PageControlViewController.swift
new file mode 100644
index 0000000..32efeaf
--- /dev/null
+++ b/UIKitCatalog/PageControlViewController.swift
@@ -0,0 +1,62 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIPageControl`.
+*/
+
+import UIKit
+
+class PageControlViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var pageControl: UIPageControl!
+
+ @IBOutlet weak var colorView: UIView!
+
+ // Colors that correspond to the selected page. Used as the background color for `colorView`.
+ let colors = [
+ UIColor.black,
+ UIColor.gray,
+ UIColor.red,
+ UIColor.green,
+ UIColor.blue,
+ UIColor.cyan,
+ UIColor.yellow,
+ UIColor.magenta,
+ UIColor.orange,
+ UIColor.purple
+ ]
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configurePageControl()
+ pageControlValueDidChange()
+ }
+
+ // MARK: - Configuration
+
+ func configurePageControl() {
+ // The total number of available pages is based on the number of available colors.
+ pageControl.numberOfPages = colors.count
+ pageControl.currentPage = 2
+
+ pageControl.pageIndicatorTintColor = UIColor(named: "Tint_Green_Color")
+ pageControl.currentPageIndicatorTintColor = UIColor(named: "Tint_Purple_Color")
+
+ pageControl.addTarget(self, action: #selector(PageControlViewController.pageControlValueDidChange), for: .valueChanged)
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func pageControlValueDidChange() {
+ // Note: gesture swiping between pages is provided by `UIPageViewController` and not `UIPageControl`.
+ print("The page control changed its current page to \(pageControl.currentPage).")
+
+ colorView.backgroundColor = colors[pageControl.currentPage]
+ }
+}
diff --git a/UIKitCatalog/PickerViewController.swift b/UIKitCatalog/PickerViewController.swift
new file mode 100644
index 0000000..a9d4052
--- /dev/null
+++ b/UIKitCatalog/PickerViewController.swift
@@ -0,0 +1,165 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIPickerView`.
+*/
+
+import UIKit
+
+class PickerViewController: UIViewController {
+ // MARK: - Types
+
+ enum ColorComponent: Int {
+ case red = 0, green, blue
+
+ static var count: Int {
+ return ColorComponent.blue.rawValue + 1
+ }
+ }
+
+ struct RGB {
+ static let max: CGFloat = 255.0
+ static let min: CGFloat = 0.0
+ static let offset: CGFloat = 5.0
+ }
+
+ // MARK: - Properties
+
+ @IBOutlet weak var pickerView: UIPickerView!
+ @IBOutlet weak var colorSwatchView: UIView!
+
+ lazy var numberOfColorValuesPerComponent: Int = (Int(RGB.max) / Int(RGB.offset)) + 1
+
+ var redColor: CGFloat = RGB.min {
+ didSet {
+ updateColorSwatchViewBackgroundColor()
+ }
+ }
+
+ var greenColor: CGFloat = RGB.min {
+ didSet {
+ updateColorSwatchViewBackgroundColor()
+ }
+ }
+
+ var blueColor: CGFloat = RGB.min {
+ didSet {
+ updateColorSwatchViewBackgroundColor()
+ }
+ }
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configurePickerView()
+ }
+
+ func updateColorSwatchViewBackgroundColor() {
+ colorSwatchView.backgroundColor = UIColor(red: redColor, green: greenColor, blue: blueColor, alpha: 1)
+ }
+
+ func configurePickerView() {
+ // Show that a given row is selected. This is off by default.
+ pickerView.showsSelectionIndicator = true
+
+ // Set the default selected rows (the desired rows to initially select will vary from app to app).
+ let selectedRows: [ColorComponent: Int] = [.red: 13, .green: 41, .blue: 24]
+
+ for (colorComponent, selectedRow) in selectedRows {
+ /** Note that the delegate method on `UIPickerViewDelegate` is not triggered
+ when manually calling `selectRow(_:inComponent:animated:)`. To do
+ this, we fire off delegate method manually.
+ */
+ pickerView.selectRow(selectedRow, inComponent: colorComponent.rawValue, animated: true)
+ pickerView(pickerView, didSelectRow: selectedRow, inComponent: colorComponent.rawValue)
+ }
+ }
+
+}
+
+// MARK: - UIPickerViewDataSource
+
+extension PickerViewController: UIPickerViewDataSource {
+ func numberOfComponents(in pickerView: UIPickerView) -> Int {
+ return ColorComponent.count
+ }
+
+ func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
+ return numberOfColorValuesPerComponent
+ }
+}
+
+// MARK: - UIPickerViewDelegate
+
+extension PickerViewController: UIPickerViewDelegate {
+ func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
+ let colorValue = CGFloat(row) * RGB.offset
+
+ // Set the initial colors for each picker segment.
+ let value = CGFloat(colorValue) / RGB.max
+ var redColorComponent = RGB.min
+ var greenColorComponent = RGB.min
+ var blueColorComponent = RGB.min
+
+ switch ColorComponent(rawValue: component)! {
+ case .red:
+ redColorComponent = value
+
+ case .green:
+ greenColorComponent = value
+
+ case .blue:
+ blueColorComponent = value
+ }
+
+ let foregroundColor = UIColor(red: redColorComponent, green: greenColorComponent, blue: blueColorComponent, alpha: 1)
+
+ // Set the foreground color for the entire attributed string.
+ let attributes = [
+ NSAttributedStringKey.foregroundColor: foregroundColor
+ ]
+
+ let title = NSMutableAttributedString(string: "\(Int(colorValue))", attributes: attributes)
+
+ return title
+ }
+
+ func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
+ let colorComponentValue = RGB.offset * CGFloat(row) / RGB.max
+
+ switch ColorComponent(rawValue: component)! {
+ case .red:
+ redColor = colorComponentValue
+
+ case .green:
+ greenColor = colorComponentValue
+
+ case .blue:
+ blueColor = colorComponentValue
+ }
+ }
+
+}
+
+// MARK: - UIPickerViewAccessibilityDelegate
+
+extension PickerViewController: UIPickerViewAccessibilityDelegate {
+
+ func pickerView(_ pickerView: UIPickerView, accessibilityLabelForComponent component: Int) -> String? {
+
+ switch ColorComponent(rawValue: component)! {
+ case .red:
+ return NSLocalizedString("Red color component value", comment: "")
+
+ case .green:
+ return NSLocalizedString("Green color component value", comment: "")
+
+ case .blue:
+ return NSLocalizedString("Blue color component value", comment: "")
+ }
+ }
+}
+
diff --git a/UIKitCatalog/ProgressViewController.swift b/UIKitCatalog/ProgressViewController.swift
new file mode 100644
index 0000000..d77b6fe
--- /dev/null
+++ b/UIKitCatalog/ProgressViewController.swift
@@ -0,0 +1,109 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIProgressView`.
+*/
+
+import UIKit
+
+class ProgressViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var defaultStyleProgressView: UIProgressView!
+
+ @IBOutlet weak var barStyleProgressView: UIProgressView!
+
+ @IBOutlet weak var tintedProgressView: UIProgressView!
+
+ @IBOutlet var progressViews: [UIProgressView]!
+
+ var observer: NSKeyValueObservation?
+
+ /** An `NSProgress` object who's `fractionCompleted` is observed using KVO to update
+ the `UIProgressView`s' `progress` properties.
+ */
+ let progress = Progress(totalUnitCount: 10)
+
+ // A repeating timer that, when fired, updates the `NSProgress` object's `completedUnitCount` property.
+ var updateTimer: Timer?
+
+ // MARK: - Initialization
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+
+ // Register as an observer of the `NSProgress`'s `fractionCompleted` property.
+ observer = progress.observe(\.fractionCompleted, options: [.new]) { (_, _) in
+ // Update the progress views.
+ for progressView in self.progressViews {
+ progressView.setProgress(Float(self.progress.fractionCompleted), animated: true)
+ }
+ }
+ }
+
+ deinit {
+ // Unregister as an observer of the `NSProgress`'s `fractionCompleted` property.
+ observer?.invalidate()
+ }
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureDefaultStyleProgressView()
+ configureBarStyleProgressView()
+ configureTintedProgressView()
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+
+ // Reset the completed progress of the `UIProgressView`s.
+ for progressView in progressViews {
+ progressView.setProgress(0.0, animated: false)
+ }
+
+ /** Reset the `completedUnitCount` of the `NSProgress` object and create
+ a repeating timer to increment it over time.
+ */
+ progress.completedUnitCount = 0
+
+ updateTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (_) in
+ /** Update the `completedUnitCount` of the `NSProgress` object if it's
+ not completed. Otherwise, stop the timer.
+ */
+ if self.progress.completedUnitCount < self.progress.totalUnitCount {
+ self.progress.completedUnitCount += 1
+ } else {
+ self.updateTimer?.invalidate()
+ }
+ })
+ }
+
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+
+ // Stop the timer from firing.
+ updateTimer?.invalidate()
+ }
+
+ // MARK: - Configuration
+
+ func configureDefaultStyleProgressView() {
+ defaultStyleProgressView.progressViewStyle = .default
+ }
+
+ func configureBarStyleProgressView() {
+ barStyleProgressView.progressViewStyle = .bar
+ }
+
+ func configureTintedProgressView() {
+ tintedProgressView.progressViewStyle = .default
+
+ tintedProgressView.trackTintColor = UIColor(named: "Tint_Blue_Color")
+ tintedProgressView.progressTintColor = UIColor(named: "Tint_Purple_Color")
+ }
+
+}
diff --git a/UIKitCatalog/SearchBarsTableViewController.swift b/UIKitCatalog/SearchBarsTableViewController.swift
new file mode 100644
index 0000000..87116c4
--- /dev/null
+++ b/UIKitCatalog/SearchBarsTableViewController.swift
@@ -0,0 +1,30 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Table view controller for presenting various search bars.
+*/
+
+import UIKit
+
+class SearchBarsTableViewController: BaseTableViewController {
+ // MARK: - UITableViewDelegate
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ var storyboardSceneID = String()
+
+ switch indexPath.row {
+ case 0:
+ // Default
+ storyboardSceneID = "DefaultSearchBarViewController"
+ case 1:
+ // Custom
+ storyboardSceneID = "CustomSearchBarViewController"
+ default: break
+ }
+
+ let exampleViewController = storyboard?.instantiateViewController(withIdentifier: storyboardSceneID)
+ pushOrPresentViewController(viewController: exampleViewController!, cellIndexPath: indexPath)
+ }
+}
+
diff --git a/UIKitCatalog/SegmentedControlViewController.swift b/UIKitCatalog/SegmentedControlViewController.swift
new file mode 100644
index 0000000..91dac75
--- /dev/null
+++ b/UIKitCatalog/SegmentedControlViewController.swift
@@ -0,0 +1,124 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UISegmentedControl`.
+*/
+
+import UIKit
+
+class SegmentedControlViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var defaultSegmentedControl: UISegmentedControl!
+
+ @IBOutlet weak var tintedSegmentedControl: UISegmentedControl!
+
+ @IBOutlet weak var customSegmentsSegmentedControl: UISegmentedControl!
+
+ @IBOutlet weak var customBackgroundSegmentedControl: UISegmentedControl!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureDefaultSegmentedControl()
+ configureTintedSegmentedControl()
+ configureCustomSegmentsSegmentedControl()
+ configureCustomBackgroundSegmentedControl()
+ }
+
+ // MARK: - Configuration
+
+ func configureDefaultSegmentedControl() {
+
+ defaultSegmentedControl.setEnabled(false, forSegmentAt: 0)
+
+ defaultSegmentedControl.addTarget(self, action: #selector(SegmentedControlViewController.selectedSegmentDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureTintedSegmentedControl() {
+ tintedSegmentedControl.tintColor = UIColor(named: "Tint_Blue_Color")
+
+ tintedSegmentedControl.selectedSegmentIndex = 1
+
+ tintedSegmentedControl.addTarget(self, action: #selector(SegmentedControlViewController.selectedSegmentDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureCustomSegmentsSegmentedControl() {
+ let imageToAccessibilityLabelMappings = [
+ "checkmark_icon": NSLocalizedString("Done", comment: ""),
+ "search_icon": NSLocalizedString("Search", comment: ""),
+ "tools_icon": NSLocalizedString("Settings", comment: "")
+ ]
+
+ // Guarantee that the segments show up in the same order.
+ var sortedSegmentImageNames = Array(imageToAccessibilityLabelMappings.keys)
+ sortedSegmentImageNames.sort { lhs, rhs in
+ return lhs.localizedStandardCompare(rhs) == ComparisonResult.orderedAscending
+ }
+
+ for (idx, segmentImageName) in sortedSegmentImageNames.enumerated() {
+ let image = UIImage(named: segmentImageName)!
+
+ image.accessibilityLabel = imageToAccessibilityLabelMappings[segmentImageName]
+
+ customSegmentsSegmentedControl.setImage(image, forSegmentAt: idx)
+ }
+
+ customSegmentsSegmentedControl.selectedSegmentIndex = 0
+
+ customSegmentsSegmentedControl.addTarget(self,
+ action: #selector(SegmentedControlViewController.selectedSegmentDidChange(_:)),
+ for: .valueChanged)
+ }
+
+ func configureCustomBackgroundSegmentedControl() {
+ customBackgroundSegmentedControl.selectedSegmentIndex = 2
+
+ // Set the background images for each control state.
+ let normalSegmentBackgroundImage = UIImage(named: "stepper_and_segment_background")
+ customBackgroundSegmentedControl.setBackgroundImage(normalSegmentBackgroundImage, for: .normal, barMetrics: .default)
+
+ let disabledSegmentBackgroundImage = UIImage(named: "stepper_and_segment_background_disabled")
+ customBackgroundSegmentedControl.setBackgroundImage(disabledSegmentBackgroundImage, for: .disabled, barMetrics: .default)
+
+ let highlightedSegmentBackgroundImage = UIImage(named: "stepper_and_segment_background_highlighted")
+ customBackgroundSegmentedControl.setBackgroundImage(highlightedSegmentBackgroundImage, for: .highlighted, barMetrics: .default)
+
+ // Set the divider image.
+ let segmentDividerImage = UIImage(named: "stepper_and_segment_divider")
+ customBackgroundSegmentedControl.setDividerImage(segmentDividerImage,
+ forLeftSegmentState: .normal,
+ rightSegmentState: .normal,
+ barMetrics: .default)
+
+ // Create a font to use for the attributed title, for both normal and highlighted states.
+ let captionFontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .caption1)
+ let font = UIFont(descriptor: captionFontDescriptor, size: 0)
+
+ let normalTextAttributes = [
+ NSAttributedStringKey.foregroundColor: UIColor(named: "Tint_Purple_Color")!,
+ NSAttributedStringKey.font: font
+ ]
+ customBackgroundSegmentedControl.setTitleTextAttributes(normalTextAttributes, for: .normal)
+
+ let highlightedTextAttributes = [
+ NSAttributedStringKey.foregroundColor: UIColor(named: "Tint_Green_Color")!,
+ NSAttributedStringKey.font: font
+ ]
+ customBackgroundSegmentedControl.setTitleTextAttributes(highlightedTextAttributes, for: .highlighted)
+
+ customBackgroundSegmentedControl.addTarget(self,
+ action: #selector(SegmentedControlViewController.selectedSegmentDidChange(_:)),
+ for: .valueChanged)
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func selectedSegmentDidChange(_ segmentedControl: UISegmentedControl) {
+ print("The selected segment changed for: \(segmentedControl).")
+ }
+}
diff --git a/UIKitCatalog/SliderViewController.swift b/UIKitCatalog/SliderViewController.swift
new file mode 100644
index 0000000..76f75de
--- /dev/null
+++ b/UIKitCatalog/SliderViewController.swift
@@ -0,0 +1,69 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UISlider`.
+*/
+
+import UIKit
+
+class SliderViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var defaultSlider: UISlider!
+ @IBOutlet weak var tintedSlider: UISlider!
+ @IBOutlet weak var customSlider: UISlider!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureDefaultSlider()
+ configureTintedSlider()
+ configureCustomSlider()
+ }
+
+ // MARK: - Configuration
+
+ func configureDefaultSlider() {
+ defaultSlider.minimumValue = 0
+ defaultSlider.maximumValue = 100
+ defaultSlider.value = 42
+ defaultSlider.isContinuous = true
+
+ defaultSlider.addTarget(self, action: #selector(SliderViewController.sliderValueDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureTintedSlider() {
+ tintedSlider.minimumTrackTintColor = UIColor(named: "Tint_Blue_Color")
+ tintedSlider.maximumTrackTintColor = UIColor(named: "Tint_Purple_Color")
+
+ tintedSlider.addTarget(self, action: #selector(SliderViewController.sliderValueDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureCustomSlider() {
+ let leftTrackImage = UIImage(named: "slider_blue_track")
+ customSlider.setMinimumTrackImage(leftTrackImage, for: .normal)
+
+ let rightTrackImage = UIImage(named: "slider_green_track")
+ customSlider.setMaximumTrackImage(rightTrackImage, for: .normal)
+
+ let thumbImage = UIImage(named: "slider_thumb")
+ customSlider.setThumbImage(thumbImage, for: .normal)
+
+ customSlider.minimumValue = 0
+ customSlider.maximumValue = 100
+ customSlider.isContinuous = false
+ customSlider.value = 84
+
+ customSlider.addTarget(self, action: #selector(SliderViewController.sliderValueDidChange(_:)), for: .valueChanged)
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func sliderValueDidChange(_ slider: UISlider) {
+ print("A slider changed its value: \(slider).")
+ }
+}
diff --git a/UIKitCatalog/StackViewController.swift b/UIKitCatalog/StackViewController.swift
new file mode 100644
index 0000000..5f10276
--- /dev/null
+++ b/UIKitCatalog/StackViewController.swift
@@ -0,0 +1,102 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates different options for manipulating `UIStackView` content.
+*/
+
+import UIKit
+
+class StackViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet var furtherDetailStackView: UIStackView!
+
+ @IBOutlet var plusButton: UIButton!
+
+ @IBOutlet var addRemoveExampleStackView: UIStackView!
+
+ @IBOutlet var addArrangedViewButton: UIButton!
+
+ @IBOutlet var removeArrangedViewButton: UIButton!
+
+ let maximumArrangedSubviewCount = 3
+
+ // MARK: - View Life Cycle
+
+ override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+
+ furtherDetailStackView.isHidden = true
+ plusButton.isHidden = false
+ updateAddRemoveButtons()
+ }
+
+ // MARK: - Actions
+
+ @IBAction func showFurtherDetail(_: AnyObject) {
+ // Animate the changes by performing them in a `UIViewPropertyAnimator` animation block.
+ let showDetailAnimator = UIViewPropertyAnimator(duration: 0.25, curve: .easeIn, animations: { [weak self] in
+ // Reveal the further details stack view and hide the plus button.
+ self?.furtherDetailStackView.isHidden = false
+ self?.plusButton.isHidden = true
+ })
+ showDetailAnimator.startAnimation()
+ }
+
+ @IBAction func hideFurtherDetail(_: AnyObject) {
+ // Animate the changes by performing them in a `UIViewPropertyAnimator` animation block.
+ let hideDetailAnimator = UIViewPropertyAnimator(duration: 0.25, curve: .easeOut, animations: { [weak self] in
+ // Reveal the further details stack view and hide the plus button.
+ self?.furtherDetailStackView.isHidden = true
+ self?.plusButton.isHidden = false
+ })
+ hideDetailAnimator.startAnimation()
+ }
+
+ @IBAction func addArrangedSubviewToStack(_: AnyObject) {
+ // Create a simple, fixed-size, square view to add to the stack view.
+ let newViewSize = CGSize(width: 38, height: 38)
+ let newView = UIView(frame: CGRect(origin: CGPoint.zero, size: newViewSize))
+ newView.backgroundColor = randomColor()
+ newView.widthAnchor.constraint(equalToConstant: newViewSize.width).isActive = true
+ newView.heightAnchor.constraint(equalToConstant: newViewSize.height).isActive = true
+
+ // Adding an arranged subview automatically adds it as a child of the stack view.
+ addRemoveExampleStackView.addArrangedSubview(newView)
+
+ updateAddRemoveButtons()
+ }
+
+ @IBAction func removeArrangedSubviewFromStack(_: AnyObject) {
+ // Make sure there is an arranged view to remove.
+ guard let viewToRemove = addRemoveExampleStackView.arrangedSubviews.last else { return }
+
+ addRemoveExampleStackView.removeArrangedSubview(viewToRemove)
+
+ /** Calling `removeArrangedSubview` does not remove the provided view from
+ the stack view's `subviews` array. Since we no longer want the view
+ we removed to appear, we have to explicitly remove it from its superview.
+ */
+ viewToRemove.removeFromSuperview()
+
+ updateAddRemoveButtons()
+ }
+
+ // MARK: - Convenience
+
+ func updateAddRemoveButtons() {
+ let arrangedSubviewCount = addRemoveExampleStackView.arrangedSubviews.count
+
+ addArrangedViewButton.isEnabled = arrangedSubviewCount < maximumArrangedSubviewCount
+ removeArrangedViewButton.isEnabled = arrangedSubviewCount > 0
+ }
+
+ func randomColor() -> UIColor {
+ let red = CGFloat(arc4random_uniform(255)) / 255.0
+ let green = CGFloat(arc4random_uniform(255)) / 255.0
+ let blue = CGFloat(arc4random_uniform(255)) / 255.0
+
+ return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
+ }
+}
diff --git a/UIKitCatalog/StepperViewController.swift b/UIKitCatalog/StepperViewController.swift
new file mode 100644
index 0000000..8d31eaf
--- /dev/null
+++ b/UIKitCatalog/StepperViewController.swift
@@ -0,0 +1,96 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UIStepper`.
+*/
+
+import UIKit
+
+class StepperViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var defaultStepper: UIStepper!
+
+ @IBOutlet weak var tintedStepper: UIStepper!
+
+ @IBOutlet weak var customStepper: UIStepper!
+
+ @IBOutlet weak var defaultStepperLabel: UILabel!
+
+ @IBOutlet weak var tintedStepperLabel: UILabel!
+
+ @IBOutlet weak var customStepperLabel: UILabel!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureDefaultStepper()
+ configureTintedStepper()
+ configureCustomStepper()
+ }
+
+ // MARK: - Configuration
+
+ func configureDefaultStepper() {
+ defaultStepper.value = 0
+ defaultStepper.minimumValue = 0
+ defaultStepper.maximumValue = 10
+ defaultStepper.stepValue = 1
+
+ defaultStepperLabel.text = "\(Int(defaultStepper.value))"
+ defaultStepper.addTarget(self, action: #selector(StepperViewController.stepperValueDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureTintedStepper() {
+ tintedStepper.tintColor = UIColor(named: "Tint_Blue_Color")
+
+ tintedStepperLabel.text = "\(Int(tintedStepper.value))"
+ tintedStepper.addTarget(self, action: #selector(StepperViewController.stepperValueDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureCustomStepper() {
+ // Set the background image.
+ let stepperBackgroundImage = UIImage(named: "stepper_and_segment_background")
+ customStepper.setBackgroundImage(stepperBackgroundImage, for: .normal)
+
+ let stepperHighlightedBackgroundImage = UIImage(named: "stepper_and_segment_background_highlighted")
+ customStepper.setBackgroundImage(stepperHighlightedBackgroundImage, for: .highlighted)
+
+ let stepperDisabledBackgroundImage = UIImage(named: "stepper_and_segment_background_disabled")
+ customStepper.setBackgroundImage(stepperDisabledBackgroundImage, for: .disabled)
+
+ // Set the image which will be painted in between the two stepper segments. It depends on the states of both segments.
+ let stepperSegmentDividerImage = UIImage(named: "stepper_and_segment_divider")
+ customStepper.setDividerImage(stepperSegmentDividerImage, forLeftSegmentState: .normal, rightSegmentState: .normal)
+
+ // Set the image for the + button.
+ let stepperIncrementImage = UIImage(named: "stepper_increment")
+ customStepper.setIncrementImage(stepperIncrementImage, for: .normal)
+
+ // Set the image for the - button.
+ let stepperDecrementImage = UIImage(named: "stepper_decrement")
+ customStepper.setDecrementImage(stepperDecrementImage, for: .normal)
+
+ customStepperLabel.text = "\(Int(customStepper.value))"
+ customStepper.addTarget(self, action: #selector(StepperViewController.stepperValueDidChange(_:)), for: .valueChanged)
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func stepperValueDidChange(_ stepper: UIStepper) {
+ print("A stepper changed its value: \(stepper).")
+
+ // A mapping from a stepper to its associated label.
+ let stepperMapping = [
+ defaultStepper: defaultStepperLabel,
+ tintedStepper: tintedStepperLabel,
+ customStepper: customStepperLabel
+ ]
+
+ stepperMapping[stepper]!?.text = "\(Int(stepper.value))"
+ }
+}
diff --git a/UIKitCatalog/SwitchViewController.swift b/UIKitCatalog/SwitchViewController.swift
new file mode 100644
index 0000000..5574121
--- /dev/null
+++ b/UIKitCatalog/SwitchViewController.swift
@@ -0,0 +1,48 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UISwitch`.
+*/
+
+import UIKit
+
+class SwitchViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var defaultSwitch: UISwitch!
+
+ @IBOutlet weak var tintedSwitch: UISwitch!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureDefaultSwitch()
+ configureTintedSwitch()
+ }
+
+ // MARK: - Configuration
+
+ func configureDefaultSwitch() {
+ defaultSwitch.setOn(true, animated: false)
+
+ defaultSwitch.addTarget(self, action: #selector(SwitchViewController.switchValueDidChange(_:)), for: .valueChanged)
+ }
+
+ func configureTintedSwitch() {
+ tintedSwitch.tintColor = UIColor(named: "Tint_Blue_Color")
+ tintedSwitch.onTintColor = UIColor(named: "Tint_Green_Color")
+ tintedSwitch.thumbTintColor = UIColor(named: "Tint_Purple_Color")
+
+ tintedSwitch.addTarget(self, action: #selector(SwitchViewController.switchValueDidChange(_:)), for: .valueChanged)
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func switchValueDidChange(_ aSwitch: UISwitch) {
+ print("A switch changed its value: \(aSwitch).")
+ }
+}
diff --git a/UIKitCatalog/TextFieldViewController.swift b/UIKitCatalog/TextFieldViewController.swift
new file mode 100644
index 0000000..7764085
--- /dev/null
+++ b/UIKitCatalog/TextFieldViewController.swift
@@ -0,0 +1,117 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UITextField`.
+*/
+
+import UIKit
+
+class TextFieldViewController: UITableViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var textField: UITextField!
+
+ @IBOutlet weak var tintedTextField: UITextField!
+
+ @IBOutlet weak var secureTextField: UITextField!
+
+ @IBOutlet weak var specificKeyboardTextField: UITextField!
+
+ @IBOutlet weak var customTextField: UITextField!
+
+ // MARK: View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureTextField()
+ configureTintedTextField()
+ configureSecureTextField()
+ configureSpecificKeyboardTextField()
+ configureCustomTextField()
+ }
+
+ // MARK: - Configuration
+
+ func configureTextField() {
+ textField.placeholder = NSLocalizedString("Placeholder text", comment: "")
+ textField.autocorrectionType = .yes
+ textField.returnKeyType = .done
+ textField.clearButtonMode = .never
+ }
+
+ func configureTintedTextField() {
+ tintedTextField.tintColor = UIColor(named: "Tint_Blue_Color")
+ tintedTextField.textColor = UIColor(named: "Tint_Green_Color")
+
+ tintedTextField.placeholder = NSLocalizedString("Placeholder text", comment: "")
+ tintedTextField.returnKeyType = .done
+ tintedTextField.clearButtonMode = .never
+ }
+
+ func configureSecureTextField() {
+ secureTextField.isSecureTextEntry = true
+
+ secureTextField.placeholder = NSLocalizedString("Placeholder text", comment: "")
+ secureTextField.returnKeyType = .done
+ secureTextField.clearButtonMode = .always
+ }
+
+ /** There are many different types of keyboards that you may choose to use.
+ The different types of keyboards are defined in the `UITextInputTraits` interface.
+ This example shows how to display a keyboard to help enter email addresses.
+ */
+ func configureSpecificKeyboardTextField() {
+ specificKeyboardTextField.keyboardType = .emailAddress
+
+ specificKeyboardTextField.placeholder = NSLocalizedString("Placeholder text", comment: "")
+ specificKeyboardTextField.returnKeyType = .done
+ }
+
+ func configureCustomTextField() {
+ // Text fields with custom image backgrounds must have no border.
+ customTextField.borderStyle = .none
+
+ customTextField.background = UIImage(named: "text_field_background")
+
+ // Create a purple button that, when selected, turns the custom text field's text color to purple.
+ let purpleImage = UIImage(named: "text_field_purple_right_view")!
+ let purpleImageButton = UIButton(type: .custom)
+ purpleImageButton.bounds = CGRect(x: 0, y: 0, width: purpleImage.size.width, height: purpleImage.size.height)
+ purpleImageButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 5)
+ purpleImageButton.setImage(purpleImage, for: .normal)
+ purpleImageButton.addTarget(self, action: #selector(TextFieldViewController.customTextFieldPurpleButtonClicked), for: .touchUpInside)
+ customTextField.rightView = purpleImageButton
+ customTextField.rightViewMode = .always
+
+ // Add an empty view as the left view to ensure the proper inset between the text and the bounding rectangle.
+ let leftPaddingView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 0))
+ leftPaddingView.backgroundColor = UIColor.clear
+ customTextField.leftView = leftPaddingView
+ customTextField.leftViewMode = .always
+
+ customTextField.placeholder = NSLocalizedString("Placeholder text", comment: "")
+ customTextField.autocorrectionType = .no
+ customTextField.returnKeyType = .done
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func customTextFieldPurpleButtonClicked() {
+ customTextField.textColor = UIColor(named: "Tint_Purple_Color")
+
+ print("The custom text field's purple right view button was clicked.")
+ }
+}
+
+// MARK: - UITextFieldDelegate
+
+extension TextFieldViewController: UITextFieldDelegate {
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return true
+ }
+
+}
diff --git a/UIKitCatalog/TextViewController.swift b/UIKitCatalog/TextViewController.swift
new file mode 100644
index 0000000..b905d88
--- /dev/null
+++ b/UIKitCatalog/TextViewController.swift
@@ -0,0 +1,175 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `UITextView`.
+*/
+
+import UIKit
+
+class TextViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var textView: UITextView!
+
+ /// Used to adjust the text view's height when the keyboard hides and shows.
+ @IBOutlet weak var textViewBottomLayoutGuideConstraint: NSLayoutConstraint!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ configureTextView()
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+
+ // Listen for changes to keyboard visibility so that we can adjust the text view's height accordingly.
+ let notificationCenter = NotificationCenter.default
+
+ notificationCenter.addObserver(self,
+ selector: #selector(TextViewController.handleKeyboardNotification(_:)),
+ name: NSNotification.Name.UIKeyboardWillShow,
+ object: nil)
+
+ notificationCenter.addObserver(self,
+ selector: #selector(TextViewController.handleKeyboardNotification(_:)),
+ name: NSNotification.Name.UIKeyboardWillHide,
+ object: nil)
+ }
+
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+
+ let notificationCenter = NotificationCenter.default
+ notificationCenter.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
+ notificationCenter.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
+ }
+
+ // MARK: - Keyboard Event Notifications
+
+ @objc
+ func handleKeyboardNotification(_ notification: Notification) {
+ let userInfo = notification.userInfo!
+
+ // Get the animation duration.
+ var animationDuration: TimeInterval = 0
+ if let value = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber {
+ animationDuration = value.doubleValue
+ }
+
+ // Convert the keyboard frame from screen to view coordinates.
+ var keyboardScreenBeginFrame = CGRect()
+ if let value = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue) {
+ keyboardScreenBeginFrame = value.cgRectValue
+ }
+
+ var keyboardScreenEndFrame = CGRect()
+ if let value = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue) {
+ keyboardScreenEndFrame = value.cgRectValue
+ }
+
+ let keyboardViewBeginFrame = view.convert(keyboardScreenBeginFrame, from: view.window)
+ let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
+
+ let originDelta = keyboardViewEndFrame.origin.y - keyboardViewBeginFrame.origin.y
+
+ // The text view should be adjusted, update the constant for this constraint.
+ textViewBottomLayoutGuideConstraint.constant -= originDelta
+
+ // Inform the view that its autolayout constraints have changed and the layout should be updated.
+ view.setNeedsUpdateConstraints()
+
+ // Animate updating the view's layout by calling layoutIfNeeded inside a `UIViewPropertyAnimator` animation block.
+ let textViewAnimator = UIViewPropertyAnimator(duration: animationDuration, curve: .easeIn, animations: { [weak self] in
+ self?.view.layoutIfNeeded()
+ })
+ textViewAnimator.startAnimation()
+
+ // Scroll to the selected text once the keyboard frame changes.
+ let selectedRange = textView.selectedRange
+ textView.scrollRangeToVisible(selectedRange)
+ }
+
+ // MARK: - Configuration
+
+ func configureTextView() {
+ let bodyFontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: UIFontTextStyle.body)
+ let bodyFont = UIFont(descriptor: bodyFontDescriptor, size: 0)
+
+ textView.font = bodyFont
+ textView.textColor = UIColor.black
+ textView.backgroundColor = UIColor.white
+ textView.isScrollEnabled = true
+
+ /** Let's modify some of the attributes of the attributed string.
+ You can modify these attributes yourself to get a better feel for what they do.
+ Note that the initial text is visible in the storyboard.
+ */
+ let attributedText = NSMutableAttributedString(attributedString: textView.attributedText!)
+
+ /** Use NSString so the result of rangeOfString is an NSRange, not Range.
+ This will then be the correct type to then pass to the addAttribute method of NSMutableAttributedString.
+ */
+ let text = textView.text! as NSString
+
+ // Find the range of each element to modify.
+ let boldRange = text.range(of: NSLocalizedString("bold", comment: ""))
+ let highlightedRange = text.range(of: NSLocalizedString("highlighted", comment: ""))
+ let underlinedRange = text.range(of: NSLocalizedString("underlined", comment: ""))
+ let tintedRange = text.range(of: NSLocalizedString("tinted", comment: ""))
+
+ /** Add bold attribute. Take the current font descriptor and create a new font descriptor
+ with an additional bold trait.
+ */
+ let boldFontDescriptor = textView.font!.fontDescriptor.withSymbolicTraits(.traitBold)
+ let boldFont = UIFont(descriptor: boldFontDescriptor!, size: 0)
+ attributedText.addAttribute(NSAttributedStringKey.font, value: boldFont, range: boldRange)
+
+ // Add highlight attribute.
+ attributedText.addAttribute(NSAttributedStringKey.backgroundColor, value: UIColor(named: "Tint_Green_Color")!, range: highlightedRange)
+
+ // Add underline attribute.
+ attributedText.addAttribute(NSAttributedStringKey.underlineStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: underlinedRange)
+
+ // Add tint color.
+ attributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor(named: "Tint_Blue_Color")!, range: tintedRange)
+
+ // Add the image as an attachment.
+ let textAttachment = NSTextAttachment()
+ let image = #imageLiteral(resourceName: "text_view_attachment")
+ textAttachment.image = image
+ textAttachment.bounds = CGRect(origin: CGPoint.zero, size: image.size)
+
+ let textAttachmentString = NSAttributedString(attachment: textAttachment)
+ attributedText.append(textAttachmentString)
+
+ textView.attributedText = attributedText
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func doneBarButtonItemClicked() {
+ // Dismiss the keyboard by removing it as the first responder.
+ textView.resignFirstResponder()
+
+ navigationItem.setRightBarButton(nil, animated: true)
+ }
+}
+
+// MARK: - UITextViewDelegate
+
+extension TextViewController: UITextViewDelegate {
+ func textViewDidBeginEditing(_ textView: UITextView) {
+ // Provide a "Done" button for the user to end text editing.
+ let doneBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done,
+ target: self,
+ action: #selector(TextViewController.doneBarButtonItemClicked))
+
+ navigationItem.setRightBarButton(doneBarButtonItem, animated: true)
+ }
+
+}
diff --git a/UIKitCatalog/TintedToolbarViewController.swift b/UIKitCatalog/TintedToolbarViewController.swift
new file mode 100644
index 0000000..76c3775
--- /dev/null
+++ b/UIKitCatalog/TintedToolbarViewController.swift
@@ -0,0 +1,62 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to customize a `UIToolbar`.
+*/
+
+import UIKit
+
+class TintedToolbarViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var toolbar: UIToolbar!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // See the `UIBarStyle` enum for more styles, including `.Default`.
+ toolbar.barStyle = .black
+ toolbar.isTranslucent = true
+
+ toolbar.tintColor = UIColor(named: "Tint_Green_Color")
+ toolbar.backgroundColor = UIColor(named: "Tint_Blue_Color")
+
+ let toolbarButtonItems = [
+ refreshBarButtonItem,
+ flexibleSpaceBarButtonItem,
+ actionBarButtonItem
+ ]
+ toolbar.setItems(toolbarButtonItems, animated: true)
+ }
+
+ // MARK: - `UIBarButtonItem` Creation and Configuration
+
+ var refreshBarButtonItem: UIBarButtonItem {
+ return UIBarButtonItem(barButtonSystemItem: .refresh,
+ target: self,
+ action: #selector(TintedToolbarViewController.barButtonItemClicked(_:)))
+ }
+
+ var flexibleSpaceBarButtonItem: UIBarButtonItem {
+ // Note that there's no target/action since this represents empty space.
+ return UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
+ target: nil,
+ action: nil)
+ }
+
+ var actionBarButtonItem: UIBarButtonItem {
+ return UIBarButtonItem(barButtonSystemItem: .action,
+ target: self,
+ action: #selector(TintedToolbarViewController.barButtonItemClicked(_:)))
+ }
+
+ // MARK: - Actions
+
+ @objc
+ func barButtonItemClicked(_ barButtonItem: UIBarButtonItem) {
+ print("A bar button item on the tinted toolbar was clicked: \(barButtonItem).")
+ }
+}
diff --git a/UIKitCatalog/ToolbarsTableViewController.swift b/UIKitCatalog/ToolbarsTableViewController.swift
new file mode 100644
index 0000000..5938e8d
--- /dev/null
+++ b/UIKitCatalog/ToolbarsTableViewController.swift
@@ -0,0 +1,31 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Table view controller for presenting various `UIToolbars`.
+*/
+
+import UIKit
+
+class ToolbarsTableViewController: BaseTableViewController {
+ // MARK: - UITableViewDelegate
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ var storyboardSceneID = String()
+ switch indexPath.row {
+ case 0:
+ // Default
+ storyboardSceneID = "DefaultToolbarViewController"
+ case 1:
+ // Tinted
+ storyboardSceneID = "TintedToolbarViewController"
+ case 2:
+ // Custom
+ storyboardSceneID = "CustomToolbarViewController"
+ default: break
+ }
+
+ let exampleViewController = storyboard?.instantiateViewController(withIdentifier: storyboardSceneID)
+ pushOrPresentViewController(viewController: exampleViewController!, cellIndexPath: indexPath)
+ }
+}
diff --git a/UIKitCatalog/UIKitCatalog-Info.plist b/UIKitCatalog/UIKitCatalog-Info.plist
new file mode 100644
index 0000000..a9abe34
--- /dev/null
+++ b/UIKitCatalog/UIKitCatalog-Info.plist
@@ -0,0 +1,47 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIdentifier
+ ${PRODUCT_BUNDLE_IDENTIFIER}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 14
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/UIKitCatalog/UIViewController+SizeChange.swift b/UIKitCatalog/UIViewController+SizeChange.swift
new file mode 100644
index 0000000..9febe10
--- /dev/null
+++ b/UIKitCatalog/UIViewController+SizeChange.swift
@@ -0,0 +1,21 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+Extension for any view controller that wants to pop itself from the nav stack, if transitioned
+ to compact mode on the iPhone.
+*/
+
+import UIKit
+
+extension UIViewController {
+ func popDueToSizeChange() {
+ /** This view controller was pushed in a table view while in the split view controller's
+ master table, upon rotation to expand, we want to pop this view controller (to avoid
+ master and detail being the same view controller).
+ */
+ if navigationController != nil {
+ navigationController?.popViewController(animated: true)
+ }
+ }
+}
diff --git a/UIKitCatalog/WebViewController.swift b/UIKitCatalog/WebViewController.swift
new file mode 100644
index 0000000..4ad704a
--- /dev/null
+++ b/UIKitCatalog/WebViewController.swift
@@ -0,0 +1,59 @@
+/*
+See LICENSE folder for this sample’s licensing information.
+
+Abstract:
+A view controller that demonstrates how to use `WKWebView`.
+*/
+
+import UIKit
+import WebKit
+
+/** NOTE:
+ If your app customizes, interacts with, or controls the display of web content, use the WKWebView class.
+ If you want to view a website from anywhere on the Internet, use the SFSafariViewController class.
+ */
+
+class WebViewController: UIViewController {
+ // MARK: - Properties
+
+ @IBOutlet weak var webView: WKWebView!
+
+ // MARK: - View Life Cycle
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // So we can capture failures in "didFailProvisionalNavigation".
+ webView.navigationDelegate = self
+ loadAddressURL()
+ }
+
+ // MARK: - Loading
+
+ func loadAddressURL() {
+ // Set the content to local html in our app bundle.
+ if let url = Bundle.main.url(forResource: "content", withExtension: "html") {
+ webView.loadFileURL(url, allowingReadAccessTo: url)
+ }
+ }
+
+}
+
+// MARK: - WKNavigationDelegate
+
+extension WebViewController: WKNavigationDelegate {
+ func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
+ let webKitError = error as NSError
+ if webKitError.code == NSURLErrorNotConnectedToInternet {
+ // Report the error inside the web view.
+ let localizedErrorMessage = NSLocalizedString("An error occurred:", comment: "")
+
+ let message = "\(localizedErrorMessage) \(error.localizedDescription)"
+ let errorHTML =
+ "\(message)
"
+
+ webView.loadHTMLString(errorHTML, baseURL: nil)
+ }
+ }
+
+}