Skip to content

Commit 017e452

Browse files
committed
Move to new observation API in Swift 4
1 parent 2b4b003 commit 017e452

File tree

3 files changed

+30
-51
lines changed

3 files changed

+30
-51
lines changed

PullToRefresh.xcodeproj/project.pbxproj

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -301,16 +301,16 @@
301301
TargetAttributes = {
302302
C7AC6CCB19A7FE6D007107DF = {
303303
CreatedOnToolsVersion = 6.0;
304-
LastSwiftMigration = 0800;
304+
LastSwiftMigration = 0900;
305305
};
306306
C7AC6CD519A7FE6D007107DF = {
307307
CreatedOnToolsVersion = 6.0;
308-
LastSwiftMigration = 0800;
308+
LastSwiftMigration = 0900;
309309
TestTargetID = C7D1CF8E199BB3C8009FD485;
310310
};
311311
C7D1CF8E199BB3C8009FD485 = {
312312
CreatedOnToolsVersion = 6.0;
313-
LastSwiftMigration = 0800;
313+
LastSwiftMigration = 0900;
314314
};
315315
};
316316
};
@@ -451,7 +451,7 @@
451451
PRODUCT_NAME = "$(TARGET_NAME)";
452452
SKIP_INSTALL = YES;
453453
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
454-
SWIFT_VERSION = 3.0;
454+
SWIFT_VERSION = 4.0;
455455
VERSIONING_SYSTEM = "apple-generic";
456456
VERSION_INFO_PREFIX = "";
457457
};
@@ -473,7 +473,7 @@
473473
PRODUCT_BUNDLE_IDENTIFIER = "JCA.$(PRODUCT_NAME:rfc1034identifier)";
474474
PRODUCT_NAME = "$(TARGET_NAME)";
475475
SKIP_INSTALL = YES;
476-
SWIFT_VERSION = 3.0;
476+
SWIFT_VERSION = 4.0;
477477
VERSIONING_SYSTEM = "apple-generic";
478478
VERSION_INFO_PREFIX = "";
479479
};
@@ -494,7 +494,7 @@
494494
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
495495
PRODUCT_BUNDLE_IDENTIFIER = "JCA.$(PRODUCT_NAME:rfc1034identifier)";
496496
PRODUCT_NAME = "$(TARGET_NAME)";
497-
SWIFT_VERSION = 3.0;
497+
SWIFT_VERSION = 4.0;
498498
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PullToRefreshDemo.app/PullToRefreshDemo";
499499
};
500500
name = Debug;
@@ -510,7 +510,7 @@
510510
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
511511
PRODUCT_BUNDLE_IDENTIFIER = "JCA.$(PRODUCT_NAME:rfc1034identifier)";
512512
PRODUCT_NAME = "$(TARGET_NAME)";
513-
SWIFT_VERSION = 3.0;
513+
SWIFT_VERSION = 4.0;
514514
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PullToRefreshDemo.app/PullToRefreshDemo";
515515
};
516516
name = Release;
@@ -624,7 +624,7 @@
624624
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
625625
PRODUCT_BUNDLE_IDENTIFIER = "JCA.${PRODUCT_NAME:rfc1034identifier}";
626626
PRODUCT_NAME = "$(TARGET_NAME)";
627-
SWIFT_VERSION = 3.0;
627+
SWIFT_VERSION = 4.0;
628628
};
629629
name = Debug;
630630
};
@@ -638,7 +638,7 @@
638638
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
639639
PRODUCT_BUNDLE_IDENTIFIER = "JCA.${PRODUCT_NAME:rfc1034identifier}";
640640
PRODUCT_NAME = "$(TARGET_NAME)";
641-
SWIFT_VERSION = 3.0;
641+
SWIFT_VERSION = 4.0;
642642
};
643643
name = Release;
644644
};

PullToRefreshDemo/PullToRefreshViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ class PullToRefreshViewController: UIViewController {
9393
// Dispose of any resources that can be recreated.
9494
}
9595

