Skip to content

Commit 6dca682

Browse files
committed
Add updatePreferredFrameIfNeeded(animated: Bool)
This method update the pull up controller's view size according to `pullUpControllerPreferredSize` and `pullUpControllerPreferredLandscapeFrame`. If the device is in portrait, the pull up controller's view will be attached to the nearest sticky point after the resize.
1 parent 3ef7316 commit 6dca682

File tree

4 files changed

+182
-53
lines changed

4 files changed

+182
-53
lines changed

Example/PullUpController/UI/Main.storyboard

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,58 @@
2121
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="drN-fA-22T">
2222
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
2323
</mapView>
24+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iMQ-X7-eJt">
25+
<rect key="frame" x="20" y="84" width="250" height="131"/>
26+
<subviews>
27+
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="dfq-ok-AvZ">
28+
<rect key="frame" x="15" y="10" width="220" height="111"/>
29+
<subviews>
30+
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="IPI-H1-hVv">
31+
<rect key="frame" x="0.0" y="0.0" width="220" height="50.5"/>
32+
<subviews>
33+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Width" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0NG-ba-qVR">
34+
<rect key="frame" x="0.0" y="0.0" width="220" height="20.5"/>
35+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
36+
<nil key="textColor"/>
37+
<nil key="highlightedColor"/>
38+
</label>
39+
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="250" minValue="200" maxValue="300" translatesAutoresizingMaskIntoConstraints="NO" id="BBH-5e-dyt">
40+
<rect key="frame" x="-2" y="20.5" width="224" height="31"/>
41+
<connections>
42+
<action selector="widthSliderValueChanged:" destination="BYZ-38-t0r" eventType="valueChanged" id="cry-5o-Xbg"/>
43+
</connections>
44+
</slider>
45+
</subviews>
46+
</stackView>
47+
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="WHY-rS-cfZ">
48+
<rect key="frame" x="0.0" y="60.5" width="220" height="50.5"/>
49+
<subviews>
50+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Height" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6k7-Vh-uLf">
51+
<rect key="frame" x="0.0" y="0.0" width="220" height="20.5"/>
52+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
53+
<nil key="textColor"/>
54+
<nil key="highlightedColor"/>
55+
</label>
56+
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="300" minValue="200" maxValue="500" translatesAutoresizingMaskIntoConstraints="NO" id="cQL-QM-VLC">
57+
<rect key="frame" x="-2" y="20.5" width="224" height="31"/>
58+
<connections>
59+
<action selector="heightSliderValueChanged:" destination="BYZ-38-t0r" eventType="valueChanged" id="XJ1-K7-F3Y"/>
60+
</connections>
61+
</slider>
62+
</subviews>
63+
</stackView>
64+
</subviews>
65+
</stackView>
66+
</subviews>
67+
<color key="backgroundColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
68+
<constraints>
69+
<constraint firstItem="dfq-ok-AvZ" firstAttribute="top" secondItem="iMQ-X7-eJt" secondAttribute="top" constant="10" id="VZI-f2-7RI"/>
70+
<constraint firstAttribute="width" constant="250" id="aW0-zJ-2qY"/>
71+
<constraint firstItem="dfq-ok-AvZ" firstAttribute="leading" secondItem="iMQ-X7-eJt" secondAttribute="leading" constant="15" id="fRI-JL-aon"/>
72+
<constraint firstAttribute="trailing" secondItem="dfq-ok-AvZ" secondAttribute="trailing" constant="15" id="uVs-MH-NKV"/>
73+
<constraint firstAttribute="bottom" secondItem="dfq-ok-AvZ" secondAttribute="bottom" constant="10" id="yE4-Jj-2vV"/>
74+
</constraints>
75+
</view>
2476
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="agq-BC-bau">
2577
<rect key="frame" x="0.0" y="0.0" width="375" height="20"/>
2678
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="fEH-yT-wLK">
@@ -37,8 +89,10 @@
3789
<constraints>
3890
<constraint firstItem="drN-fA-22T" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" id="7AR-Wc-usn"/>
3991
<constraint firstAttribute="bottom" secondItem="drN-fA-22T" secondAttribute="bottom" id="BNk-Pq-9mt"/>
92+
<constraint firstItem="iMQ-X7-eJt" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="20" id="DXK-V0-r6F"/>
4093
<constraint firstItem="drN-fA-22T" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="TGw-SP-OU6"/>
4194
<constraint firstItem="drN-fA-22T" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="ZoL-CH-lGY"/>
95+
<constraint firstItem="iMQ-X7-eJt" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="20" id="cuZ-GY-s6v"/>
4296
<constraint firstItem="agq-BC-bau" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="ewe-vs-e5Q"/>
4397
<constraint firstItem="agq-BC-bau" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" id="nRk-u4-pYb"/>
4498
<constraint firstAttribute="trailing" secondItem="agq-BC-bau" secondAttribute="trailing" id="qOz-Yp-9fE"/>
@@ -59,7 +113,10 @@
59113
</barButtonItem>
60114
</navigationItem>
61115
<connections>
116+
<outlet property="heightSlider" destination="cQL-QM-VLC" id="IZA-Ju-0mH"/>
62117
<outlet property="mapView" destination="drN-fA-22T" id="EE5-qd-AEu"/>
118+
<outlet property="sizeSliderView" destination="iMQ-X7-eJt" id="5B3-VC-LYw"/>
119+
<outlet property="widthSlider" destination="BBH-5e-dyt" id="e2p-It-Bhh"/>
63120
</connections>
64121
</viewController>
65122
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
@@ -75,9 +132,9 @@
75132
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
76133
<subviews>
77134
<visualEffectView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tqg-Jj-GrO">
78-
<rect key="frame" x="0.0" y="0.0" width="375" height="466"/>
135+
<rect key="frame" x="0.0" y="0.0" width="375" height="416"/>
79136
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="i42-6p-NuO">
80-
<rect key="frame" x="0.0" y="0.0" width="375" height="466"/>
137+
<rect key="frame" x="0.0" y="0.0" width="375" height="416"/>
81138
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
82139
<subviews>
83140
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tcn-Uq-ouF">
@@ -121,14 +178,14 @@
121178
</constraints>
122179
</view>
123180
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZrV-tJ-aqf">
124-
<rect key="frame" x="0.0" y="216" width="375" height="250"/>
181+
<rect key="frame" x="0.0" y="216" width="375" height="200"/>
125182
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
126183
<constraints>
127-
<constraint firstAttribute="height" constant="250" id="t9E-rD-EPs"/>
184+
<constraint firstAttribute="height" constant="200" id="t9E-rD-EPs"/>
128185
</constraints>
129186
</view>
130187
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="50" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="trT-oA-YHo">
131-
<rect key="frame" x="0.0" y="66" width="375" height="400"/>
188+
<rect key="frame" x="0.0" y="66" width="375" height="350"/>
132189
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
133190
<color key="sectionIndexBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
134191
<prototypes>

