From d52139ba94b3d17e2af2b07ebaf3d88f6eb14528 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Tue, 18 Sep 2018 16:53:26 +0100 Subject: [PATCH 1/4] Restart animations when the layout changes --- SpringIndicator/SpringIndicator.swift | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/SpringIndicator/SpringIndicator.swift b/SpringIndicator/SpringIndicator.swift index 82b8359..ec14303 100644 --- a/SpringIndicator/SpringIndicator.swift +++ b/SpringIndicator/SpringIndicator.swift @@ -10,9 +10,6 @@ import UIKit @IBDesignable open class SpringIndicator: UIView { - deinit { - stop() - } let indicatorView: UIView fileprivate var pathLayer: CAShapeLayer? { @@ -65,15 +62,28 @@ open class SpringIndicator: UIView { backgroundColor = UIColor.clear } - + + deinit { + stop() + } + open override func draw(_ rect: CGRect) { super.draw(rect) - if animating { start(for: .begin) } } + open override func layoutSubviews() { + super.layoutSubviews() + restartAnimations() + } + + private func restartAnimations() { + stop() + start(for: .begin) + } + private func makeRotationPath(for process: AnimationProcess) -> UIBezierPath { let start = CGFloat(process.startAngle()) let end = CGFloat(Double.pi + Double.pi_2) + start From 3f6adebc00953ebd81f95f433899c1637088204f Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Tue, 18 Sep 2018 17:22:28 +0100 Subject: [PATCH 2/4] Update Example --- .gitignore | 1 + .../project.pbxproj | 2 + .../Base.lproj/Main.storyboard | 47 ++++++++++--------- .../ViewController.swift | 17 ++++++- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index b22f023..c879a0d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ DerivedData *.hmap *.ipa *.xcuserstate +IDEWorkspaceChecks.plist # CocoaPods # diff --git a/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj b/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj index 40a4abe..30bcd9d 100644 --- a/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj +++ b/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj @@ -437,6 +437,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = SpringIndicatorExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.kyoheiito.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -451,6 +452,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = SpringIndicatorExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.kyoheiito.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard b/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard index ca8c892..3b0d5e1 100644 --- a/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard +++ b/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -10,7 +14,7 @@ - + @@ -30,12 +34,12 @@ - + - - + + @@ -49,30 +53,30 @@ - + - + @@ -86,6 +90,7 @@ + @@ -96,18 +101,18 @@ - + - - + + - + @@ -132,15 +137,15 @@ - + - - + + - + diff --git a/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift b/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift index b44a22e..9a72664 100644 --- a/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift +++ b/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift @@ -13,12 +13,25 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - let defaultIndicator = SpringIndicator(frame: CGRect(x: 100, y: 100, width: 60, height: 60)) defaultIndicator.lineColors = [.red, .blue, .orange, .green] defaultIndicator.rotationDuration = 2 + defaultIndicator.translatesAutoresizingMaskIntoConstraints = false view.addSubview(defaultIndicator) + + let topAnchor: NSLayoutYAxisAnchor + if #available(iOS 11.0, *) { + topAnchor = view.safeAreaLayoutGuide.topAnchor + } else { + topAnchor = topLayoutGuide.topAnchor + } + + NSLayoutConstraint.activate([ + defaultIndicator.topAnchor.constraint(equalTo: topAnchor, constant: 40), + defaultIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor), + defaultIndicator.heightAnchor.constraint(equalToConstant: 40), + defaultIndicator.widthAnchor.constraint(equalToConstant: 40), + ]) defaultIndicator.start() let colorIndicator = SpringIndicator(frame: CGRect(x: 300, y: 100, width: 20, height: 20)) From 9a5357eda962c540829e8838ce3c92c991b1ee90 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Tue, 18 Sep 2018 18:11:15 +0100 Subject: [PATCH 3/4] fixup! Restart animations when the layout changes --- SpringIndicator/SpringIndicator.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SpringIndicator/SpringIndicator.swift b/SpringIndicator/SpringIndicator.swift index ec14303..ee6f19b 100644 --- a/SpringIndicator/SpringIndicator.swift +++ b/SpringIndicator/SpringIndicator.swift @@ -76,12 +76,14 @@ open class SpringIndicator: UIView { open override func layoutSubviews() { super.layoutSubviews() - restartAnimations() + restartAnimationsIfNeeded() } - private func restartAnimations() { - stop() - start(for: .begin) + private func restartAnimationsIfNeeded() { + if isSpinning { + stop() + start(for: .begin) + } } private func makeRotationPath(for process: AnimationProcess) -> UIBezierPath { From 9c66afd93453159c167b81168cde6eb68bb93326 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Tue, 18 Sep 2018 18:13:31 +0100 Subject: [PATCH 4/4] Remove some warnings --- SpringIndicator/RefreshIndicator.swift | 7 ++++--- .../project.pbxproj | 18 +++++++++++++++++- .../Base.lproj/Main.storyboard | 3 --- .../TableViewController.swift | 11 ++++++----- .../ViewController.swift | 5 ----- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/SpringIndicator/RefreshIndicator.swift b/SpringIndicator/RefreshIndicator.swift index dc70617..6bec677 100644 --- a/SpringIndicator/RefreshIndicator.swift +++ b/SpringIndicator/RefreshIndicator.swift @@ -9,9 +9,6 @@ import UIKit public class RefreshIndicator: UIControl { - deinit { - stopIndicatorAnimation() - } private let defaultContentHeight: CGFloat = 60 private var refreshContext = UInt8() @@ -45,6 +42,10 @@ public class RefreshIndicator: UIControl { setupIndicator() } + deinit { + stopIndicatorAnimation() + } + private func setupIndicator() { indicator.lineWidth = 2 indicator.rotationDuration = 1 diff --git a/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj b/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj index 30bcd9d..31b8c02 100644 --- a/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj +++ b/SpringIndicatorExample/SpringIndicatorExample.xcodeproj/project.pbxproj @@ -215,7 +215,7 @@ attributes = { LastSwiftMigration = 0700; LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = kyohei_ito; TargetAttributes = { C724B8B51AA8CC31006F0F00 = { @@ -354,14 +354,22 @@ 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; @@ -400,14 +408,22 @@ 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; diff --git a/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard b/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard index 3b0d5e1..a9bf132 100644 --- a/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard +++ b/SpringIndicatorExample/SpringIndicatorExample/Base.lproj/Main.storyboard @@ -49,9 +49,6 @@ - - - diff --git a/SpringIndicatorExample/SpringIndicatorExample/TableViewController.swift b/SpringIndicatorExample/SpringIndicatorExample/TableViewController.swift index 2aac91e..b0352ee 100644 --- a/SpringIndicatorExample/SpringIndicatorExample/TableViewController.swift +++ b/SpringIndicatorExample/SpringIndicatorExample/TableViewController.swift @@ -10,24 +10,25 @@ import UIKit import SpringIndicator class TableViewController: UIViewController { + @IBOutlet weak var tableView: UITableView! + let refreshControl = RefreshIndicator() let dataSourceList: [[String]] = [[Int](0..<20).map({ "section 0, cell \($0)" })] override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - tableView.dataSource = self tableView.delegate = self - + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") - + refreshControl.addTarget(self, action: #selector(TableViewController.onRefresh), for: .valueChanged) + tableView.addSubview(refreshControl) } - + @objc func onRefresh() { DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.refreshControl.endRefreshing() diff --git a/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift b/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift index 9a72664..1586296 100644 --- a/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift +++ b/SpringIndicatorExample/SpringIndicatorExample/ViewController.swift @@ -42,9 +42,4 @@ class ViewController: UIViewController { colorIndicator.start() } - override func didReceiveMemoryWarning() { - super.didReceiveMemoryWarning() - // Dispose of any resources that can be recreated. - } } -