【问题标题】:Display only the corners of a UIView仅显示 UIView 的角
【发布时间】:2017-05-31 10:49:48
【问题描述】:

如何只显示 UIView 的角?

        let view = UIView()
        view.layer.borderColor = UIColor.white.cgColor

        view.layer.borderWidth = 2 
           let maskframe = UIView(frame: CGRect(x:0, y:0, 
          width:view.frame.width, height:view.frame.height))

         view.layer.mask = maskframe.layer.`

这仅掩盖了右边缘,我也不明白它是如何工作的。

【问题讨论】:

  • 你能详细说明一下吗?有截图什么的?
  • 给视图层添加一个遮罩层。
  • 您可以自定义绘制您的 UIView,您需要 swift 或 Objective-C 中的解决方案吗?
  • @luk2302 你能告诉我它是怎么做的吗?因为我找不到合适的来源来了解它
  • 请@ReinierMelian swift

标签: ios swift uiview draw


【解决方案1】:

试试这个class,这里我使用CoreGraphics的自定义视图绘图,添加了一些Inspectable变量来帮助自定义

//
//  CornerView.swift
//  CornersViewSO
//
//  Created by Reinier Melian on 5/31/17.
//  Copyright © 2017 Reinier Melian. All rights reserved.
//

import UIKit
import CoreGraphics

@IBDesignable
class CornerView: UIView {

    @IBInspectable
    var sizeMultiplier : CGFloat = 0.2{
        didSet{
            self.draw(self.bounds)
        }
    }

    @IBInspectable
    var lineWidth : CGFloat = 2{
        didSet{
            self.draw(self.bounds)
        }
    }

    @IBInspectable
    var lineColor : UIColor = UIColor.black{
        didSet{
            self.draw(self.bounds)
        }
    }


    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.clear
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.backgroundColor = UIColor.clear
    }

    func drawCorners()
    {
        let currentContext = UIGraphicsGetCurrentContext()

        currentContext?.setLineWidth(lineWidth)
        currentContext?.setStrokeColor(lineColor.cgColor)

        //first part of top left corner
        currentContext?.beginPath()
        currentContext?.move(to: CGPoint(x: 0, y: 0))
        currentContext?.addLine(to: CGPoint(x: self.bounds.size.width*sizeMultiplier, y: 0))
        currentContext?.strokePath()

        //top rigth corner
        currentContext?.beginPath()
        currentContext?.move(to: CGPoint(x: self.bounds.size.width - self.bounds.size.width*sizeMultiplier, y: 0))
        currentContext?.addLine(to: CGPoint(x: self.bounds.size.width, y: 0))
        currentContext?.addLine(to: CGPoint(x: self.bounds.size.width, y: self.bounds.size.height*sizeMultiplier))
        currentContext?.strokePath()

        //bottom rigth corner
        currentContext?.beginPath()
        currentContext?.move(to: CGPoint(x: self.bounds.size.width, y: self.bounds.size.height - self.bounds.size.height*sizeMultiplier))
        currentContext?.addLine(to: CGPoint(x: self.bounds.size.width, y: self.bounds.size.height))
        currentContext?.addLine(to: CGPoint(x: self.bounds.size.width - self.bounds.size.width*sizeMultiplier, y: self.bounds.size.height))
        currentContext?.strokePath()

        //bottom left corner
        currentContext?.beginPath()
        currentContext?.move(to: CGPoint(x: self.bounds.size.width*sizeMultiplier, y: self.bounds.size.height))
        currentContext?.addLine(to: CGPoint(x: 0, y: self.bounds.size.height))
        currentContext?.addLine(to: CGPoint(x: 0, y: self.bounds.size.height - self.bounds.size.height*sizeMultiplier))
        currentContext?.strokePath()

        //second part of top left corner
        currentContext?.beginPath()
        currentContext?.move(to: CGPoint(x: 0, y: self.bounds.size.height*sizeMultiplier))
        currentContext?.addLine(to: CGPoint(x: 0, y: 0))
        currentContext?.strokePath()
    }


    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
        super.draw(rect)
        self.drawCorners()
    }


}

已编辑

使用示例代码

import UIKit

class ViewController: UIViewController {

    var cornerViewCode : CornerView?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.cornerViewCode = CornerView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        self.view.addSubview(self.cornerViewCode!)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

这就是它的样子

希望对你有帮助

【讨论】:

  • 谢谢。但对我来说,什么都没有显示。让 cv=CornerView() cv.draw(CGRect(x:50,y:(view.frame.height/2-50),width:view.frame.width-100,height:100 )) view.addSubview(cv) view.bringSubview(toFront: cv)
  • 你需要用frame初始化,我可以分享一个示例代码,你也可以用storyboard或xib来做这个
  • @SavithaSuresh 请检查我的答案是否已使用示例代码编辑,以说明如何使用它,最好的问候
  • @SavithaSuresh 关闭你永远不应该调用 .draw 方法的记录
  • 如果从 (0, height*multiplier) 开始,则可以消除“左上角的第二部分”代码部分。
【解决方案2】:

看看这个 UIView:

class RectangleView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {

        let aPath = UIBezierPath()

        UIColor.black.set()

        aPath.move(to: CGPoint(x: rect.minX, y: 0.1*rect.maxY))
        aPath.addLine(to: CGPoint(x: rect.minX, y: rect.minY))
        aPath.addLine(to: CGPoint(x: 20, y: rect.minY))
        aPath.stroke()

        aPath.move(to: CGPoint(x: rect.maxX - 0.1*rect.maxX, y: rect.minY))
        aPath.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        aPath.addLine(to: CGPoint(x: rect.maxX, y: 0.1*rect.maxY))
        aPath.stroke()

        aPath.move(to: CGPoint(x: rect.maxX, y: rect.maxY - 0.1*rect.maxY))
        aPath.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        aPath.addLine(to: CGPoint(x: rect.maxX - 0.1*rect.maxX, y: rect.maxY))
        aPath.stroke()

        aPath.move(to: CGPoint(x: rect.minX + 0.1*rect.maxX, y: rect.maxY))
        aPath.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        aPath.addLine(to: CGPoint(x: rect.minX, y: rect.maxY - 0.1*rect.maxY))
        aPath.stroke()

    }

}

【讨论】:

  • 谢谢@kingalione,有没有办法屏蔽视图而不是这样做?
【解决方案3】:

如果你不想继承 UIView。使用 Autolayout 也可以达到同样的效果。

Swift 版本:3.0

Xcode 版本 8.2.1

func setupAutoLayout() {
    let cameraViewWidth : Float = Float(UIScreen.main.bounds.size.width * 0.50)

    let edgeLength : Float = cameraViewWidth * 0.10

    cameraView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    cameraView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    cameraView.widthAnchor.constraint(equalToConstant: CGFloat(cameraViewWidth)).isActive = true
    cameraView.heightAnchor.constraint(equalToConstant: CGFloat(cameraViewWidth)).isActive = true

    //Top Left
    topLeftEdgeView.leadingAnchor.constraint(equalTo: cameraView.leadingAnchor).isActive = true
    topLeftEdgeView.topAnchor.constraint(equalTo: cameraView.topAnchor).isActive = true
    topLeftEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true
    topLeftEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true

    topLeftSideEdgeView.leadingAnchor.constraint(equalTo: cameraView.leadingAnchor).isActive = true
    topLeftSideEdgeView.topAnchor.constraint(equalTo: cameraView.topAnchor).isActive = true
    topLeftSideEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true
    topLeftSideEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true

    //Top Right
    topRightEdgeView.trailingAnchor.constraint(equalTo: cameraView.trailingAnchor).isActive = true
    topRightEdgeView.topAnchor.constraint(equalTo: cameraView.topAnchor).isActive = true
    topRightEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true
    topRightEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true

    topRightSideEdgeView.trailingAnchor.constraint(equalTo: cameraView.trailingAnchor).isActive = true
    topRightSideEdgeView.topAnchor.constraint(equalTo: cameraView.topAnchor).isActive = true
    topRightSideEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true
    topRightSideEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true

    //Bottom Left
    bottomLeftEdgeView.leadingAnchor.constraint(equalTo: cameraView.leadingAnchor).isActive = true
    bottomLeftEdgeView.bottomAnchor.constraint(equalTo: cameraView.bottomAnchor, constant : -CGFloat(1.0)).isActive = true
    bottomLeftEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true
    bottomLeftEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true

    bottomLeftSideEdgeView.leadingAnchor.constraint(equalTo: cameraView.leadingAnchor).isActive = true
    bottomLeftSideEdgeView.topAnchor.constraint(equalTo: cameraView.bottomAnchor, constant : -CGFloat(edgeLength + 1.0)).isActive = true
    bottomLeftSideEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true
    bottomLeftSideEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true

    //Bottom Right
    bottomRightEdgeView.trailingAnchor.constraint(equalTo: cameraView.trailingAnchor).isActive = true
    bottomRightEdgeView.bottomAnchor.constraint(equalTo: cameraView.bottomAnchor, constant : -CGFloat(1.0)).isActive = true
    bottomRightEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true
    bottomRightEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true

    bottomRightSideEdgeView.trailingAnchor.constraint(equalTo: cameraView.trailingAnchor).isActive = true
    bottomRightSideEdgeView.topAnchor.constraint(equalTo: cameraView.bottomAnchor, constant : -CGFloat(edgeLength + 1.0)).isActive = true
    bottomRightSideEdgeView.widthAnchor.constraint(equalToConstant: CGFloat(1.0)).isActive = true
    bottomRightSideEdgeView.heightAnchor.constraint(equalToConstant: CGFloat(edgeLength)).isActive = true
}

PS:其中cameraView、topLeftEdgeView、topLeftSideEdgeView...等都是UIView。

这里我们的 edgeLength 取决于 cameraView 的宽度(目前是 10%)。 在 0.50 这将在 cameraView 周围绘制完整的边框。

不要忘记为所有涉及的视图添加 translatesAutoresizingMaskIntoConstraints = false!

【讨论】:

    【解决方案4】:

    我能够通过 BeizerPath 和 CAShapeLayer 实现相同的目标。因此共享相同。

    使用 Swift 4.0Xcode 9.3 上创建的代码。在 iOS 10.0iOS 11.3

    上测试
      func createCorners() -> Void {
    
            //Calculate the length of corner to be shown
            let cornerLengthToShow = self.bounds.size.height * 0.10
            print(cornerLengthToShow)
    
            // Create Paths Using BeizerPath for all four corners
            let topLeftCorner = UIBezierPath()
            topLeftCorner.move(to: CGPoint(x: self.bounds.minX, y: self.bounds.minY + cornerLengthToShow))
            topLeftCorner.addLine(to: CGPoint(x: self.bounds.minX, y: self.bounds.minY))
            topLeftCorner.addLine(to: CGPoint(x: self.bounds.minX + cornerLengthToShow, y: self.bounds.minY))
    
            let topRightCorner = UIBezierPath()
            topRightCorner.move(to: CGPoint(x: self.bounds.maxX - cornerLengthToShow, y: self.bounds.minY))
            topRightCorner.addLine(to: CGPoint(x: self.bounds.maxX, y: self.bounds.minY))
            topRightCorner.addLine(to: CGPoint(x: self.bounds.maxX, y: self.bounds.minY + cornerLengthToShow))
    
            let bottomRightCorner = UIBezierPath()
            bottomRightCorner.move(to: CGPoint(x: self.bounds.maxX, y: self.bounds.maxY - cornerLengthToShow))
            bottomRightCorner.addLine(to: CGPoint(x: self.bounds.maxX, y: self.bounds.maxY))
            bottomRightCorner.addLine(to: CGPoint(x: self.bounds.maxX - cornerLengthToShow, y: self.bounds.maxY ))
    
            let bottomLeftCorner = UIBezierPath()
            bottomLeftCorner.move(to: CGPoint(x: self.bounds.minX, y: self.bounds.maxY - cornerLengthToShow))
            bottomLeftCorner.addLine(to: CGPoint(x: self.bounds.minX, y: self.bounds.maxY))
            bottomLeftCorner.addLine(to: CGPoint(x: self.bounds.minX + cornerLengthToShow, y: self.bounds.maxY))
    
            let combinedPath = CGMutablePath()
            combinedPath.addPath(topLeftCorner.cgPath)
            combinedPath.addPath(topRightCorner.cgPath)
            combinedPath.addPath(bottomRightCorner.cgPath)
            combinedPath.addPath(bottomLeftCorner.cgPath)
    
            let shapeLayer = CAShapeLayer()
            shapeLayer.path = combinedPath
            shapeLayer.strokeColor = UIColor.blue.cgColor
            shapeLayer.fillColor = UIColor.clear.cgColor
            shapeLayer.lineWidth = 3
    
            layer.addSublayer(shapeLayer)
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      相关资源
      最近更新 更多