Skip to content

Commit

Permalink
💲[Native Checkout] Sheet Overlay Container (#674)
Browse files Browse the repository at this point in the history
* Sheet overlay container VC and animator

* Renaming, fixing rotation issues

* Revert testing code

* Cleanup and fixing a snapshot

* Using keypath lenses

* Updating the comment

* PR comments

* Renaming

* Cleanup

* View helpers

* Style naming

* Fix build

* Remove iOS 11 Availability Checks From Native Checkout (#679)

* Remove iOS 11 availability references

* Fix merge conflict issues

* Renaming suggestions

* Swiftlint
  • Loading branch information
Isabel Barrera authored and ifbarrera committed Aug 6, 2019
1 parent 7f2e6b7 commit ddf9bcc
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 92 deletions.
11 changes: 2 additions & 9 deletions Kickstarter-iOS/Views/Cells/PledgeDescriptionCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,8 @@ final class PledgeDescriptionCell: UITableViewCell, ValueCell {
_ = (views, self.descriptionStackView)
|> ksr_addArrangedSubviewsToStackView()

if #available(iOS 11.0, *) {
self.descriptionStackView.setCustomSpacing(10.0, after: self.dateLabel)
} else {
let view: UIView = {
return UIView(frame: .zero) |> \.translatesAutoresizingMaskIntoConstraints .~ false
}()
view.heightAnchor.constraint(equalToConstant: Layout.SpacerView.height).isActive = true
self.descriptionStackView.insertArrangedSubview(view, at: 3)
}
self.descriptionStackView.setCustomSpacing(10.0, after: self.dateLabel)

_ = ([self.descriptionStackView], self.rootStackView)
|> ksr_addArrangedSubviewsToStackView()
}
Expand Down
11 changes: 0 additions & 11 deletions Kickstarter-iOS/Views/Controllers/PledgeTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,5 @@ private func tableViewStyle(_ tableView: UITableView) -> UITableView {
|> \.sectionFooterHeight .~ PledgeFooterView.defaultHeight
|> \.sectionHeaderHeight .~ 0

if #available(iOS 11, *) { } else {
let estimatedHeight: CGFloat = 44

return style
|> \.contentInset .~ UIEdgeInsets(top: 30)
|> \.estimatedSectionFooterHeight .~ estimatedHeight
|> \.estimatedSectionHeaderHeight .~ estimatedHeight
|> \.estimatedRowHeight .~ estimatedHeight
|> \.rowHeight .~ UITableView.automaticDimension
}

return style
}
100 changes: 39 additions & 61 deletions Kickstarter-iOS/Views/Controllers/ProjectPamphletViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,6 @@ public final class ProjectPamphletViewController: UIViewController {
|> \.translatesAutoresizingMaskIntoConstraints .~ false
}()

private let backThisProjectContainerSublayer: CAShapeLayer = {
let mask = CAShapeLayer()
|> \.fillColor .~ UIColor.white.cgColor
|> \.shadowColor .~ UIColor.black.cgColor
|> \.shadowOpacity .~ 0.12
|> \.shadowOffset .~ CGSize(width: 0, height: -1.0)
|> \.shadowRadius .~ 1.0

return mask
}()

public static func configuredWith(projectOrParam: Either<Project, Param>,
refTag: RefTag?) -> ProjectPamphletViewController {

Expand Down Expand Up @@ -84,7 +73,6 @@ public final class ProjectPamphletViewController: UIViewController {
constant: initialTopConstraint)

if self.shouldShowNativeCheckout() {
self.configureSublayers()
self.updateContentInsets()
}
}
Expand All @@ -102,41 +90,21 @@ public final class ProjectPamphletViewController: UIViewController {
}
}

