three layer collection anchoring
This commit is contained in:
parent
e0d17f7270
commit
a97132c897
@ -79,6 +79,8 @@ import Foundation
|
||||
|
||||
|
||||
open override func handleNewData() {
|
||||
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
||||
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||
setup()
|
||||
registerCells()
|
||||
super.handleNewData()
|
||||
|
||||
@ -12,6 +12,8 @@ import Foundation
|
||||
@objc open class ProgrammaticCollectionViewController: ScrollingViewController {
|
||||
|
||||
public var collectionView: UICollectionView?
|
||||
public var topConstraint: NSLayoutConstraint?
|
||||
public var bottomConstraint: NSLayoutConstraint?
|
||||
|
||||
open override func loadView() {
|
||||
let view = UIView()
|
||||
@ -19,7 +21,9 @@ import Foundation
|
||||
|
||||
let collection = createCollectionView()
|
||||
view.addSubview(collection)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: collection)
|
||||
let constraints = NSLayoutConstraint.constraintPinSubview(toSuperview: collection)
|
||||
topConstraint = constraints?[ConstraintTop] as? NSLayoutConstraint
|
||||
bottomConstraint = constraints?[ConstraintBot] as? NSLayoutConstraint
|
||||
|
||||
collectionView = collection
|
||||
scrollView = collectionView
|
||||
|
||||
@ -52,16 +52,34 @@ import Foundation
|
||||
footerView?.topConstraint?.constant = half
|
||||
collectionView?.collectionViewLayout.invalidateLayout()
|
||||
} else if fillTop {
|
||||
// Only top is spaced (half the size if the bottom view is out of the scroll because it needs to be sized as if there are two spacers but there is only one.
|
||||
// Only top is spaced.
|
||||
headerView?.bottomConstraint?.constant = newSpace
|
||||
collectionView?.collectionViewLayout.invalidateLayout()
|
||||
} else if fillBottom {
|
||||
// Only bottom is spaced.
|
||||
footerView?.topConstraint?.constant = newSpace
|
||||
collectionView?.collectionViewLayout.invalidateLayout()
|
||||
collectionView.collectionViewLayout.invalidateLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addTopViewOutside() {
|
||||
guard let collectionView = collectionView, let topView = topView else { return }
|
||||
view.addSubview(topView)
|
||||
topView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
|
||||
topView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
|
||||
view.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: topView.rightAnchor).isActive = true
|
||||
collectionView.topAnchor.constraint(equalTo: topView.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
func addBottomViewOutside() {
|
||||
guard let collectionView = collectionView, let bottomView = bottomView else { return }
|
||||
view.addSubview(bottomView)
|
||||
bottomView.topAnchor.constraint(equalTo: collectionView.bottomAnchor).isActive = true
|
||||
bottomView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
|
||||
view.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: bottomView.rightAnchor).isActive = true
|
||||
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: bottomView.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
//MARK: - ViewController
|
||||
open override func updateViews() {
|
||||
@ -86,8 +104,22 @@ import Foundation
|
||||
|
||||
open override func handleNewData() {
|
||||
super.handleNewData()
|
||||
topView?.removeFromSuperview()
|
||||
bottomView?.removeFromSuperview()
|
||||
topView = viewForTop()
|
||||
bottomView = viewForBottom()
|
||||
if topViewOutsideOfScrollArea {
|
||||
topConstraint?.isActive = false
|
||||
addTopViewOutside()
|
||||
} else {
|
||||
topConstraint?.isActive = true
|
||||
}
|
||||
if bottomViewOutsideOfScrollArea {
|
||||
bottomConstraint?.isActive = false
|
||||
addBottomViewOutside()
|
||||
} else {
|
||||
bottomConstraint?.isActive = true
|
||||
}
|
||||
reloadCollectionData()
|
||||
}
|
||||
|
||||
@ -176,14 +208,14 @@ import Foundation
|
||||
open func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
|
||||
if kind == UICollectionView.elementKindSectionFooter,
|
||||
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: footerID, for: indexPath) as? ContainerCollectionReusableView {
|
||||
let bottomView = self.bottomView ?? MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
let bottomView = (bottomViewOutsideOfScrollArea ? nil : self.bottomView) ?? MVMCoreUICommonViewsUtility.getView(with: 0.5)
|
||||
footerView.addAndContain(view: bottomView)
|
||||
footerView.topConstraint?.constant = spaceAboveBottomView() ?? 0
|
||||
self.footerView = footerView
|
||||
return footerView
|
||||
} else if kind == UICollectionView.elementKindSectionHeader,
|
||||
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerID, for: indexPath) as? ContainerCollectionReusableView {
|
||||
let topView = self.topView ?? MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
let topView = (topViewOutsideOfScrollArea ? nil : self.topView) ?? MVMCoreUICommonViewsUtility.getView(with: 0.5)
|
||||
headerView.addAndContain(view: topView)
|
||||
headerView.bottomConstraint?.constant = spaceBelowTopView() ?? 0
|
||||
self.headerView = headerView
|
||||
|
||||
@ -117,22 +117,20 @@ extension ThreeLayerViewController {
|
||||
if let topView = viewForTop() {
|
||||
self.topView = topView
|
||||
} else {
|
||||
topView = MVMCoreUICommonViewsUtility.commonView()
|
||||
topView?.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
topView = MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
}
|
||||
guard var topView = topView else { return nil }
|
||||
|
||||
// Adds the top view outside the scroll if directed.
|
||||
if topViewOutsideOfScroll {
|
||||
topConstraint?.isActive = false;
|
||||
topConstraint?.isActive = false
|
||||
addViewOutsideOfScrollViewTop(topView)
|
||||
|
||||
// Adds and returns an empty view to use for the internal logic.
|
||||
topView = MVMCoreUICommonViewsUtility.commonView()
|
||||
topView.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
topView = MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
addViewInsideOfScrollViewTop(topView)
|
||||
} else {
|
||||
topConstraint?.isActive = true;
|
||||
topConstraint?.isActive = true
|
||||
addViewInsideOfScrollViewTop(topView)
|
||||
}
|
||||
return topView
|
||||
@ -142,8 +140,7 @@ extension ThreeLayerViewController {
|
||||
if let middleView = viewForMiddle() {
|
||||
self.middleView = middleView
|
||||
} else {
|
||||
middleView = MVMCoreUICommonViewsUtility.commonView()
|
||||
middleView?.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
middleView = MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
}
|
||||
guard let middleView = middleView, let contentView = contentView else { return nil }
|
||||
contentView.addSubview(middleView)
|
||||
@ -157,8 +154,7 @@ extension ThreeLayerViewController {
|
||||
if let bottomView = viewForBottom() {
|
||||
self.bottomView = bottomView
|
||||
} else {
|
||||
bottomView = MVMCoreUICommonViewsUtility.commonView()
|
||||
bottomView?.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
bottomView = MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
}
|
||||
guard var bottomView = bottomView else { return nil }
|
||||
|
||||
@ -168,8 +164,7 @@ extension ThreeLayerViewController {
|
||||
addViewOutsideOfScrollViewBottom(bottomView)
|
||||
|
||||
// Adds and returns an empty view to use for the internal logic.
|
||||
bottomView = MVMCoreUICommonViewsUtility.commonView()
|
||||
bottomView.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
bottomView = MVMCoreUICommonViewsUtility.getView(with: 0)
|
||||
addViewInsideOfScrollViewBottom(bottomView)
|
||||
} else {
|
||||
bottomConstraint?.isActive = true;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user