如何在UIImageView上面生成一个自定义的UIView,中间打一个圆孔,可以看到UIImageView?

问题描述 投票:0回答:1

我想在UIImageView上方的UIView上打一个圆孔,这个圆孔可以看到下面的图片(我想以后用手势识别器通过圆孔与这个图片交互)。 我有2个问题,我不能让圆孔居中到UIImageView的中间(它目前居中到屏幕的左上方),而且我得到的效果与我想达到的效果相反(圆圈外的所有东西都是可见的)。 下面是我的代码。 谁能给点建议?

结果。enter image description here

class UploadProfileImageViewController: UIViewController {

var scrollView: ReadyToUseScrollView!
let container: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor.black
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

let imgView: UIImageView = {
    let imgView = UIImageView()
    imgView.backgroundColor = UIColor.black
    imgView.contentMode = .scaleAspectFit
    imgView.image = UIImage.init(named: "soldier")!
    imgView.translatesAutoresizingMaskIntoConstraints = false
    return imgView
}()

var overlay: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    setup()
}

private func setup(){
    view.backgroundColor = UIColor.white
    setupViews()
}

override func viewDidLayoutSubviews() {

    overlay.center = imgView.center
    print("imgView.center: \(imgView.center)")
    overlay.layer.layoutIfNeeded() // I have also tried view.layoutIfNeeded()
}


private func setupViews(){
    let s = view.safeAreaLayoutGuide

    view.addSubview(imgView)
    imgView.topAnchor.constraint(equalTo: s.topAnchor).isActive = true
    imgView.leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
    imgView.trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
    imgView.heightAnchor.constraint(equalTo: s.heightAnchor, multiplier: 0.7).isActive = true

    overlay = Overlay.init(frame: .zero, center: imgView.center)
    print("setup.imgView.center: \(imgView.center)")
    view.addSubview(overlay)
    overlay.translatesAutoresizingMaskIntoConstraints = false
    overlay.topAnchor.constraint(equalTo: s.topAnchor).isActive = true
    overlay.leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
    overlay.trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
    overlay.bottomAnchor.constraint(equalTo: imgView.bottomAnchor).isActive = true

}

private func deg2rad( number: Double) -> CGFloat{
       let rad = number * .pi / 180
       return CGFloat.init(rad)
   }
}



class Overlay: UIView{

var path: UIBezierPath!
var viewCenter: CGPoint?

init(frame: CGRect, center: CGPoint) {
    super.init(frame: frame)

    self.viewCenter = center
    setup()
}

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

private func setup(){

    backgroundColor = UIColor.black.withAlphaComponent(0.8)

    guard  let path = createCirclePath() else {return}
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = path.cgPath
    shapeLayer.fillRule = CAShapeLayerFillRule.evenOdd
    self.layer.mask = shapeLayer
}


private func createCirclePath() -> UIBezierPath?{
    guard let center = self.viewCenter else{return nil}
    let circlePath = UIBezierPath()
    circlePath.addArc(withCenter: center, radius: 200, startAngle: 0, endAngle: deg2rad(number: 360), clockwise: true)
    return circlePath
}

private func deg2rad( number: Double) -> CGFloat{
    let rad = number * .pi / 180
    return CGFloat.init(rad)
}
}

CONSOLE:

setup.imgView.center: (0.0, 0.0)
imgView.center: (207.0, 359.0)
swift cashapelayer
1个回答
1
投票

试着摆脱你的覆盖,而添加下面的UIView。它基本上是一个圆形的UIView,有一个巨大的黑色边框,但它占据了整个屏幕,所以用户无法分辨。顺便说一下,你需要使用.frame来定位屏幕上的项目。下面将圆圈放在屏幕的中心。如果你想要图片的中心,用self.imgView.frame代替self.view.frame...... 玩转 circleSize 和 borderSize,直到得到你想要的圆圈大小。

    let circle = UIView()
    let circleSize: CGFloat = self.view.frame.height * 2 //must be bigger than the screen
    let x = (self.view.frame.width / 2) - (circleSize / 2)
    let y = (self.view.frame.height / 2) - (circleSize / 2)
    circle.frame = CGRect(x: x, y: y, width: circleSize, height: circleSize)

    let borderSize = (circleSize / 2) * 0.9 //the size of the inner circle will be circleSize - borderSize
    circle.backgroundColor = .clear
    circle.layer.cornerRadius = circle.frame.height / 2
    circle.layer.borderColor = UIColor.black.cgColor
    circle.layer.borderWidth = borderSize

    view.addSubview(circle)
© www.soinside.com 2019 - 2024. All rights reserved.