如何隐藏UIContextMenuInteraction/UITargetedPreview黑色背景?
How to hide UIContextMenuInteraction/UITargetedPreview black background?
我想将 UIContextMenuInteraction 添加到具有一些透明部分的 UIView。当用户与此视图交互时,iOS 以黑色背景显示此视图。
是否可以使这些部分透明或更改颜色?
终于找到解决办法了!
如果你想显示一个自定义的曲线,你需要实现这个功能:
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
let previewTarget = UIPreviewTarget(container: self.view, center: center)
let previewParams = UIPreviewParameters()
var topLeft : CGFloat = 8
var topRight : CGFloat = 9
var bottomRight : CGFloat = 10
var bottomLeft : CGFloat = 11
let topLeftRadius = CGSize(width: topLeft, height: topLeft)
let topRightRadius = CGSize(width: topRight, height: topRight)
let bottomLeftRadius = CGSize(width: bottomLeft, height: bottomLeft)
let bottomRightRadius = CGSize(width: bottomRight, height: bottomRight)
previewParams.visiblePath = UIBezierPath(shouldRoundRect: TheExactRectYouWantToShow, topLeftRadius: topLeftRadius, topRightRadius: topRightRadius, bottomLeftRadius: bottomLeftRadius, bottomRightRadius: bottomRightRadius)
let targetView = UITargetedPreview(view: YourViewToShow, parameters: previewParams, target: previewTarget)
return targetView
}
在这里,我们围绕自定义形状的视图绘制了一个 UIBezierPath。为此,您可能还需要此扩展程序:
extension UIBezierPath {
convenience init(shouldRoundRect rect: CGRect, topLeftRadius: CGSize = .zero, topRightRadius: CGSize = .zero, bottomLeftRadius: CGSize = .zero, bottomRightRadius: CGSize = .zero){
self.init()
let path = CGMutablePath()
let topLeft = rect.origin
let topRight = CGPoint(x: rect.maxX, y: rect.minY)
let bottomRight = CGPoint(x: rect.maxX, y: rect.maxY)
let bottomLeft = CGPoint(x: rect.minX, y: rect.maxY)
if topLeftRadius != .zero{
path.move(to: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y))
} else {
path.move(to: CGPoint(x: topLeft.x, y: topLeft.y))
}
if topRightRadius != .zero{
path.addLine(to: CGPoint(x: topRight.x-topRightRadius.width, y: topRight.y))
path.addCurve(to: CGPoint(x: topRight.x, y: topRight.y+topRightRadius.height), control1: CGPoint(x: topRight.x, y: topRight.y), control2:CGPoint(x: topRight.x, y: topRight.y+topRightRadius.height))
} else {
path.addLine(to: CGPoint(x: topRight.x, y: topRight.y))
}
if bottomRightRadius != .zero{
path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y-bottomRightRadius.height))
path.addCurve(to: CGPoint(x: bottomRight.x-bottomRightRadius.width, y: bottomRight.y), control1: CGPoint(x: bottomRight.x, y: bottomRight.y), control2: CGPoint(x: bottomRight.x-bottomRightRadius.width, y: bottomRight.y))
} else {
path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y))
}
if bottomLeftRadius != .zero{
path.addLine(to: CGPoint(x: bottomLeft.x+bottomLeftRadius.width, y: bottomLeft.y))
path.addCurve(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius.height), control1: CGPoint(x: bottomLeft.x, y: bottomLeft.y), control2: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius.height))
} else {
path.addLine(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y))
}
if topLeftRadius != .zero{
path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y+topLeftRadius.height))
path.addCurve(to: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y) , control1: CGPoint(x: topLeft.x, y: topLeft.y) , control2: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y))
} else {
path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y))
}
path.closeSubpath()
cgPath = path
}
还有这个:
extension UIView {
func roundCorners(topLeft: CGFloat = 0, topRight: CGFloat = 0, bottomLeft: CGFloat = 0, bottomRight: CGFloat = 0) {//(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) {
let topLeftRadius = CGSize(width: topLeft, height: topLeft)
let topRightRadius = CGSize(width: topRight, height: topRight)
let bottomLeftRadius = CGSize(width: bottomLeft, height: bottomLeft)
let bottomRightRadius = CGSize(width: bottomRight, height: bottomRight)
let maskPath = UIBezierPath(shouldRoundRect: bounds, topLeftRadius: topLeftRadius, topRightRadius: topRightRadius, bottomLeftRadius: bottomLeftRadius, bottomRightRadius: bottomRightRadius)
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
layer.mask = shape
}
}
更改上下文菜单背景颜色的更简单解决方案
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
let previewTarget = UIPreviewTarget(container: self, center: <#your-view>.center)
let previewParams = UIPreviewParameters()
previewParams.backgroundColor = .clear
return UITargetedPreview(view: <#your-view>, parameters: previewParams, target: previewTarget)
}
如所说,您可以使用previewForHighlightingContextMenuWithConfiguration
和previewForDismissingContextMenuWithConfiguration
委托方法创建您自己的UITargetedPreview并将其背景颜色设置为清除。
func collectionView(_ collectionView: UICollectionView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview?
{
guard let indexPath = configuration.identifier as? IndexPath,
let cell = collectionView.cellForItem(at: indexPath)
else
{
return nil
}
let targetedPreview = UITargetedPreview(view: cell)
targetedPreview.parameters.backgroundColor = .clear
return targetedPreview
}
func collectionView(_ collectionView: UICollectionView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview?
{
guard let indexPath = configuration.identifier as? IndexPath,
let cell = collectionView.cellForItem(at: indexPath)
else
{
return nil
}
let targetedPreview = UITargetedPreview(view: cell)
targetedPreview.parameters.backgroundColor = .clear
return targetedPreview
}
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration?
{
return UIContextMenuConfiguration(identifier: NSIndexPath(item: indexPath.item, section: indexPath.section), previewProvider: nil) { elements -> UIMenu? in
....
注意:我们将 NSIndexPath
作为标识符传递,因为它需要符合 NSCopying
协议。
我想将 UIContextMenuInteraction 添加到具有一些透明部分的 UIView。当用户与此视图交互时,iOS 以黑色背景显示此视图。
是否可以使这些部分透明或更改颜色?
终于找到解决办法了! 如果你想显示一个自定义的曲线,你需要实现这个功能:
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
let previewTarget = UIPreviewTarget(container: self.view, center: center)
let previewParams = UIPreviewParameters()
var topLeft : CGFloat = 8
var topRight : CGFloat = 9
var bottomRight : CGFloat = 10
var bottomLeft : CGFloat = 11
let topLeftRadius = CGSize(width: topLeft, height: topLeft)
let topRightRadius = CGSize(width: topRight, height: topRight)
let bottomLeftRadius = CGSize(width: bottomLeft, height: bottomLeft)
let bottomRightRadius = CGSize(width: bottomRight, height: bottomRight)
previewParams.visiblePath = UIBezierPath(shouldRoundRect: TheExactRectYouWantToShow, topLeftRadius: topLeftRadius, topRightRadius: topRightRadius, bottomLeftRadius: bottomLeftRadius, bottomRightRadius: bottomRightRadius)
let targetView = UITargetedPreview(view: YourViewToShow, parameters: previewParams, target: previewTarget)
return targetView
}
在这里,我们围绕自定义形状的视图绘制了一个 UIBezierPath。为此,您可能还需要此扩展程序:
extension UIBezierPath {
convenience init(shouldRoundRect rect: CGRect, topLeftRadius: CGSize = .zero, topRightRadius: CGSize = .zero, bottomLeftRadius: CGSize = .zero, bottomRightRadius: CGSize = .zero){
self.init()
let path = CGMutablePath()
let topLeft = rect.origin
let topRight = CGPoint(x: rect.maxX, y: rect.minY)
let bottomRight = CGPoint(x: rect.maxX, y: rect.maxY)
let bottomLeft = CGPoint(x: rect.minX, y: rect.maxY)
if topLeftRadius != .zero{
path.move(to: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y))
} else {
path.move(to: CGPoint(x: topLeft.x, y: topLeft.y))
}
if topRightRadius != .zero{
path.addLine(to: CGPoint(x: topRight.x-topRightRadius.width, y: topRight.y))
path.addCurve(to: CGPoint(x: topRight.x, y: topRight.y+topRightRadius.height), control1: CGPoint(x: topRight.x, y: topRight.y), control2:CGPoint(x: topRight.x, y: topRight.y+topRightRadius.height))
} else {
path.addLine(to: CGPoint(x: topRight.x, y: topRight.y))
}
if bottomRightRadius != .zero{
path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y-bottomRightRadius.height))
path.addCurve(to: CGPoint(x: bottomRight.x-bottomRightRadius.width, y: bottomRight.y), control1: CGPoint(x: bottomRight.x, y: bottomRight.y), control2: CGPoint(x: bottomRight.x-bottomRightRadius.width, y: bottomRight.y))
} else {
path.addLine(to: CGPoint(x: bottomRight.x, y: bottomRight.y))
}
if bottomLeftRadius != .zero{
path.addLine(to: CGPoint(x: bottomLeft.x+bottomLeftRadius.width, y: bottomLeft.y))
path.addCurve(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius.height), control1: CGPoint(x: bottomLeft.x, y: bottomLeft.y), control2: CGPoint(x: bottomLeft.x, y: bottomLeft.y-bottomLeftRadius.height))
} else {
path.addLine(to: CGPoint(x: bottomLeft.x, y: bottomLeft.y))
}
if topLeftRadius != .zero{
path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y+topLeftRadius.height))
path.addCurve(to: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y) , control1: CGPoint(x: topLeft.x, y: topLeft.y) , control2: CGPoint(x: topLeft.x+topLeftRadius.width, y: topLeft.y))
} else {
path.addLine(to: CGPoint(x: topLeft.x, y: topLeft.y))
}
path.closeSubpath()
cgPath = path
}
还有这个:
extension UIView {
func roundCorners(topLeft: CGFloat = 0, topRight: CGFloat = 0, bottomLeft: CGFloat = 0, bottomRight: CGFloat = 0) {//(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) {
let topLeftRadius = CGSize(width: topLeft, height: topLeft)
let topRightRadius = CGSize(width: topRight, height: topRight)
let bottomLeftRadius = CGSize(width: bottomLeft, height: bottomLeft)
let bottomRightRadius = CGSize(width: bottomRight, height: bottomRight)
let maskPath = UIBezierPath(shouldRoundRect: bounds, topLeftRadius: topLeftRadius, topRightRadius: topRightRadius, bottomLeftRadius: bottomLeftRadius, bottomRightRadius: bottomRightRadius)
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
layer.mask = shape
}
}
更改上下文菜单背景颜色的更简单解决方案
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, previewForHighlightingMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
let previewTarget = UIPreviewTarget(container: self, center: <#your-view>.center)
let previewParams = UIPreviewParameters()
previewParams.backgroundColor = .clear
return UITargetedPreview(view: <#your-view>, parameters: previewParams, target: previewTarget)
}
如previewForHighlightingContextMenuWithConfiguration
和previewForDismissingContextMenuWithConfiguration
委托方法创建您自己的UITargetedPreview并将其背景颜色设置为清除。
func collectionView(_ collectionView: UICollectionView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview?
{
guard let indexPath = configuration.identifier as? IndexPath,
let cell = collectionView.cellForItem(at: indexPath)
else
{
return nil
}
let targetedPreview = UITargetedPreview(view: cell)
targetedPreview.parameters.backgroundColor = .clear
return targetedPreview
}
func collectionView(_ collectionView: UICollectionView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview?
{
guard let indexPath = configuration.identifier as? IndexPath,
let cell = collectionView.cellForItem(at: indexPath)
else
{
return nil
}
let targetedPreview = UITargetedPreview(view: cell)
targetedPreview.parameters.backgroundColor = .clear
return targetedPreview
}
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration?
{
return UIContextMenuConfiguration(identifier: NSIndexPath(item: indexPath.item, section: indexPath.section), previewProvider: nil) { elements -> UIMenu? in
....
注意:我们将 NSIndexPath
作为标识符传递,因为它需要符合 NSCopying
协议。