private func configureViews() {
// Configure subviews
self.backThisProjectContainerView.addSubview(self.backThisProjectButton)

self.view.addSubview(self.backThisProjectContainerView)

self.backThisProjectButton.addTarget(self, action: #selector(backThisProjectTapped), for: .touchUpInside)

// Configure constraints
let backThisProjectContainerViewConstraints = [
self.backThisProjectContainerView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
self.backThisProjectContainerView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
self.backThisProjectContainerView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
]

let containerMargins = self.backThisProjectContainerView.layoutMarginsGuide
let minHeight = Styles.minTouchSize.height

let backThisProjectButtonConstraints = [
self.backThisProjectButton.leftAnchor.constraint(equalTo: containerMargins.leftAnchor),
self.backThisProjectButton.rightAnchor.constraint(equalTo: containerMargins.rightAnchor),
self.backThisProjectButton.bottomAnchor.constraint(equalTo: containerMargins.bottomAnchor),
self.backThisProjectButton.topAnchor.constraint(equalTo: containerMargins.topAnchor),
self.backThisProjectButton.heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight)
]

NSLayoutConstraint.activate(backThisProjectContainerViewConstraints + backThisProjectButtonConstraints)
}

public override func bindStyles() {
super.bindStyles()

_ = self.backThisProjectContainerView
|> \.layoutMargins .~ .init(all: backThisProjectContainerViewMargins)

_ = self.backThisProjectContainerView.layer
|> checkoutLayerCardRoundedStyle
|> \.backgroundColor .~ UIColor.white.cgColor
|> \.shadowColor .~ UIColor.black.cgColor
|> \.shadowOpacity .~ 0.12
|> \.shadowOffset .~ CGSize(width: 0, height: -1.0)
|> \.shadowRadius .~ 1.0
|> \.maskedCorners .~ [.layerMaxXMinYCorner, .layerMinXMinYCorner]

_ = self.backThisProjectButton
|> checkoutGreenButtonStyle
|> UIButton.lens.title(for: .normal) %~ { _ in
Expand Down Expand Up @@ -188,19 +156,39 @@ public final class ProjectPamphletViewController: UIViewController {
}

// MARK: - Private View Setup Functions
private func configureSublayers() {
let updatedPath = UIBezierPath(roundedRect: self.backThisProjectContainerView.bounds,
byRoundingCorners: [.topLeft, .topRight],
cornerRadii: CGSize(width: 16, height: 16))

_ = self.backThisProjectContainerSublayer
|> \.path .~ updatedPath.cgPath
private func configureViews() {
_ = (self.backThisProjectButton, self.backThisProjectContainerView)
|> ksr_addSubviewToParent()

if self.backThisProjectContainerView.layer.sublayers?.count == 1 {
self.backThisProjectContainerView.layer.insertSublayer(self.backThisProjectContainerSublayer, at: 0)
}
_ = (self.backThisProjectContainerView, self.view)
|> ksr_addSubviewToParent()

self.backThisProjectButton.addTarget(self, action: #selector(backThisProjectTapped), for: .touchUpInside)

// Configure constraints
let backThisProjectContainerViewConstraints = [
self.backThisProjectContainerView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
self.backThisProjectContainerView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
self.backThisProjectContainerView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
]

let containerMargins = self.backThisProjectContainerView.layoutMarginsGuide
let minHeight = Styles.minTouchSize.height

let backThisProjectButtonConstraints = [
self.backThisProjectButton.leftAnchor.constraint(equalTo: containerMargins.leftAnchor),
self.backThisProjectButton.rightAnchor.constraint(equalTo: containerMargins.rightAnchor),
self.backThisProjectButton.bottomAnchor.constraint(equalTo: containerMargins.bottomAnchor),
self.backThisProjectButton.topAnchor.constraint(equalTo: containerMargins.topAnchor),
self.backThisProjectButton.heightAnchor.constraint(greaterThanOrEqualToConstant: minHeight)
]

NSLayoutConstraint.activate(backThisProjectContainerViewConstraints + backThisProjectButtonConstraints)
}

// MARK: - Private Helpers

private func setInitial(constraints: [NSLayoutConstraint?], constant: CGFloat) {
constraints.forEach {
$0?.constant = constant
Expand All @@ -213,7 +201,6 @@ public final class ProjectPamphletViewController: UIViewController {
refTag: refTag)
}

// MARK: - Private Helpers
private func shouldShowNativeCheckout() -> Bool {
// Show native checkout only if the `ios_native_checkout` flag is enabled
return AppEnvironment.current.config?.features[Feature.checkout.rawValue] == .some(true)
Expand All @@ -223,16 +210,7 @@ public final class ProjectPamphletViewController: UIViewController {
let buttonSize = self.backThisProjectButton.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
let bottomInset = buttonSize.height + 2 * self.backThisProjectContainerViewMargins

if #available(iOS 11.0, *) {
self.contentController.additionalSafeAreaInsets = UIEdgeInsets(bottom: bottomInset)
} else {
let insets = self.contentController.tableView.contentInset

self.contentController.tableView.contentInset = UIEdgeInsets(top: insets.top,
left: insets.left,
bottom: bottomInset,
right: insets.right)
}
self.contentController.additionalSafeAreaInsets = UIEdgeInsets(bottom: bottomInset)
}

// MARK: - Selectors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal final class ProjectPamphletViewControllerTests: TestCase {
let (parent, _) = traitControllers(device: device, orientation: .portrait, child: vc)
parent.view.frame.size.height = device == .pad ? 1_200 : 800

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)", tolerance: 0.01)
}
}
}
Expand All @@ -79,7 +79,7 @@ internal final class ProjectPamphletViewControllerTests: TestCase {
let (parent, _) = traitControllers(device: device, orientation: .landscape, child: vc)
parent.view.frame.size.height = device == .pad ? 1_200 : parent.view.frame.size.height

FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)")
FBSnapshotVerifyView(vc.view, identifier: "lang_\(language)_device_\(device)", tolerance: 0.01)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,7 @@ final class RewardsCollectionViewController: UICollectionViewController {
let cardWidth = Layout.Card.width

let sectionInsets = layout.sectionInset
var adjustedContentInset = UIEdgeInsets.zero

if #available(iOS 11.0, *) {
adjustedContentInset = collectionView.adjustedContentInset
}
let adjustedContentInset = collectionView.adjustedContentInset

let topBottomSectionInsets = sectionInsets.top + sectionInsets.bottom
let topBottomContentInsets = adjustedContentInset.top + adjustedContentInset.bottom
Expand Down
79 changes: 79 additions & 0 deletions Kickstarter-iOS/Views/Controllers/SheetOverlayViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import UIKit
import Library
import Prelude

/**
SheetOverlayViewController is intended to be used as a container for another view controller
that renders as a "sheet" or "card" that partially covers the content beneath it.
*/

final class SheetOverlayViewController: UIViewController {
// MARK: - Properties

private let childViewController: UIViewController
private let offset: CGFloat
private let transitionAnimator = SheetOverlayTransitionAnimator()

init(child: UIViewController, offset: CGFloat = 45.0) {
self.childViewController = child
self.offset = offset

super.init(nibName: nil, bundle: nil)

_ = self
|> \.modalPresentationStyle .~ .custom
|> \.transitioningDelegate .~ self
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()

self.addChild(self.childViewController)
self.configure(childView: self.childViewController.view, offset: self.offset)

self.childViewController.didMove(toParent: self)
}

private func configure(childView: UIView, offset: CGFloat) {
_ = (childView, self.view)
|> ksr_addSubviewToParent()

_ = childView
|> \.translatesAutoresizingMaskIntoConstraints .~ false

_ = childView.layer
|> checkoutLayerCardRoundedStyle
|> \.masksToBounds .~ true
|> \.maskedCorners .~ [.layerMaxXMinYCorner, .layerMinXMinYCorner]

let isRegular = UIScreen.main.traitCollection.isRegularRegular
let portraitWidth = min(UIScreen.main.bounds.height, UIScreen.main.bounds.width)

NSLayoutConstraint.activate([childView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
childView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
childView.topAnchor.constraint(equalTo: self.view.topAnchor,
constant: offset)])

if isRegular {
childView.widthAnchor.constraint(equalToConstant: portraitWidth).isActive = true
} else {
childView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
}
}
}

extension SheetOverlayViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController,
source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return self.transitionAnimator
}

func animationController(forDismissed dismissed: UIViewController) ->
UIViewControllerAnimatedTransitioning? {
return self.transitionAnimator
}
}
Loading

0 comments on commit ddf9bcc

Please sign in to comment.