Example/PullUpController/UI/MapViewController.swift

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,39 @@ import MapKit
1212
class MapViewController: UIViewController {
1313

1414
@IBOutlet private weak var mapView: MKMapView!
15+
@IBOutlet private weak var sizeSliderView: UIView! {
16+
didSet {
17+
sizeSliderView.layer.cornerRadius = 10
18+
}
19+
}
20+
@IBOutlet private weak var widthSlider: UISlider!
21+
@IBOutlet private weak var heightSlider: UISlider!
22+
23+
private func makeSearchViewControllerIfNeeded() -> SearchViewController {
24+
let currentPullUpController = childViewControllers
25+
.filter({ $0 is SearchViewController })
26+
.first as? SearchViewController
27+
if let currentPullUpController = currentPullUpController {
28+
return currentPullUpController
29+
} else {
30+
return UIStoryboard(name: "Main", bundle: nil)
31+
.instantiateViewController(withIdentifier: "SearchViewController") as! SearchViewController
32+
}
33+
}
1534

1635
override func viewDidLoad() {
1736
super.viewDidLoad()
18-
1937
addPullUpController()
38+
39+
let pullUpController = makeSearchViewControllerIfNeeded()
40+
widthSlider.maximumValue = Float(pullUpController.portraitSize.width)
41+
widthSlider.value = widthSlider.maximumValue
42+
heightSlider.maximumValue = Float(pullUpController.portraitSize.height)
43+
heightSlider.value = heightSlider.maximumValue
2044
}
2145

2246
private func addPullUpController() {
23-
guard
24-
let pullUpController = UIStoryboard(name: "Main", bundle: nil)
25-
.instantiateViewController(withIdentifier: "SearchViewController") as? SearchViewController
26-
else { return }
27-
47+
let pullUpController = makeSearchViewControllerIfNeeded()
2848
addPullUpController(pullUpController, animated: true)
2949
}
3050

@@ -43,11 +63,32 @@ class MapViewController: UIViewController {
4363
}
4464

4565
@IBAction private func removeButtonTapped() {
46-
guard
47-
let pullUpController = childViewControllers.filter({ $0 is SearchViewController }).first as? SearchViewController
48-
else { return }
66+
let pullUpController = makeSearchViewControllerIfNeeded()
4967
removePullUpController(pullUpController, animated: true)
5068
}
5169

70+
@IBAction private func widthSliderValueChanged(_ sender: UISlider) {
71+
let width = CGFloat(sender.value)
72+
let pullUpController = makeSearchViewControllerIfNeeded()
73+
pullUpController.portraitSize = CGSize(width: width,
74+
height: pullUpController.portraitSize.height)
75+
pullUpController.landscapeFrame = CGRect(origin: pullUpController.landscapeFrame.origin,
76+
size: CGSize(width: width,
77+
height: pullUpController.landscapeFrame.height))
78+
pullUpController.updatePreferredFrameIfNeeded(animated: true)
79+
}
80+
81+
@IBAction private func heightSliderValueChanged(_ sender: UISlider) {
82+
let height = CGFloat(sender.value)
83+
let pullUpController = makeSearchViewControllerIfNeeded()
84+
pullUpController.portraitSize = CGSize(width: pullUpController.portraitSize.width,
85+
height: height)
86+
pullUpController.landscapeFrame = CGRect(origin: pullUpController.landscapeFrame.origin,
87+
size: CGSize(width: pullUpController.landscapeFrame.width,
88+
height: height))
89+
pullUpController.updatePreferredFrameIfNeeded(animated: true)
90+
91+
}
92+
5293
}
5394

