add anchor logic to table three layer and list
Safe area for scrollview remove safeAreaView itself for now until requirement comes in
This commit is contained in:
parent
a697fea926
commit
9366469f35
@ -81,6 +81,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override func handleNewData() {
|
open override func handleNewData() {
|
||||||
|
topViewOutsideOfScrollArea = templateModel?.anchorHeader ?? false
|
||||||
|
bottomViewOutsideOfScrollArea = templateModel?.anchorFooter ?? false
|
||||||
setup()
|
setup()
|
||||||
registerWithTable()
|
registerWithTable()
|
||||||
super.handleNewData()
|
super.handleNewData()
|
||||||
|
|||||||
@ -39,11 +39,13 @@ open class ProgrammaticScrollViewController: ScrollingViewController {
|
|||||||
topConstraint = constraints?[ConstraintTop] as? NSLayoutConstraint
|
topConstraint = constraints?[ConstraintTop] as? NSLayoutConstraint
|
||||||
bottomConstraint = constraints?[ConstraintBot] as? NSLayoutConstraint
|
bottomConstraint = constraints?[ConstraintBot] as? NSLayoutConstraint
|
||||||
|
|
||||||
|
// Sets the constraints for the content view
|
||||||
let contentView = MVMCoreUICommonViewsUtility.commonView()
|
let contentView = MVMCoreUICommonViewsUtility.commonView()
|
||||||
scrollView.addSubview(contentView)
|
scrollView.addSubview(contentView)
|
||||||
|
contentView.leftAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.leftAnchor).isActive = true
|
||||||
// Sets the constraints for the content view
|
scrollView.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: contentView)
|
contentView.topAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.topAnchor).isActive = true
|
||||||
|
scrollView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
|
||||||
|
|
||||||
// Super will set later.
|
// Super will set later.
|
||||||
contentWidthConstraint = contentView.widthAnchor.constraint(equalToConstant: 320.0)
|
contentWidthConstraint = contentView.widthAnchor.constraint(equalToConstant: 320.0)
|
||||||
|
|||||||
@ -15,9 +15,9 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
private var bottomView: UIView?
|
private var bottomView: UIView?
|
||||||
private var headerView: UIView?
|
private var headerView: UIView?
|
||||||
private var footerView: UIView?
|
private var footerView: UIView?
|
||||||
private var safeAreaView: UIView?
|
|
||||||
var useMargins: Bool = true
|
var useMargins: Bool = true
|
||||||
public var bottomViewOutsideOfScrollArea: Bool = false
|
public var bottomViewOutsideOfScrollArea: Bool = false
|
||||||
|
public var topViewOutsideOfScrollArea: Bool = false
|
||||||
private var topViewBottomConstraint: NSLayoutConstraint?
|
private var topViewBottomConstraint: NSLayoutConstraint?
|
||||||
private var bottomViewTopConstraint: NSLayoutConstraint?
|
private var bottomViewTopConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
@ -76,14 +76,14 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
var totalMinimumSpace: CGFloat = 0
|
var totalMinimumSpace: CGFloat = 0
|
||||||
|
|
||||||
var fillTop = false
|
var fillTop = false
|
||||||
if spaceBelowTopView() == nil, self.tableView?.tableHeaderView != nil {
|
if spaceBelowTopView() == nil, tableView.tableHeaderView != nil {
|
||||||
fillTop = true
|
fillTop = true
|
||||||
currentSpace += topViewBottomConstraint?.constant ?? 0
|
currentSpace += topViewBottomConstraint?.constant ?? 0
|
||||||
totalMinimumSpace += minimumSpace
|
totalMinimumSpace += minimumSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
var fillBottom = false
|
var fillBottom = false
|
||||||
if spaceAboveBottomView() == nil, !bottomViewOutsideOfScrollArea, self.tableView?.tableFooterView != nil {
|
if spaceAboveBottomView() == nil, tableView.tableFooterView != nil {
|
||||||
fillBottom = true
|
fillBottom = true
|
||||||
currentSpace += bottomViewTopConstraint?.constant ?? 0
|
currentSpace += bottomViewTopConstraint?.constant ?? 0
|
||||||
totalMinimumSpace += minimumSpace
|
totalMinimumSpace += minimumSpace
|
||||||
@ -109,12 +109,7 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
showHeader(width)
|
showHeader(width)
|
||||||
showFooter(width)
|
showFooter(width)
|
||||||
} else if fillTop {
|
} 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.
|
topViewBottomConstraint?.constant = newSpace
|
||||||
if bottomViewOutsideOfScrollArea {
|
|
||||||
topViewBottomConstraint?.constant = newSpace / 2
|
|
||||||
} else {
|
|
||||||
topViewBottomConstraint?.constant = newSpace
|
|
||||||
}
|
|
||||||
showHeader(width)
|
showHeader(width)
|
||||||
} else if fillBottom {
|
} else if fillBottom {
|
||||||
// Only bottom is spaced.
|
// Only bottom is spaced.
|
||||||
@ -127,9 +122,14 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
//MARK: - Header Footer
|
//MARK: - Header Footer
|
||||||
/// Gets the top view and adds it to a spacing view, headerView, and then calls showHeader.
|
/// Gets the top view and adds it to a spacing view, headerView, and then calls showHeader.
|
||||||
open func createViewForTableHeader() {
|
open func createViewForTableHeader() {
|
||||||
let topView = viewForTop()
|
var topView = viewForTop()
|
||||||
self.topView = topView
|
self.topView = topView
|
||||||
|
|
||||||
|
// If top view is outside of scroll area, create a dummy view for the header.
|
||||||
|
if topViewOutsideOfScrollArea {
|
||||||
|
topView = MVMCoreUICommonViewsUtility.commonView()
|
||||||
|
topView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
|
||||||
|
}
|
||||||
let headerView = MVMCoreUICommonViewsUtility.commonView()
|
let headerView = MVMCoreUICommonViewsUtility.commonView()
|
||||||
headerView.addSubview(topView)
|
headerView.addSubview(topView)
|
||||||
topView.topAnchor.constraint(equalTo: headerView.topAnchor).isActive = true
|
topView.topAnchor.constraint(equalTo: headerView.topAnchor).isActive = true
|
||||||
@ -143,9 +143,14 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
|
|
||||||
/// Gets the bottom view and adds it to a spacing view, footerView, and then calls showFooter.
|
/// Gets the bottom view and adds it to a spacing view, footerView, and then calls showFooter.
|
||||||
open func createViewForTableFooter() {
|
open func createViewForTableFooter() {
|
||||||
let bottomView = viewForBottom()
|
var bottomView = viewForBottom()
|
||||||
self.bottomView = bottomView
|
self.bottomView = bottomView
|
||||||
|
|
||||||
|
// If bottom view is outside of scroll area, create a dummy view for the header.
|
||||||
|
if bottomViewOutsideOfScrollArea {
|
||||||
|
bottomView = MVMCoreUICommonViewsUtility.commonView()
|
||||||
|
bottomView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
|
||||||
|
}
|
||||||
let footerView = MVMCoreUICommonViewsUtility.commonView()
|
let footerView = MVMCoreUICommonViewsUtility.commonView()
|
||||||
footerView.addSubview(bottomView)
|
footerView.addSubview(bottomView)
|
||||||
bottomViewTopConstraint = bottomView.topAnchor.constraint(equalTo: footerView.topAnchor, constant: spaceAboveBottomView() ?? 0)
|
bottomViewTopConstraint = bottomView.topAnchor.constraint(equalTo: footerView.topAnchor, constant: spaceAboveBottomView() ?? 0)
|
||||||
@ -161,10 +166,20 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
func showHeader(_ sizingWidth: CGFloat?) {
|
func showHeader(_ sizingWidth: CGFloat?) {
|
||||||
headerView?.removeFromSuperview()
|
headerView?.removeFromSuperview()
|
||||||
tableView?.tableHeaderView = nil
|
tableView?.tableHeaderView = nil
|
||||||
guard let headerView = headerView else {
|
guard let topView = topView,
|
||||||
return
|
let headerView = headerView else { return }
|
||||||
}
|
|
||||||
|
|
||||||
|
if topViewOutsideOfScrollArea {
|
||||||
|
// put top view outside of scrolling area.
|
||||||
|
topConstraint?.isActive = false
|
||||||
|
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
|
||||||
|
tableView.topAnchor.constraint(equalTo: topView.bottomAnchor).isActive = true
|
||||||
|
} else {
|
||||||
|
topConstraint?.isActive = true
|
||||||
|
}
|
||||||
// This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout.
|
// This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout.
|
||||||
headerView.setNeedsLayout()
|
headerView.setNeedsLayout()
|
||||||
headerView.layoutIfNeeded()
|
headerView.layoutIfNeeded()
|
||||||
@ -173,41 +188,42 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController {
|
|||||||
tableHeaderView.addSubview(headerView)
|
tableHeaderView.addSubview(headerView)
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: headerView)
|
NSLayoutConstraint.constraintPinSubview(toSuperview: headerView)
|
||||||
tableView?.tableHeaderView = tableHeaderView
|
tableView?.tableHeaderView = tableHeaderView
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the current footerView and adds it to the tableFooterView
|
/// Takes the current footerView and adds it to the tableFooterView
|
||||||
func showFooter(_ sizingWidth: CGFloat?) {
|
func showFooter(_ sizingWidth: CGFloat?) {
|
||||||
footerView?.removeFromSuperview()
|
footerView?.removeFromSuperview()
|
||||||
safeAreaView?.removeFromSuperview()
|
guard let bottomView = bottomView,
|
||||||
guard let footerView = footerView, let tableView = tableView else {
|
let footerView = footerView,
|
||||||
return
|
let tableView = tableView else {
|
||||||
|
self.tableView?.tableFooterView = nil
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if bottomViewOutsideOfScrollArea {
|
if bottomViewOutsideOfScrollArea {
|
||||||
// put bottom view outside of scrolling area.
|
// put bottom view outside of scrolling area.
|
||||||
bottomConstraint?.isActive = false
|
bottomConstraint?.isActive = false
|
||||||
view.addSubview(footerView)
|
view.addSubview(bottomView)
|
||||||
footerView.topAnchor.constraint(equalTo: tableView.bottomAnchor).isActive = true
|
bottomView.topAnchor.constraint(equalTo: tableView.bottomAnchor).isActive = true
|
||||||
footerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
|
bottomView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
|
||||||
view.rightAnchor.constraint(equalTo: footerView.rightAnchor).isActive = true
|
view.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: bottomView.rightAnchor).isActive = true
|
||||||
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: footerView.bottomAnchor).isActive = true
|
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: bottomView.bottomAnchor).isActive = true
|
||||||
safeAreaView = MVMCoreUICommonViewsUtility.getAndSetupSafeAreaView(on: view)
|
|
||||||
safeAreaView?.backgroundColor = bottomView?.backgroundColor
|
|
||||||
} else {
|
} else {
|
||||||
bottomConstraint?.isActive = true
|
bottomConstraint?.isActive = true
|
||||||
var y: CGFloat?
|
|
||||||
if let tableFooterView = tableView.tableFooterView {
|
|
||||||
// if footer already exists, use the same y location to avoid strange moving animation
|
|
||||||
y = tableFooterView.frame.minY
|
|
||||||
}
|
|
||||||
|
|
||||||
// This extra view is needed because of the wonkiness of apple's table footer. Things breaks if using autolayout.
|
|
||||||
MVMCoreUIUtility.sizeView(toFit: footerView)
|
|
||||||
let tableFooterView = UIView(frame: CGRect(x: 0, y: y ?? 0, width: MVMCoreUIUtility.getWidth(), height: footerView.frame.height))
|
|
||||||
tableFooterView.addSubview(footerView)
|
|
||||||
NSLayoutConstraint.constraintPinSubview(toSuperview: footerView)
|
|
||||||
tableView.tableFooterView = tableFooterView
|
|
||||||
}
|
}
|
||||||
|
var y: CGFloat?
|
||||||
|
if let tableFooterView = tableView.tableFooterView {
|
||||||
|
// if footer already exists, use the same y location to avoid strange moving animation
|
||||||
|
y = tableFooterView.frame.minY
|
||||||
|
}
|
||||||
|
|
||||||
|
// This extra view is needed because of the wonkiness of apple's table footer. Things breaks if using autolayout.
|
||||||
|
MVMCoreUIUtility.sizeView(toFit: footerView)
|
||||||
|
let tableFooterView = UIView(frame: CGRect(x: 0, y: y ?? 0, width: MVMCoreUIUtility.getWidth(), height: footerView.frame.height))
|
||||||
|
tableFooterView.addSubview(footerView)
|
||||||
|
NSLayoutConstraint.constraintPinSubview(toSuperview: footerView)
|
||||||
|
tableView.tableFooterView = tableFooterView
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - Functions to subclass
|
//MARK: - Functions to subclass
|
||||||
|
|||||||
@ -24,7 +24,6 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
|
|||||||
// The bottom view can be put outside of the scrolling area.
|
// The bottom view can be put outside of the scrolling area.
|
||||||
var bottomViewOutsideOfScroll = false
|
var bottomViewOutsideOfScroll = false
|
||||||
|
|
||||||
private var safeAreaView: UIView?
|
|
||||||
var heightConstraint: NSLayoutConstraint?
|
var heightConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
open override func updateViews() {
|
open override func updateViews() {
|
||||||
@ -71,7 +70,6 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
|
|||||||
topView?.removeFromSuperview()
|
topView?.removeFromSuperview()
|
||||||
middleView?.removeFromSuperview()
|
middleView?.removeFromSuperview()
|
||||||
bottomView?.removeFromSuperview()
|
bottomView?.removeFromSuperview()
|
||||||
safeAreaView?.removeFromSuperview()
|
|
||||||
if let subViews = contentView?.subviews {
|
if let subViews = contentView?.subviews {
|
||||||
for view in subViews {
|
for view in subViews {
|
||||||
view.removeFromSuperview()
|
view.removeFromSuperview()
|
||||||
@ -266,10 +264,6 @@ extension ThreeLayerViewController {
|
|||||||
NSLayoutConstraint.pinViewLeft(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
|
NSLayoutConstraint.pinViewLeft(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
|
||||||
NSLayoutConstraint.pinViewRight(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
|
NSLayoutConstraint.pinViewRight(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true
|
||||||
parentView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
parentView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||||
if let safeAreaView = MVMCoreUICommonViewsUtility.getAndSetupSafeAreaView(on: parentView) {
|
|
||||||
safeAreaView.backgroundColor = bottomView?.backgroundColor
|
|
||||||
self.safeAreaView = safeAreaView
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user