Skip to content

Commit

Permalink
Merge pull request #190 from SCENEE/fix-surface-mask
Browse files Browse the repository at this point in the history
Fix surface mask
  • Loading branch information
scenee authored Apr 17, 2019
2 parents e1185fd + 5888104 commit e480851
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 28 deletions.
2 changes: 1 addition & 1 deletion FloatingPanel.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The new interface displays the related contents and utilities in parallel as a u
s.source = { :git => "https://github.com/SCENEE/FloatingPanel.git", :tag => "v#{s.version}" }
s.source_files = "Framework/Sources/*.swift"
s.swift_version = "4.0"
s.pod_target_xcconfig = { 'SWIFT_WHOLE_MODULE_OPTIMIZATION' => 'YES', 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }

s.framework = "UIKit"

Expand Down
63 changes: 38 additions & 25 deletions Framework/Sources/FloatingPanelSurfaceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,19 @@ public class FloatingPanelSurfaceView: UIView {
/// The color of the surface border.
public var borderWidth: CGFloat = 0.0 { didSet { setNeedsLayout() } }


/// The view presents an actual surface shape.
///
/// It renders the background color, border line and top rounded corners,
/// specified by other properties. The reason why they're not be applied to
/// a content view directly is because it avoids any side-effects to the
/// content view.
public var containerView: UIView!

@available(*, unavailable, renamed: "containerView")
public var backgroundView: UIView!
private var backgroundHeightConstraint: NSLayoutConstraint!

private var containerViewHeightConstraint: NSLayoutConstraint!

private struct Default {
public static let grabberTopPadding: CGFloat = 6.0
Expand All @@ -80,20 +91,19 @@ public class FloatingPanelSurfaceView: UIView {
super.backgroundColor = .clear
self.clipsToBounds = false

let backgroundView = UIView()
addSubview(backgroundView)
self.backgroundView = backgroundView
let containerView = UIView()
addSubview(containerView)
self.containerView = containerView

backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundHeightConstraint = backgroundView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1.0)
containerView.translatesAutoresizingMaskIntoConstraints = false
containerViewHeightConstraint = containerView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1.0)
NSLayoutConstraint.activate([
backgroundView.topAnchor.constraint(equalTo: topAnchor, constant: 0.0),
backgroundView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0.0),
backgroundView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0.0),
backgroundHeightConstraint,
containerView.topAnchor.constraint(equalTo: topAnchor, constant: 0.0),
containerView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0.0),
containerView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0.0),
containerViewHeightConstraint,
])


let grabberHandle = GrabberHandleView()
addSubview(grabberHandle)
self.grabberHandle = grabberHandle
Expand All @@ -109,7 +119,7 @@ public class FloatingPanelSurfaceView: UIView {

public override func updateConstraints() {
super.updateConstraints()
backgroundHeightConstraint.constant = bottomOverflow
containerViewHeightConstraint.constant = bottomOverflow
}

public override func layoutSubviews() {
Expand All @@ -118,18 +128,17 @@ public class FloatingPanelSurfaceView: UIView {

updateLayers()
updateContentViewMask()
updateBorder()

contentView?.layer.borderColor = borderColor?.cgColor
contentView?.layer.borderWidth = borderWidth
contentView?.frame = bounds
}

private func updateLayers() {
backgroundView.backgroundColor = color
containerView.backgroundColor = color

if cornerRadius != 0.0, backgroundView.layer.cornerRadius != cornerRadius {
backgroundView.layer.masksToBounds = true
backgroundView.layer.cornerRadius = cornerRadius
if cornerRadius != 0.0, containerView.layer.cornerRadius != cornerRadius {
containerView.layer.masksToBounds = true
containerView.layer.cornerRadius = cornerRadius
}

if shadowHidden == false {
Expand All @@ -142,34 +151,38 @@ public class FloatingPanelSurfaceView: UIView {

private func updateContentViewMask() {
guard
let contentView = contentView,
cornerRadius != 0.0,
contentView.layer.cornerRadius != cornerRadius
containerView.layer.cornerRadius != cornerRadius
else { return }

if #available(iOS 11, *) {
// Don't use `contentView.clipToBounds` because it prevents content view from expanding the height of a subview of it
// for the bottom overflow like Auto Layout settings of UIVisualEffectView in Main.storyboard of Example/Maps.
// Because the bottom of contentView must be fit to the bottom of a screen to work the `safeLayoutGuide` of a content VC.
contentView.layer.masksToBounds = true
contentView.layer.cornerRadius = cornerRadius
contentView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
containerView.layer.masksToBounds = true
containerView.layer.cornerRadius = cornerRadius
containerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
} else {
// Don't use `contentView.layer.mask` because of a UIVisualEffectView issue in iOS 10, https://forums.developer.apple.com/thread/50854
// Instead, a user can mask the content view manually in an application.
}
}

private func updateBorder() {
containerView.layer.borderColor = borderColor?.cgColor
containerView.layer.borderWidth = borderWidth
}

func add(contentView: UIView) {
insertSubview(contentView, belowSubview: grabberHandle)
containerView.addSubview(contentView)
self.contentView = contentView
/* contentView.frame = bounds */ // MUST NOT: Because the top safe area inset of a content VC will be incorrect.
contentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: topAnchor, constant: 0.0),
contentView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0.0),
contentView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0.0),
contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0.0),
contentView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 1.0)
])
}
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,9 @@ You can show a floating panel over UINavigationController from the container vie
FloatingPanelController.view (FloatingPanelPassThroughView)
├─ .backdropView (FloatingPanelBackdropView)
└─ .surfaceView (FloatingPanelSurfaceView)
├─ .contentView == FloatingPanelController.contentViewController.view
└─ .grabberHandle (GrabberHandleView)
├─ .containerView (UIView)
│ └─ .contentView (FloatingPanelController.contentViewController.view)
└─ .grabberHandle (GrabberHandleView)
```

## Usage
Expand Down

0 comments on commit e480851

Please sign in to comment.