Example/PullUpController/UI/SearchViewController.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,18 @@ class SearchViewController: PullUpController {
2727

2828
private var locations = [(title: String, location: CLLocationCoordinate2D)]()
2929

30+
public var portraitSize: CGSize = .zero
31+
public var landscapeFrame: CGRect = .zero
32+
3033
// MARK: - Lifecycle
3134

3235
override func viewDidLoad() {
3336
super.viewDidLoad()
3437

38+
portraitSize = CGSize(width: min(UIScreen.main.bounds.width, UIScreen.main.bounds.height),
39+
height: secondPreviewView.frame.maxY)
40+
landscapeFrame = CGRect(x: 5, y: 50, width: 280, height: 300)
41+
3542
tableView.attach(to: self)
3643
setupDataSource()
3744

@@ -68,7 +75,11 @@ class SearchViewController: PullUpController {
6875
// MARK: - PullUpController
6976

7077
override var pullUpControllerPreferredSize: CGSize {
71-
return CGSize(width: UIScreen.main.bounds.width, height: secondPreviewView.frame.maxY)
78+
return portraitSize
79+
}
80+
81+
override var pullUpControllerPreferredLandscapeFrame: CGRect {
82+
return landscapeFrame
7283
}
7384

7485
override var pullUpControllerPreviewOffset: CGFloat {
@@ -83,9 +94,6 @@ class SearchViewController: PullUpController {
8394
return false
8495
}
8596

86-
override var pullUpControllerPreferredLandscapeFrame: CGRect {
87-
return CGRect(x: 5, y: 5, width: 280, height: UIScreen.main.bounds.height - 10)
88-
}
8997
}
9098

9199
// MARK: - UISearchBarDelegate

0 commit comments

Comments
 (0)