Skip to content

Commit 9104ba2

Browse files
committed
Merge branch 'release/1.2.0'
2 parents c3c5d06 + 3dcb8d8 commit 9104ba2

File tree

9 files changed

+175
-34
lines changed

9 files changed

+175
-34
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,15 @@ class ViewController: ScrollStackController, ScrollStackControllerDelegate {
617617
func scrollStackRowDidBecomeHidden(_ stackView: ScrollStack, row: ScrollStackRow, index: Int, state: ScrollStack.RowVisibility) {
618618
// Row did become partially or entirely invisible.
619619
}
620-
620+
621+
func scrollStackDidUpdateLayout(_ stackView: ScrollStack) {
622+
// This function is called when layout is updated (added, removed, hide or show one or more rows).
623+
}
624+
625+
func scrollStackContentSizeDidChange(_ stackView: ScrollStack, from oldValue: CGSize, to newValue: CGSize) {
626+
// This function is called when content size of the stack did change (remove/add, hide/show rows).
627+
}
628+
621629
}
622630
```
623631

ScrollStackController.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "ScrollStackController"
3-
s.version = "1.1.0"
3+
s.version = "1.2.0"
44
s.summary = "Create complex scrollable layout using UIViewController and simplify your code"
55
s.homepage = "https://github.com/malcommac/ScrollStackController"
66
s.license = { :type => "MIT", :file => "LICENSE" }

ScrollStackController.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@
544544
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
545545
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
546546
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
547-
MARKETING_VERSION = 1.1.0;
547+
MARKETING_VERSION = 1.2.0;
548548
ONLY_ACTIVE_ARCH = NO;
549549
PRODUCT_BUNDLE_IDENTIFIER = "com.ScrollStackController.ScrollStackController-iOS";
550550
PRODUCT_NAME = ScrollStackController;
@@ -569,7 +569,7 @@
569569
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
570570
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
571571
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
572-
MARKETING_VERSION = 1.1.0;
572+
MARKETING_VERSION = 1.2.0;
573573
PRODUCT_BUNDLE_IDENTIFIER = "com.ScrollStackController.ScrollStackController-iOS";
574574
PRODUCT_NAME = ScrollStackController;
575575
SKIP_INSTALL = YES;
@@ -617,11 +617,13 @@
617617
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
618618
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
619619
CODE_SIGN_STYLE = Automatic;
620+
CURRENT_PROJECT_VERSION = 0;
620621
DEVELOPMENT_TEAM = SXF6X3A7VN;
621622
GCC_C_LANGUAGE_STANDARD = gnu11;
622623
INFOPLIST_FILE = ScrollStackControllerDemo/Info.plist;
623624
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
624625
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
626+
MARKETING_VERSION = 1.2.0;
625627
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
626628
MTL_FAST_MATH = YES;
627629
PRODUCT_BUNDLE_IDENTIFIER = com.danielemargutti.ScrollStackControllerDemo;
@@ -643,11 +645,13 @@
643645
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
644646
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
645647
CODE_SIGN_STYLE = Automatic;
648+
CURRENT_PROJECT_VERSION = 0;
646649
DEVELOPMENT_TEAM = SXF6X3A7VN;
647650
GCC_C_LANGUAGE_STANDARD = gnu11;
648651
INFOPLIST_FILE = ScrollStackControllerDemo/Info.plist;
649652
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
650653
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
654+
MARKETING_VERSION = 1.2.0;
651655
MTL_FAST_MATH = YES;
652656
PRODUCT_BUNDLE_IDENTIFIER = com.danielemargutti.ScrollStackControllerDemo;
653657
PRODUCT_NAME = "$(TARGET_NAME)";

ScrollStackControllerDemo/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<key>CFBundlePackageType</key>
1616
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.0</string>
18+
<string>$(MARKETING_VERSION)</string>
1919
<key>CFBundleVersion</key>
20-
<string>1</string>
20+
<string>$(CURRENT_PROJECT_VERSION)</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>NSAppTransportSecurity</key>

ScrollStackControllerDemo/ViewController.swift

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88

99
import UIKit
1010

11-
class ViewController: UIViewController {
11+
class ViewController: UIViewController, ScrollStackControllerDelegate {
12+
1213

1314
@IBOutlet public var contentView: UIView!
1415

@@ -28,13 +29,19 @@ class ViewController: UIViewController {
2829
override func viewDidLoad() {
2930
super.viewDidLoad()
3031
}
32+
33+
func scrollStackRowDidUpdateLayout(_ stackView: ScrollStack) {
34+
debugPrint("New content insets \(stackView.contentSize.height)")
35+
}
3136

3237
override func viewDidAppear(_ animated: Bool) {
3338
super.viewDidAppear(animated)
3439

3540
stackController.view.frame = contentView.bounds
3641
contentView.addSubview(stackController.view)
3742

43+
44+
stackView.stackDelegate = self
3845
// Prepare content
3946

4047
welcomeVC = WelcomeVC.create()
@@ -44,7 +51,6 @@ class ViewController: UIViewController {
4451
notesVC = NotesVC.create(delegate: self)
4552

4653
stackView.addRows(controllers: [welcomeVC, notesVC, tagsVC, galleryVC,pricingVC], animated: false)
47-
4854
}
4955

5056
@IBAction public func addNewRow() {
@@ -78,6 +84,28 @@ class ViewController: UIViewController {
7884
let randomRow = Int.random(in: 0..<stackView.rows.count)
7985
stackView.scrollToRow(index: randomRow, at: .middle, animated: true)
8086
}
87+
88+
89+
func scrollStackDidScroll(_ stackView: ScrollStack, offset: CGPoint) {
90+
91+
}
92+
93+
func scrollStackRowDidBecomeVisible(_ stackView: ScrollStack, row: ScrollStackRow, index: Int, state: ScrollStack.RowVisibility) {
94+
95+
}
96+
97+
func scrollStackRowDidBecomeHidden(_ stackView: ScrollStack, row: ScrollStackRow, index: Int, state: ScrollStack.RowVisibility) {
98+
99+
}
100+
101+
func scrollStackDidUpdateLayout(_ stackView: ScrollStack) {
102+
103+
}
104+
105+
func scrollStackContentSizeDidChange(_ stackView: ScrollStack, from oldValue: CGSize, to newValue: CGSize) {
106+
// debugPrint("Content size did change from \(oldValue) to \(newValue)")
107+
}
108+
81109
}
82110

83111
extension ViewController: TagsVCProtocol {

Sources/ScrollStackController/ScrollStack.swift

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,16 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
4343
right: UITableView().separatorInset.left
4444
)
4545

46+
private static let defaultRowPadding: UIEdgeInsets = .zero
47+
4648
public static let defaultSeparatorInset: UIEdgeInsets = UITableView().separatorInset
4749
public static let defaultSeparatorColor = (UITableView().separatorColor ?? .clear)
4850
public static let defaultRowColor = UIColor.clear
4951
public static let defaultRowHighlightColor = UIColor(red: 0.85, green: 0.85, blue: 0.85, alpha: 1)
50-
52+
53+
/// Cached content size for did change content size callback in scrollstack delegate.
54+
private var cachedContentSize: CGSize?
55+
5156
// MARK: Public Properties
5257

5358
/// The direction that rows are laid out in the stack view and scrolling works.
@@ -122,6 +127,15 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
122127
}
123128
}
124129

130+
/// Padding for rows `contentView` (the view of the view controller handled by row).
131+
open var rowPadding: UIEdgeInsets = ScrollStack.defaultRowPadding {
132+
didSet {
133+
rows.forEach { row in
134+
row.rowPadding = rowPadding
135+
}
136+
}
137+
}
138+
125139
/// The color of separators in the stack view.
126140
/// You can set property for a single separator by setting new value inside the row's `separatoView`.
127141
open var separatorColor = ScrollStack.defaultSeparatorColor {
@@ -515,7 +529,7 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
515529
safeRowAtIndex(rowIndex)?.rowInsets = insets
516530
}
517531

518-
/// Set the ints of the row's content related to the parent row cell.
532+
/// Set the insets of the row's content related to the parent row cell.
519533
///
520534
/// - Parameter row: target rows.
521535
/// - Parameter insets: new insets.
@@ -525,6 +539,24 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
525539
}
526540
}
527541

542+
/// Set the padding of the row's content related to parent row cell.
543+
///
544+
/// - Parameter row: target row.
545+
/// - Parameter padding: new insets.
546+
open func setRowPadding(index rowIndex: Int, padding: UIEdgeInsets) {
547+
safeRowAtIndex(rowIndex)?.rowPadding = padding
548+
}
549+
550+
/// Set the padding of the row's content related to the parent row cell.
551+
///
552+
/// - Parameter row: target rows.
553+
/// - Parameter insets: new padding.
554+
open func setRowPadding(indexes rowIndexes: [Int], padding: UIEdgeInsets) {
555+
rowIndexes.forEach {
556+
setRowPadding(index: $0, padding: padding)
557+
}
558+
}
559+
528560
/// Return the visibility status of a row.
529561
///
530562
/// - Parameter index: index of the row to check.
@@ -924,4 +956,20 @@ open class ScrollStack: UIScrollView, UIScrollViewDelegate {
924956
dispatchRowsVisibilityChangesTo(stackDelegate)
925957
}
926958

959+
open override func layoutSubviews() {
960+
super.layoutSubviews()
961+
962+
guard let stackDelegate = stackDelegate else {
963+
return
964+
}
965+
966+
stackDelegate.scrollStackDidUpdateLayout(self)
967+
968+
if let oldContentSize = cachedContentSize, oldContentSize != self.contentSize {
969+
stackDelegate.scrollStackContentSizeDidChange(self, from: oldContentSize, to: contentSize)
970+
}
971+
972+
cachedContentSize = self.contentSize
973+
}
974+
927975
}

Sources/ScrollStackController/ScrollStackRow.swift

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
import UIKit
3434

35+
// MARK: - ScrollStackRow
36+
3537
open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
3638

3739
// MARK: Private Properties
@@ -52,12 +54,10 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
5254
}()
5355

5456
/// Constraints to handle separator's insets changes.
55-
private var separatorConstraints: (
56-
top: NSLayoutConstraint,
57-
bottom: NSLayoutConstraint,
58-
leading: NSLayoutConstraint,
59-
trailing: NSLayoutConstraint
60-
)?
57+
private var separatorConstraints: ConstraintsHolder?
58+
59+
/// Constraints to handle content's view padding changes.
60+
private var paddingConstraints: ConstraintsHolder?
6161

6262
/// Location of the separator view.
6363
/// It's automatically managed when you change the axis of the parent stackview.
@@ -150,6 +150,13 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
150150
}
151151
}
152152

153+
open var rowPadding: UIEdgeInsets {
154+
didSet {
155+
paddingConstraints?.updateInsets(rowPadding)
156+
layoutIfNeeded()
157+
}
158+
}
159+
153160
open override var isHidden: Bool {
154161
didSet {
155162
guard isHidden != oldValue else {
@@ -162,6 +169,7 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
162169
internal init(controller: UIViewController, stackView: ScrollStack) {
163170
self.stackView = stackView
164171
self.controller = controller
172+
self.rowPadding = stackView.rowPadding
165173
super.init(frame: .zero)
166174

167175
clipsToBounds = true
@@ -198,6 +206,7 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
198206
}
199207

200208
rowInsets = stackView.rowInsets
209+
rowPadding = stackView.rowPadding
201210
rowBackgroundColor = stackView.rowBackgroundColor
202211
rowHighlightColor = stackView.rowHighlightColor
203212

@@ -212,40 +221,42 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
212221
// MARK: Manage Separator
213222

214223
private func didUpdateContentViewContraints() {
215-
let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
224+
let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor, constant: rowPadding.bottom)
216225
bottomConstraint.priority = UILayoutPriority(rawValue: UILayoutPriority.required.rawValue - 1)
226+
227+
paddingConstraints = ConstraintsHolder(
228+
top: contentView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: rowPadding.top),
229+
bottom: bottomConstraint,
230+
left: contentView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: rowPadding.left),
231+
right: contentView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor, constant: rowPadding.right)
232+
)
217233

218-
NSLayoutConstraint.activate([
219-
contentView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
220-
contentView.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
221-
contentView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
222-
bottomConstraint
223-
])
234+
paddingConstraints?.activateAll()
224235
}
225236

226237
private func didUpdateSeparatorViewContraintsIfNeeded() {
227238
if separatorConstraints == nil {
228-
separatorConstraints = (
239+
separatorConstraints = ConstraintsHolder(
229240
top: separatorView.topAnchor.constraint(equalTo: topAnchor),
230241
bottom: separatorView.bottomAnchor.constraint(equalTo: bottomAnchor),
231-
leading: separatorView.leadingAnchor.constraint(equalTo: leadingAnchor),
232-
trailing: separatorView.trailingAnchor.constraint(equalTo: trailingAnchor)
242+
left: separatorView.leadingAnchor.constraint(equalTo: leadingAnchor),
243+
right: separatorView.trailingAnchor.constraint(equalTo: trailingAnchor)
233244
)
234245
}
235246
}
236247

237248
private func didUpdateSeparatorAxis() {
238-
separatorConstraints?.top.isActive = (separatorAxis == .vertical)
239-
separatorConstraints?.bottom.isActive = true
240-
separatorConstraints?.leading.isActive = (separatorAxis == .horizontal)
241-
separatorConstraints?.trailing.isActive = true
249+
separatorConstraints?.top?.isActive = (separatorAxis == .vertical)
250+
separatorConstraints?.bottom?.isActive = true
251+
separatorConstraints?.left?.isActive = (separatorAxis == .horizontal)
252+
separatorConstraints?.right?.isActive = true
242253
}
243254

244255
private func didUpdateSeparatorInsets() {
245-
separatorConstraints?.top.constant = separatorInsets.top
246-
separatorConstraints?.bottom.constant = (separatorAxis == .horizontal ? 0 : -separatorInsets.bottom)
247-
separatorConstraints?.leading.constant = separatorInsets.left
248-
separatorConstraints?.trailing.constant = (separatorAxis == .vertical ? 0 : -separatorInsets.right)
256+
separatorConstraints?.top?.constant = separatorInsets.top
257+
separatorConstraints?.bottom?.constant = (separatorAxis == .horizontal ? 0 : -separatorInsets.bottom)
258+
separatorConstraints?.left?.constant = separatorInsets.left
259+
separatorConstraints?.right?.constant = (separatorAxis == .vertical ? 0 : -separatorInsets.right)
249260
}
250261

251262
// MARK: - Sizing the Controller
@@ -370,3 +381,32 @@ open class ScrollStackRow: UIView, UIGestureRecognizerDelegate {
370381
}
371382

372383
}
384+
385+
// MARK: - ConstraintsHolder
386+
387+
fileprivate class ConstraintsHolder {
388+
var top: NSLayoutConstraint?
389+
var left: NSLayoutConstraint?
390+
var bottom: NSLayoutConstraint?
391+
var right: NSLayoutConstraint?
392+
393+
init(top: NSLayoutConstraint?, bottom: NSLayoutConstraint?,
394+
left: NSLayoutConstraint?, right: NSLayoutConstraint?) {
395+
self.top = top
396+
self.bottom = bottom
397+
self.left = left
398+
self.right = right
399+
}
400+
401+
func activateAll() {
402+
[top, left, bottom, right].forEach { $0?.isActive = true }
403+
}
404+
405+
func updateInsets(_ insets: UIEdgeInsets) {
406+
top?.constant = insets.top
407+
bottom?.constant = insets.bottom
408+
left?.constant = insets.left
409+
right?.constant = insets.right
410+
}
411+
412+
}

0 commit comments

Comments
 (0)