Как скрыть UIContextMenuInteraction / UITargetedPreview черный фон? - PullRequest
0 голосов
/ 07 января 2020

Я хочу добавить UIContextMenuInteraction в UIView с некоторыми прозрачными частями. Когда пользователь взаимодействует с этим видом, iOS показывает его с черным фоном.

enter image description here

Можно ли сделать эти части прозрачными или изменить цвет

1 Ответ

1 голос
/ 12 января 2020

Наконец я нашел решение! Вам необходимо реализовать эту функцию, если вы хотите отобразить пользовательскую кривую:

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
}
}
...