Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift-将2个UIView与1个无缝边框组合_Ios_Swift_Uiview - Fatal编程技术网

Ios Swift-将2个UIView与1个无缝边框组合

Ios Swift-将2个UIView与1个无缝边框组合,ios,swift,uiview,Ios,Swift,Uiview,我将以下两个UIView固定在一起 顶部是名为BalonView的常规UIView,底部是UIView名为TriangalView的子类。我有一个边框环绕ballonView,但我希望边框也像这样环绕三角形视图。边界看起来是无缝的 我该怎么做 override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .black displayBalloonView() } lazy var

我将以下两个UIView固定在一起

顶部是名为BalonView的常规UIView,底部是UIView名为TriangalView的子类。我有一个
边框
环绕ballonView,但我希望
边框
也像这样环绕三角形视图。边界看起来是无缝的

我该怎么做

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .black

    displayBalloonView()
}

lazy var balloonView: UIView = {
    let v = UIView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.backgroundColor = .orange
    v.layer.borderWidth = 3
    v.layer.borderColor = UIColor.white.cgColor
    v.layer.cornerRadius = 7
    v.layer.masksToBounds = true
    v.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
    return v
}()

lazy var triangleView: TriangleView = {
    let v = TriangleView()
    v.translatesAutoresizingMaskIntoConstraints = false
    v.fillColor = UIColor.orange
    v.backgroundColor = .clear
    return v
}()


func displayBalloonView() {

    view.addSubview(balloonView)
    balloonView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    balloonView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16).isActive = true
    balloonView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16).isActive = true
    balloonView.heightAnchor.constraint(equalToConstant: 70).isActive = true
    
    view.addSubview(triangleView)
    triangleView.topAnchor.constraint(equalTo: balloonView.bottomAnchor).isActive = true
    triangleView.centerXAnchor.constraint(equalTo: balloonView.centerXAnchor).isActive = true
    triangleView.widthAnchor.constraint(equalToConstant: 35).isActive = true
    triangleView.heightAnchor.constraint(equalToConstant: 25).isActive = true
    
    let messageLabel = UILabel()
    messageLabel.translatesAutoresizingMaskIntoConstraints = false
    messageLabel.text = "Tap here to see more"
    messageLabel.textColor = .white
    messageLabel.font = UIFont.systemFont(ofSize: 15, weight: .medium)
    messageLabel.textAlignment = .center
    messageLabel.numberOfLines = 0 // the text might be more than 1 line and I would set the balloonView to the label's height but for simplicity I just set the ballonView heightConstraint to 70
    messageLabel.sizeToFit()
    
    balloonView.addSubview(messageLabel)
    messageLabel.centerYAnchor.constraint(equalTo: balloonView.centerYAnchor).isActive = true
    messageLabel.leadingAnchor.constraint(equalTo: balloonView.leadingAnchor, constant: 16).isActive = true
    messageLabel.trailingAnchor.constraint(equalTo: balloonView.trailingAnchor, constant: -16).isActive = true
}
三角视图:

class TriangleView : UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    var fillColor = UIColor()
    
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        context.beginPath()
        context.move(to: CGPoint(x: rect.minX, y: rect.minY))
        context.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        context.addLine(to: CGPoint(x: (rect.midX), y: rect.maxY))
        context.closePath()
        context.setFillColor(fillColor.cgColor)
        context.fillPath()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

只需“用手”绘制三角形的圆形矩形作为贝塞尔路径。我最后把这张画成了一张草图:

将标签放在其前面是留给读者的练习。这只是一个包含我在代码中构建的图像的图像视图:

let r = UIGraphicsImageRenderer(size: CGSize(width: 200, height: 100))
let im = r.image {
    ctx in
    let con = ctx.cgContext
    con.move(to: CGPoint(x:100, y:10))
    con.addArc(tangent1End: CGPoint(x:190, y:10), tangent2End: CGPoint(x:190, y:80), radius: 10)
    con.addArc(tangent1End: CGPoint(x:190, y:80), tangent2End: CGPoint(x:0, y:80), radius: 10)
    con.addLine(to: CGPoint(x:110, y:80))
    con.addLine(to: CGPoint(x:100, y:95))
    con.addLine(to: CGPoint(x:90, y:80))
    con.addArc(tangent1End: CGPoint(x:10, y:80), tangent2End: CGPoint(x:10, y:0), radius: 10)
    con.addArc(tangent1End: CGPoint(x:10, y:10), tangent2End: CGPoint(x:200, y:10), radius: 10)
    con.addLine(to: CGPoint(x:100, y:10))
    con.setLineWidth(3)
    con.setStrokeColor(UIColor.white.cgColor)
    con.setFillColor(UIColor.red.cgColor)
    con.drawPath(using: .fillStroke)
}
let iv = UIImageView(image:im)

您将图像视图添加到界面中,并将标签放在其前面,就完成了设置。当然,我已经硬编码了我的数字,但嘿,这只是一个草图;根据需要进行调整。

在单个视图中使用单个形状层。您的意思是将三角形和BallooView合并为一个视图?正如斯帕特尔所说,是的,只需创建一个看起来像您想要的方式的单个贝塞尔路径(BallooPlus arrow),然后自己绘制即可。你可以把它填好,然后抚摸一下,它就会看起来正是你想要的样子。@matt好的,谢谢,我明天早上会试试,快睡着了。现在已经很晚了,不过如果有一种方法可以“联合”观点,那就很方便了……你为什么不从这里链接到你的答案:?我还没有尝试过,但似乎这会奏效。我不认为这种方法是好的。关于如何合并两个形状,或者如何给出这样做的外观,有很多答案;研究那是你的工作,不是我的。