Маскирование формы пончика в UIImageView - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь вырезать форму пончика в UIImageView.В настоящее время я могу получить только вырез из круга, например:

import UIKit
import CoreGraphics

class AvatarImageView: UIImageView {

    enum AvatarImageViewOnlineStatus {
        case online
        case offline
        case hidden
    }

    var rounded: Bool = false
    var onlineStatus: AvatarImageViewOnlineStatus = .hidden

    override func layoutSubviews() {
        super.layoutSubviews()
        guard !rounded else { return }
        if let image = image, !rounded {
            self.image = image.af_imageRoundedIntoCircle()
            rounded = true
        }

        let rect: CGRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
        let maskLayer: CAShapeLayer = CAShapeLayer()
        maskLayer.frame = rect

        let mainPath: UIBezierPath = UIBezierPath(rect: rect)
        let circlePath: UIBezierPath = UIBezierPath(ovalIn: CGRect(x: 20, y: 20, width: 30, height: 30))
        mainPath.append(circlePath)

        maskLayer.fillRule = kCAFillRuleEvenOdd
        maskLayer.path = mainPath.cgPath
        maskLayer.strokeColor = UIColor.clear.cgColor
        maskLayer.lineWidth = 10.0
        layer.mask = maskLayer
    }

}

enter image description here

Можно ли создать вырез в форме пончика с использованием масок?

1 Ответ

0 голосов
/ 27 августа 2018

Это заняло немного больше усилий, чем я ожидал, и решение не было очевидным ... пока я не нашел его, тогда это было похоже, о, да, конечно: /

Основная идея состоит в том, что вы хотите «вырезать» часть существующего пути, решение не было очевидным, поскольку UIBezierPath не предоставляет метод «вычитания» или «удаления». Вместо этого вам нужно «изменить» путь, например ...

let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 200, height: 200))
path.append(UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 100, height: 100)).reversing())
path.append(UIBezierPath(ovalIn: CGRect(x: 75, y: 75, width: 50, height: 50)))

И так как фрагменты "вне контекста" редко бывают полезны, я использовал эту площадку для тестирования (укажите собственное изображение) ...

import UIKit
import Foundation
import CoreGraphics

let image = UIImage(named: "Profile")
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
backgroundView.backgroundColor = UIColor.green
backgroundView.addSubview(imageView)

imageView.contentMode = .scaleAspectFit
imageView.image = image
imageView.layer.cornerRadius = 100

let shapeLayer = CAShapeLayer()

let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 200, height: 200))
path.append(UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 100, height: 100)).reversing())
path.append(UIBezierPath(ovalIn: CGRect(x: 75, y: 75, width: 50, height: 50)))

shapeLayer.path = path.cgPath
shapeLayer.fillColor = UIColor.red.cgColor
shapeLayer.frame = imageView.bounds

imageView.layer.mask = shapeLayer
backgroundView

И мои результаты ...

Those are the droids you're looking for

Зеленый цвет относится к backgroundView, на котором расположен UIImageView

Теперь, если вы предпочитаете что-то более похожее ...

I can't see anything out of this helmet

Тогда просто избавьтесь от второго append утверждения, path.append(UIBezierPath(ovalIn: CGRect(x: 75, y: 75, width: 50, height: 50)))

...