diff --git a/MRGTaylor.podspec b/MRGTaylor.podspec index ce95eb4..9ad0231 100644 --- a/MRGTaylor.podspec +++ b/MRGTaylor.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| # s.name = "MRGTaylor" - s.version = "1.3.4" + s.version = "1.4.0" s.summary = "A short description of Taylor." # This description is used to generate tags and improve search results. diff --git a/Taylor.xcodeproj/project.pbxproj b/Taylor.xcodeproj/project.pbxproj index 5a74b93..bb471c2 100644 --- a/Taylor.xcodeproj/project.pbxproj +++ b/Taylor.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ 7A44D0631C187E030063575B /* Taylor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A44D0581C187E030063575B /* Taylor.framework */; }; 7ACD09751CBFC641000FAAA0 /* ExtendedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD09741CBFC641000FAAA0 /* ExtendedButton.swift */; }; 7ACD098F1CC04264000FAAA0 /* ExtendedButtonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD098E1CC04264000FAAA0 /* ExtendedButtonTests.swift */; }; + C82DD1D81FE414B0002C3942 /* CGPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DD1D71FE414B0002C3942 /* CGPoint.swift */; }; + C82DD1DA1FE41FB1002C3942 /* UIViewControllerContainer+StatusBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DD1D91FE41FB1002C3942 /* UIViewControllerContainer+StatusBar.swift */; }; + C82DD1DC1FE42012002C3942 /* UIControl+Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82DD1DB1FE42012002C3942 /* UIControl+Actions.swift */; }; DF42A5A81D3EB07A00C2FE9B /* NSDateTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF42A5A71D3EB07A00C2FE9B /* NSDateTest.swift */; }; DF45FE9D1CCFD1F90033F071 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF45FE9C1CCFD1F90033F071 /* String.swift */; }; DF9AE4C71DD0C1EE0061B155 /* CGFloatText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF9AE4C61DD0C1EE0061B155 /* CGFloatText.swift */; }; @@ -55,6 +58,9 @@ 7A44D0691C187E030063575B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 7ACD09741CBFC641000FAAA0 /* ExtendedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtendedButton.swift; sourceTree = ""; }; 7ACD098E1CC04264000FAAA0 /* ExtendedButtonTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtendedButtonTests.swift; sourceTree = ""; }; + C82DD1D71FE414B0002C3942 /* CGPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGPoint.swift; sourceTree = ""; }; + C82DD1D91FE41FB1002C3942 /* UIViewControllerContainer+StatusBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewControllerContainer+StatusBar.swift"; sourceTree = ""; }; + C82DD1DB1FE42012002C3942 /* UIControl+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIControl+Actions.swift"; sourceTree = ""; }; DF42A5A71D3EB07A00C2FE9B /* NSDateTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDateTest.swift; sourceTree = ""; }; DF45FE9C1CCFD1F90033F071 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; DF9AE4C61DD0C1EE0061B155 /* CGFloatText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CGFloatText.swift; path = Types/CGFloatText.swift; sourceTree = ""; }; @@ -165,6 +171,8 @@ DFBC07AA1CAC399700A7A665 /* UILabel.swift */, DFBC07AB1CAC399700A7A665 /* UIScreen.swift */, DFBFDA421CAF0B0900623836 /* UIView.swift */, + C82DD1D91FE41FB1002C3942 /* UIViewControllerContainer+StatusBar.swift */, + C82DD1DB1FE42012002C3942 /* UIControl+Actions.swift */, ); path = UI; sourceTree = ""; @@ -182,6 +190,7 @@ children = ( DFBC079F1CAC399700A7A665 /* CGRect.swift */, DFBC07A01CAC399700A7A665 /* CGSize.swift */, + C82DD1D71FE414B0002C3942 /* CGPoint.swift */, ); path = Geometry; sourceTree = ""; @@ -309,7 +318,9 @@ DFBC07B61CAC399700A7A665 /* UIDevice.swift in Sources */, 7ACD09751CBFC641000FAAA0 /* ExtendedButton.swift in Sources */, 7A3FC2B11CAC2ACC007A4063 /* UIEdgeInsets.swift in Sources */, + C82DD1DA1FE41FB1002C3942 /* UIViewControllerContainer+StatusBar.swift in Sources */, DFBC07AE1CAC399700A7A665 /* CGSize.swift in Sources */, + C82DD1D81FE414B0002C3942 /* CGPoint.swift in Sources */, DFBC07B21CAC399700A7A665 /* NSDate.swift in Sources */, DFBC07AD1CAC399700A7A665 /* CGRect.swift in Sources */, DFBC07B01CAC399700A7A665 /* Double.swift in Sources */, @@ -317,6 +328,7 @@ DFBC07B41CAC399700A7A665 /* UIButton.swift in Sources */, DF9F948B1CE35EF40008487F /* UIImage.swift in Sources */, DFBFDA3F1CAEF4B600623836 /* Int.swift in Sources */, + C82DD1DC1FE42012002C3942 /* UIControl+Actions.swift in Sources */, DFC8727F1DCFB8790007AE43 /* CGFloat.swift in Sources */, DFBC07B71CAC399700A7A665 /* UIImageView.swift in Sources */, DFBC07B91CAC399700A7A665 /* UIScreen.swift in Sources */, diff --git a/Taylor/Geometry/CGPoint.swift b/Taylor/Geometry/CGPoint.swift new file mode 100644 index 0000000..a9a51a2 --- /dev/null +++ b/Taylor/Geometry/CGPoint.swift @@ -0,0 +1,66 @@ +// Copyright (c) 2017, Mirego +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// - Neither the name of the Mirego nor the names of its contributors may +// be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +import Foundation + +func + (left: CGPoint, right: CGPoint) -> CGPoint { + return CGPoint(x: left.x + right.x, y: left.y + right.y) +} + +func += (left: inout CGPoint, right: CGPoint) { + left = left + right +} + +extension CGPoint +{ + public mutating func round() { + x = Darwin.round(x) + y = Darwin.round(y) + } + + public func rounded() -> CGPoint { + return CGPoint(x: Darwin.round(x), y: Darwin.round(y)) + } + + public mutating func floor() { + x = Darwin.floor(x) + y = Darwin.floor(y) + } + + public func floored() -> CGPoint { + return CGPoint(x: Darwin.floor(x), y: Darwin.floor(y)) + } + + public mutating func ceil() { + x = Darwin.ceil(x) + y = Darwin.ceil(y) + } + + public func ceiled() -> CGPoint { + return CGPoint(x: Darwin.ceil(x), y: Darwin.ceil(y)) + } +} diff --git a/Taylor/Geometry/CGRect.swift b/Taylor/Geometry/CGRect.swift index 1a9d73a..31be3fc 100644 --- a/Taylor/Geometry/CGRect.swift +++ b/Taylor/Geometry/CGRect.swift @@ -52,6 +52,30 @@ extension CGRect return origin.y } } + + mutating func roundSize() { + size.round() + } + + mutating func floorSize() { + size.floor() + } + + mutating func ceilSize() { + size.ceil() + } + + mutating func roundOrigin() { + origin.round() + } + + mutating func floorOrigin() { + origin.floor() + } + + mutating func ceilOrigin() { + origin.ceil() + } } // swiftlint:enable variable_name diff --git a/Taylor/Geometry/CGSize.swift b/Taylor/Geometry/CGSize.swift index 968eac5..ae273d6 100644 --- a/Taylor/Geometry/CGSize.swift +++ b/Taylor/Geometry/CGSize.swift @@ -27,20 +27,58 @@ import Foundation +func + (left: CGSize, right: CGSize) -> CGSize { + return CGSize(width: left.width + right.width, height: left.height + right.height) +} + +func += (left: inout CGSize, right: CGSize) { + left = left + right +} + extension CGSize { - public func inset(_ xOffset: CGFloat, yOffset: CGFloat) -> CGSize - { + @available(*, deprecated, message: "This function was not performing an inset operation but had the effect of adding values to its components, you should use the + operator on two CGSize as a direct replacement. To perform a real inset operation, use insetBy provided by CoreGraphics.") + public func inset(_ xOffset: CGFloat, yOffset: CGFloat) -> CGSize { return CGSize(width: self.width + xOffset, height: self.height + yOffset) } - public func scale(_ xOffset: CGFloat, yOffset: CGFloat) -> CGSize - { + @available(*, deprecated, message: "Use scaleBy instead of this function, its naming is more in line with naming conventions.") + public func scale(_ xOffset: CGFloat, yOffset: CGFloat) -> CGSize { return CGSize(width: self.width * xOffset, height: self.height * yOffset) } - static public func minimalTapableSize() -> CGSize - { + public func scaleBy(sx: CGFloat, sy: CGFloat) -> CGSize { + return CGSize(width: self.width * sx, height: self.height * sy) + } + + public mutating func round() { + width = Darwin.round(width) + height = Darwin.round(height) + } + + public func rounded() -> CGSize { + return CGSize(width: Darwin.round(width), height: Darwin.round(height)) + } + + public mutating func floor() { + width = Darwin.floor(width) + height = Darwin.floor(height) + } + + public func floored() -> CGSize { + return CGSize(width: Darwin.floor(width), height: Darwin.floor(height)) + } + + public mutating func ceil() { + width = Darwin.ceil(width) + height = Darwin.ceil(height) + } + + public func ceiled() -> CGSize { + return CGSize(width: Darwin.ceil(width), height: Darwin.ceil(height)) + } + + static public func minimalTapableSize() -> CGSize { return CGSize(width: 44, height: 44) } } diff --git a/Taylor/Info.plist b/Taylor/Info.plist index 4bbc96d..8bce5c7 100644 --- a/Taylor/Info.plist +++ b/Taylor/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.3 + 1.4.0 CFBundleSignature ???? CFBundleVersion diff --git a/Taylor/Types/String.swift b/Taylor/Types/String.swift index f9945cc..c5a691b 100644 --- a/Taylor/Types/String.swift +++ b/Taylor/Types/String.swift @@ -37,7 +37,7 @@ public extension String { do { let regex = try NSRegularExpression(pattern:regExp, options: caseSensitive ? [] : .caseInsensitive) - return regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSRange(location: 0, length: self.characters.count)) != nil + return regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSRange(location: 0, length: count)) != nil } catch { return false } @@ -69,8 +69,8 @@ public extension String /// ``` var capitalizedFirstLetter: String { - let first = String(characters.prefix(1)).capitalized(with: NSLocale.current) - let other = String(characters.dropFirst()) + let first = String(prefix(1)).capitalized(with: NSLocale.current) + let other = String(dropFirst()) return first + other } diff --git a/Taylor/UI/UIButton.swift b/Taylor/UI/UIButton.swift index 63748e0..682a502 100644 --- a/Taylor/UI/UIButton.swift +++ b/Taylor/UI/UIButton.swift @@ -122,4 +122,14 @@ extension UIButton setImage(image, for: state) sizeToFit() } + + /** + Sets the background color to use for the specified button state. + + - parameter color: The background color to use for the specified state + - parameter state: The state that uses the specified image. The values are described in UIControlState + */ + public func setBackgroundColor(_ color: UIColor?, for state: UIControlState) { + setBackgroundImage(UIImage.image(from: color), for: state) + } } diff --git a/Taylor/UI/UIColor.swift b/Taylor/UI/UIColor.swift index 84de25c..a0b8369 100644 --- a/Taylor/UI/UIColor.swift +++ b/Taylor/UI/UIColor.swift @@ -29,8 +29,69 @@ import UIKit extension UIColor { - static public func colorBetweenColors(startColor: UIColor, endColor: UIColor, percentage: CGFloat) -> UIColor - { + /// Create color from hexadecimal value with optional transparency. + /// parameter red: amount of red (between 0 and 1) + /// parameter green: amount of green (between 0 and 1) + /// parameter blue: amount of blue (between 0 and 1) + /// parameter transparency: optional transparency value (default is 1) + public convenience init?(red: Int, green: Int, blue: Int, transparency: CGFloat = 1) { + guard red >= 0 && red <= 255 else { return nil } + guard green >= 0 && green <= 255 else { return nil } + guard blue >= 0 && blue <= 255 else { return nil } + + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: trans) + } + + /// Create color from hexadecimal value with optional transparency. + /// parameter hex: hex Int (example: 0xDECEB5). + /// parameter transparency: optional transparency value (default is 1) + public convenience init?(hex: Int, transparency: CGFloat = 1) { + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + let red = (hex >> 16) & 0xff + let green = (hex >> 8) & 0xff + let blue = hex & 0xff + self.init(red: red, green: green, blue: blue, transparency: trans) + } + + /// Create Color from hexadecimal string with optional transparency (if applicable). + /// parameter hexString: hexadecimal string (examples: EDE7F6, 0xEDE7F6, #EDE7F6, #0ff, 0xF0F, ..). + /// parameter transparency: optional transparency value (default is 1) + public convenience init?(hexString: String, transparency: CGFloat = 1) { + var string = "" + if hexString.lowercased().hasPrefix("0x") { + string = hexString.replacingOccurrences(of: "0x", with: "") + } else if hexString.hasPrefix("#") { + string = hexString.replacingOccurrences(of: "#", with: "") + } else { + string = hexString + } + + if string.count == 3 { // convert hex to 6 digit format if in short format + var str = "" + string.forEach { str.append(String(repeating: String($0), count: 2)) } + string = str + } + + guard let hexValue = Int(string, radix: 16) else { return nil } + + var trans = transparency + if trans < 0 { trans = 0 } + if trans > 1 { trans = 1 } + + let red = (hexValue >> 16) & 0xff + let green = (hexValue >> 8) & 0xff + let blue = hexValue & 0xff + self.init(red: red, green: green, blue: blue, transparency: trans) + } + + static public func colorBetweenColors(startColor: UIColor, endColor: UIColor, percentage: CGFloat) -> UIColor { if percentage <= 0 { return startColor } else if percentage >= 1 { diff --git a/Taylor/UI/UIControl+Actions.swift b/Taylor/UI/UIControl+Actions.swift new file mode 100644 index 0000000..107fa64 --- /dev/null +++ b/Taylor/UI/UIControl+Actions.swift @@ -0,0 +1,63 @@ +// Copyright (c) 2016, Mirego +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// - Neither the name of the Mirego nor the names of its contributors may +// be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +import UIKit + +private class ActionTrampoline: NSObject { + private let action: (T) -> Void + + init(action: @escaping (T) -> Void) { + self.action = action + } + + @objc func performAction(sender: UIControl) { + action(sender as! T) + } +} + +private var UIControlActionAssociatedObjectKeys: [UInt: UnsafeMutablePointer] = [:] + +public protocol UIControlActionFunctionProtocol {} +extension UIControl: UIControlActionFunctionProtocol {} + +extension UIControlActionFunctionProtocol where Self: UIControl { + public func addAction(events: UIControlEvents, _ action: @escaping (Self) -> Void) { + let trampoline = ActionTrampoline(action: action) + addTarget(trampoline, action: #selector(trampoline.performAction(sender:)), for: events) + objc_setAssociatedObject(self, actionKey(forEvents: events), trampoline, .OBJC_ASSOCIATION_RETAIN) + } + + private func actionKey(forEvents events: UIControlEvents) -> UnsafeMutablePointer { + if let key = UIControlActionAssociatedObjectKeys[events.rawValue] { + return key + } else { + let key = UnsafeMutablePointer.allocate(capacity: 1) + UIControlActionAssociatedObjectKeys[events.rawValue] = key + return key + } + } +} diff --git a/Taylor/UI/UIImage.swift b/Taylor/UI/UIImage.swift index 880acca..7dc16d0 100644 --- a/Taylor/UI/UIImage.swift +++ b/Taylor/UI/UIImage.swift @@ -29,27 +29,32 @@ import UIKit extension UIImage { + @available(*, deprecated, message: "Use image(from: color) instead") + public class func imageWithTintColor(_ color: UIColor) -> UIImage? { + return UIImage.image(from: color) + } + /** Creates a new UIImage with the specified tint color. - parameter color: The image tint color - returns: New instance of UIImage */ - public class func imageWithTintColor(_ color: UIColor) -> UIImage? - { - let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0) - - UIGraphicsBeginImageContext(rect.size) + public class func image(from color: UIColor?) -> UIImage? { + if let color = color { + let rect = CGRect(origin: CGPoint.zero, size: CGSize(width: 1, height: 1)) - guard let context = UIGraphicsGetCurrentContext() else { return nil } + UIGraphicsBeginImageContext(rect.size) + guard let context = UIGraphicsGetCurrentContext() else { return nil } + context.setFillColor(color.cgColor) + context.fill(rect) - context.setFillColor(color.cgColor) - context.fill(rect) - - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() - return image + return image + } + return nil } /** @@ -58,8 +63,7 @@ extension UIImage - parameter color: The image tint color - returns: New instance of UIImage */ - public func imageWithTintColor(_ color: UIColor) -> UIImage? - { + public func imageWithTintColor(_ color: UIColor) -> UIImage? { let sourceImage = withRenderingMode(.alwaysTemplate) UIGraphicsBeginImageContextWithOptions(size, false, sourceImage.scale) diff --git a/Taylor/UI/UIViewControllerContainer+StatusBar.swift b/Taylor/UI/UIViewControllerContainer+StatusBar.swift new file mode 100644 index 0000000..f5f8b66 --- /dev/null +++ b/Taylor/UI/UIViewControllerContainer+StatusBar.swift @@ -0,0 +1,50 @@ +// Copyright (c) 2016, Mirego +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// - Neither the name of the Mirego nor the names of its contributors may +// be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +import UIKit + +// Provide an automatic way for UIViewController common containers to forward +// status bar appearance calls to their child. UIKit does not perform that +// forwarding automatically. + +extension UINavigationController { + open override var childViewControllerForStatusBarStyle: UIViewController? { + return self.topViewController + } +} + +extension UITabBarController { + open override var childViewControllerForStatusBarStyle: UIViewController? { + return self.selectedViewController + } +} + +extension UISplitViewController { + open override var childViewControllerForStatusBarStyle: UIViewController? { + return self.viewControllers.first + } +}