Skip to content

Commit 4b81a3b

Browse files
author
Kristian Angyal
committed
Fixed a crash caused by KVO observer handling.
1 parent 19ac960 commit 4b81a3b

File tree

2 files changed

+36
-41
lines changed

2 files changed

+36
-41
lines changed

Example/Base.lproj/Main.storyboard

+8-8
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@
4545
<action selector="showGalleryImageViewer:" destination="BYZ-38-t0r" eventType="touchUpInside" id="a7r-FT-uUm"/>
4646
</connections>
4747
</button>
48-
<button opaque="NO" tag="5" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fd6-Vz-POJ">
49-
<rect key="frame" x="56" y="447" width="201" height="83"/>
50-
<state key="normal" backgroundImage="5"/>
51-
<connections>
52-
<action selector="showGalleryImageViewer:" destination="BYZ-38-t0r" eventType="touchUpInside" id="1YS-ou-fMt"/>
53-
</connections>
54-
</button>
5548
<button opaque="NO" tag="6" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Bne-tn-gLP">
5649
<rect key="frame" x="189" y="393" width="68" height="50"/>
5750
<state key="normal" backgroundImage="6"/>
@@ -85,13 +78,20 @@
8578
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
8679
<nil key="highlightedColor"/>
8780
</label>
88-
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WRv-58-cYl">
81+
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WRv-58-cYl">
8982
<rect key="frame" x="20" y="51" width="86" height="48"/>
9083
<state key="normal" backgroundImage="image_small"/>
9184
<connections>
9285
<action selector="showSingleImageViewer:" destination="BYZ-38-t0r" eventType="touchUpInside" id="kdW-lW-YeZ"/>
9386
</connections>
9487
</button>
88+
<button opaque="NO" tag="5" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fd6-Vz-POJ">
89+
<rect key="frame" x="35" y="445" width="201" height="83"/>
90+
<state key="normal" backgroundImage="5"/>
91+
<connections>
92+
<action selector="showGalleryImageViewer:" destination="BYZ-38-t0r" eventType="touchUpInside" id="1YS-ou-fMt"/>
93+
</connections>
94+
</button>
9595
</subviews>
9696
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
9797
</view>

ImageViewer/Source/ImageViewer/ImageViewer.swift

+28-33
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,10 @@ import AVFoundation
4242
public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewControllerTransitioningDelegate {
4343

4444
/// UI
45-
private var scrollView: UIScrollView!
46-
private var overlayView: UIView!
47-
private var closeButton: UIButton!
45+
private var scrollView = UIScrollView()
46+
private var overlayView = UIView()
47+
private var closeButton = UIButton()
4848
private var imageView = UIImageView()
49-
5049
private let displacedView: UIView
5150
private var applicationWindow: UIWindow? {
5251
return UIApplication.sharedApplication().delegate?.window?.flatMap { $0 }
@@ -71,7 +70,7 @@ public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewCo
7170
private let hideCloseButtonDuration = 0.05
7271
private let zoomDuration = 0.2
7372
private let thresholdVelocity: CGFloat = 1000 // Based on UX experiments
74-
private let cutOffVelocity: CGFloat = 1000000 // we need some sufficiently large number, nobody can swipe faster then that
73+
private let cutOffVelocity: CGFloat = 1000000 // we simply need some sufficiently large number, nobody can swipe faster than that
7574
/// TRANSITIONS
7675
private let presentTransition: ImageViewerPresentTransition
7776
private let dismissTransition: ImageViewerDismissTransition
@@ -101,6 +100,7 @@ public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewCo
101100
// MARK: - Deinit
102101

103102
deinit {
103+
104104
scrollView.removeObserver(self, forKeyPath: "contentOffset")
105105
}
106106

@@ -121,6 +121,11 @@ public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewCo
121121
transitioningDelegate = self
122122
modalPresentationStyle = .Custom
123123
extendedLayoutIncludesOpaqueBars = true
124+
125+
overlayView.autoresizingMask = [.None]
126+
configureCloseButton()
127+
configureImageView()
128+
configureScrollView()
124129
}
125130

126131
public required init?(coder aDecoder: NSCoder) {
@@ -136,6 +141,7 @@ public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewCo
136141
closeButton.setImage(closeButtonAssets.normal, forState: UIControlState.Normal)
137142
closeButton.setImage(closeButtonAssets.highlighted, forState: UIControlState.Highlighted)
138143
closeButton.alpha = 0.0
144+
closeButton.addTarget(self, action: #selector(ImageViewer.close(_:)), forControlEvents: .TouchUpInside)
139145
}
140146

141147
private func configureGestureRecognizers() {
@@ -154,22 +160,37 @@ public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewCo
154160

155161
imageView.frame = parentViewFrameInOurCoordinateSystem
156162
imageView.contentMode = .ScaleAspectFit
157-
view.addSubview(imageView)
158163
imageView.image = screenshotFromView(displacedView)
159164
}
160165

161166
private func configureScrollView() {
162167

168+
scrollView.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil)
169+
scrollView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
163170
scrollView.decelerationRate = 0.5
164171
scrollView.contentInset = UIEdgeInsetsZero
165172
scrollView.contentOffset = CGPointZero
166173
scrollView.contentSize = imageView.frame.size
167174
scrollView.minimumZoomScale = 1
168-
scrollView.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.New, context: nil)
175+
scrollView.delegate = self
176+
}
177+
178+
func createViewHierarchy() {
179+
180+
view.addSubview(overlayView)
181+
view.addSubview(imageView)
182+
view.addSubview(scrollView)
183+
view.addSubview(closeButton)
169184
}
170185

171186
// MARK: - View Lifecycle
172187

188+
public override func viewDidLoad() {
189+
super.viewDidLoad()
190+
191+
createViewHierarchy()
192+
}
193+
173194
public override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
174195
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
175196
shouldRotate = true
@@ -196,32 +217,6 @@ public final class ImageViewer: UIViewController, UIScrollViewDelegate, UIViewCo
196217
}
197218
}
198219

199-
public override func loadView() {
200-
super.loadView()
201-
202-
scrollView = UIScrollView(frame: CGRectZero)
203-
overlayView = UIView(frame: CGRectZero)
204-
closeButton = UIButton(frame: CGRectZero)
205-
206-
scrollView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
207-
overlayView.autoresizingMask = [.None]
208-
209-
view.addSubview(overlayView)
210-
view.addSubview(scrollView)
211-
view.addSubview(closeButton)
212-
213-
scrollView.delegate = self
214-
closeButton.addTarget(self, action: #selector(ImageViewer.close(_:)), forControlEvents: .TouchUpInside)
215-
}
216-
217-
public override func viewDidLoad() {
218-
super.viewDidLoad()
219-
220-
configureCloseButton()
221-
configureImageView()
222-
configureScrollView()
223-
}
224-
225220
// MARK: - Transitioning Delegate
226221

227222
public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {

0 commit comments

Comments
 (0)