96-
func tableView(_ tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
96+
@objc func tableView(_ tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
9797
return 50
9898
}
9999

100-
func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: IndexPath!) -> UITableViewCell! {
100+
@objc func tableView(_ tableView: UITableView!, cellForRowAtIndexPath indexPath: IndexPath!) -> UITableViewCell! {
101101
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
102102
cell.textLabel?.text = "Row " + String(indexPath.row + 1)
103103
return cell

Refresher/PullToRefreshView.swift

Lines changed: 19 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
import UIKit
2525
import QuartzCore
2626

27-
private var KVOContext = "RefresherKVOContext"
28-
private let ContentOffsetKeyPath = "contentOffset"
29-
3027
public enum PullToRefreshViewState {
3128

3229
case loading
@@ -43,7 +40,7 @@ public protocol PullToRefreshViewDelegate {
4340
}
4441

4542
open class PullToRefreshView: UIView {
46-
43+
private var observation: NSKeyValueObservation?
4744
private var scrollViewBouncesDefaultValue: Bool = false
4845
private var scrollViewInsetsDefaultValue: UIEdgeInsets = UIEdgeInsets.zero
4946

@@ -101,51 +98,33 @@ open class PullToRefreshView: UIView {
10198
// Currently it is not supported to load view from nib
10299
}
103100

104-
deinit {
105-
let scrollView = superview as? UIScrollView
106-
scrollView?.removeObserver(self, forKeyPath: ContentOffsetKeyPath, context: &KVOContext)
107-
}
108-
109101

110102
//MARK: UIView methods
111103

112104
open override func willMove(toSuperview newSuperview: UIView!) {
113-
superview?.removeObserver(self, forKeyPath: ContentOffsetKeyPath, context: &KVOContext)
105+
self.observation?.invalidate()
114106
if let scrollView = newSuperview as? UIScrollView {
115-
scrollView.addObserver(self, forKeyPath: ContentOffsetKeyPath, options: .initial, context: &KVOContext)
116-
scrollViewBouncesDefaultValue = scrollView.bounces
117-
scrollViewInsetsDefaultValue = scrollView.contentInset
118-
}
119-
}
120-
121-
122-
//MARK: KVO methods
123-
124-
open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
125-
if (context == &KVOContext) {
126-
if let scrollView = superview as? UIScrollView , object as? NSObject == scrollView {
127-
if keyPath == ContentOffsetKeyPath {
128-
let offsetWithoutInsets = previousOffset + scrollViewInsetsDefaultValue.top
129-
if (offsetWithoutInsets < -self.frame.size.height) {
130-
if (scrollView.isDragging == false && loading == false) {
131-
loading = true
132-
} else if (loading) {
133-
self.animator.pullToRefresh(self, stateDidChange: .loading)
134-
} else {
135-
self.animator.pullToRefresh(self, stateDidChange: .releaseToRefresh)
136-
animator.pullToRefresh(self, progressDidChange: -offsetWithoutInsets / self.frame.size.height)
137-
}
138-
} else if (loading) {
107+
self.observation = scrollView.observe(\.contentOffset, options: [.initial]) { [unowned self] (scrollView, change) in
108+
let offsetWithoutInsets = self.previousOffset + self.scrollViewInsetsDefaultValue.top
109+
if (offsetWithoutInsets < -self.frame.size.height) {
110+
if (scrollView.isDragging == false && self.loading == false) {
111+
self.loading = true
112+
} else if (self.loading) {
139113
self.animator.pullToRefresh(self, stateDidChange: .loading)
140-
} else if (offsetWithoutInsets < 0) {
141-
self.animator.pullToRefresh(self, stateDidChange: .pullToRefresh)
142-
animator.pullToRefresh(self, progressDidChange: -offsetWithoutInsets / self.frame.size.height)
114+
} else {
115+
self.animator.pullToRefresh(self, stateDidChange: .releaseToRefresh)
116+
self.animator.pullToRefresh(self, progressDidChange: -offsetWithoutInsets / self.frame.size.height)
143117
}
144-
previousOffset = scrollView.contentOffset.y
118+
} else if (self.loading) {
119+
self.animator.pullToRefresh(self, stateDidChange: .loading)
120+
} else if (offsetWithoutInsets < 0) {
121+
self.animator.pullToRefresh(self, stateDidChange: .pullToRefresh)
122+
self.animator.pullToRefresh(self, progressDidChange: -offsetWithoutInsets / self.frame.size.height)
145123
}
124+
self.previousOffset = scrollView.contentOffset.y
146125
}
147-
} else {
148-
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
126+
scrollViewBouncesDefaultValue = scrollView.bounces
127+
scrollViewInsetsDefaultValue = scrollView.contentInset
149128
}
150129
}
151130

0 commit comments

Comments
 (0)