Skip to content

Commit 9cf289c

Browse files
committed
Added ScrollStack.ControllerSize to manage fitToLayout and fixed size for axis
1 parent 7110494 commit 9cf289c

File tree

8 files changed

+64
-28
lines changed

8 files changed

+64
-28
lines changed

ScrollStackControllerDemo/Child View Controllers/GalleryVC.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public class GalleryVC: UIViewController, ScrollStackContainableController {
2626
return vc
2727
}
2828

29-
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> CGFloat? {
30-
return 300
29+
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> ScrollStack.ControllerSize? {
30+
return .fixed(300)
3131
}
3232

3333
public override func viewDidAppear(_ animated: Bool) {

ScrollStackControllerDemo/Child View Controllers/NotesVC.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ public class NotesVC: UIViewController, ScrollStackContainableController {
2323
return vc
2424
}
2525

26-
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> CGFloat? {
26+
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> ScrollStack.ControllerSize? {
2727
let size = CGSize(width: stackView.bounds.size.width, height: 9000)
2828
var best = self.view.systemLayoutSizeFitting(size, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
29-
best.height += 20
30-
// it's important to set both the height constraint and bottom safe area for table bottom
31-
return best.height
29+
best.height += 20 // just some offset for UITextView insets
30+
// NOTE:
31+
// it's important to set both the height constraint and bottom safe constraints to safe area for textview,
32+
// otherwise growing does not work.
33+
return .fixed(best.height)
3234
}
3335

3436

ScrollStackControllerDemo/Child View Controllers/PricingVC.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@ public class PricingVC: UIViewController, ScrollStackContainableController {
3232
return vc
3333
}
3434

35-
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> CGFloat? {
36-
let size = CGSize(width: stackView.bounds.size.width, height: 9000)
37-
let best = self.view.systemLayoutSizeFitting(size, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
38-
// it's important to set both the height constraint and bottom safe area for table bottom
39-
return best.height
35+
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> ScrollStack.ControllerSize? {
36+
return .fitLayoutForAxis
37+
// let size = CGSize(width: stackView.bounds.size.width, height: 9000)
38+
// let best = self.view.systemLayoutSizeFitting(size, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
39+
// // NOTE:
40+
// // it's important to set both the height constraint and bottom safe constraints to safe area for tableview,
41+
// // otherwise growing does not work.
42+
// return best.height
4043
}
4144

4245
override public func updateViewConstraints() {

ScrollStackControllerDemo/Child View Controllers/TagsVC.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public class TagsVC: UIViewController, ScrollStackContainableController {
4848
return vc
4949
}
5050

51-
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> CGFloat? {
52-
return (isExpanded == false ? 170 : 170 + collectionView.contentSize.height + 20)
51+
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> ScrollStack.ControllerSize? {
52+
return (isExpanded == false ? .fixed(170) : .fixed(170 + collectionView.contentSize.height + 20))
5353
}
5454

5555
public func reloadContentFromStackViewRow() {

ScrollStackControllerDemo/Child View Controllers/WelcomeVC.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ public class WelcomeVC: UIViewController, ScrollStackContainableController {
1616
return vc
1717
}
1818

19-
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> CGFloat? {
20-
let size = CGSize(width: stackView.bounds.size.width, height: 9000)
21-
let best = self.view.systemLayoutSizeFitting(size, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
22-
return best.height
19+
public func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> ScrollStack.ControllerSize? {
20+
// let size = CGSize(width: stackView.bounds.size.width, height: 9000)
21+
// let best = self.view.systemLayoutSizeFitting(size, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
22+
// return best.height
23+
return .fitLayoutForAxis
2324
}
2425

2526
public func reloadContentFromStackViewRow() {

Sources/ScrollStackController/ScrollStackRow.swift

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
245245
separatorConstraints?.trailing.constant = (separatorAxis == .vertical ? 0 : -separatorInsets.right)
246246
}
247247

248+
// MARK: - Sizing the Controller
249+
248250
internal func askForCutomizedSizeOfContentView() {
249251
guard let customizableController = controller as? ScrollStackContainableController else {
250252
return // ignore, it's not implemented, use autolayout.
@@ -255,20 +257,40 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
255257
return // ignore, use autolayout in place for content view.
256258
}
257259

258-
switch currentAxis {
259-
case .horizontal:
260-
contentView.width(constant: bestSize)
261-
contentView.height(constant: nil)
260+
switch bestSize {
261+
case .fixed(let value):
262+
setupRowToFixedValue(value)
262263

263-
case .vertical:
264+
case .fitLayoutForAxis:
265+
setupRowSizeToFitLayout()
266+
}
267+
}
268+
269+
private func setupRowToFixedValue(_ value: CGFloat) {
270+
guard let stackView = stackView else { return }
271+
272+
if stackView.axis == .vertical {
264273
contentView.width(constant: nil)
265-
contentView.height(constant: bestSize)
266-
267-
default:
268-
break
274+
contentView.height(constant: value)
275+
} else {
276+
contentView.width(constant: value)
277+
contentView.height(constant: nil)
278+
}
279+
}
280+
281+
private func setupRowSizeToFitLayout() {
282+
guard let stackView = stackView else { return }
283+
284+
var bestSize: CGSize!
285+
if stackView.axis == .vertical {
286+
let maxAllowedSize = CGSize(width: stackView.bounds.size.width, height: CGFloat.greatestFiniteMagnitude)
287+
bestSize = contentView.systemLayoutSizeFitting(maxAllowedSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
288+
} else {
289+
let maxAllowedSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: stackView.bounds.size.height)
290+
bestSize = contentView.systemLayoutSizeFitting(maxAllowedSize, withHorizontalFittingPriority: .defaultLow, verticalFittingPriority: .required)
269291
}
270292

271-
print("")
293+
setupRowToFixedValue(bestSize.height)
272294
}
273295

274296
// MARK: - Handle Touch

Sources/ScrollStackController/Support/ScrollStack+Protocols.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public protocol ScrollStackContainableController: UIViewController {
4949
/// - Parameter axis: axis of the stackview.
5050
/// - Parameter row: row where the controller is placed.
5151
/// - Parameter stackView: stackview where the row is placed.
52-
func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> CGFloat?
52+
func scrollStackRowSizeForAxis(_ axis: NSLayoutConstraint.Axis, row: ScrollStackRow, in stackView: ScrollStack) -> ScrollStack.ControllerSize?
5353

5454
/// Method is called when you call a `reloadRow` function on a row where this controller is contained in.
5555
func reloadContentFromStackViewRow()
@@ -122,6 +122,14 @@ extension ScrollStackRowHighlightable where Self: UIView {
122122

123123
public extension ScrollStack {
124124

125+
/// Define the controller size.
126+
/// - `fixed`: fixed size in points.
127+
/// - `fitLayoutForAxis`: attempt to size the controller to fits its content set with autolayout.
128+
enum ControllerSize {
129+
case fixed(CGFloat)
130+
case fitLayoutForAxis
131+
}
132+
125133
/// Insertion of the new row.
126134
/// - `top`: insert row at the top of the stack.
127135
/// - `bottom`: append the row at the end of the stack rows.

0 commit comments

Comments
 (0)