Swift - 将 2 个 UIView 与 1 个无缝边框组合
Swift -Combine 2 UIViews with 1 Seamless Border
我将以下 2 个 UIView 固定在一起。
顶部是名为 ballonView 的常规 UIView,底部是名称为 TriangleView 的 UIView 的子类。我有一个 border
绕过 ballonView,但我希望 border
也像这样绕过 triangleView。边框看起来是无缝的。
我该怎么做?
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)
}
}
只需“手动”绘制带三角形的圆角矩形作为贝塞尔曲线路径。我最终将其作为草图:
在它前面放置一个标签留作 reader 的练习。它只是一个包含我在代码中构建的图像的图像视图:
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)
您将图像视图添加到您的界面并将标签放在它前面,一切就绪。当然,我已经对我的数字进行了硬编码,但是嘿,这只是一个草图;根据需要调整。
我将以下 2 个 UIView 固定在一起。
顶部是名为 ballonView 的常规 UIView,底部是名称为 TriangleView 的 UIView 的子类。我有一个 border
绕过 ballonView,但我希望 border
也像这样绕过 triangleView。边框看起来是无缝的。
我该怎么做?
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)
}
}
只需“手动”绘制带三角形的圆角矩形作为贝塞尔曲线路径。我最终将其作为草图:
在它前面放置一个标签留作 reader 的练习。它只是一个包含我在代码中构建的图像的图像视图:
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)
您将图像视图添加到您的界面并将标签放在它前面,一切就绪。当然,我已经对我的数字进行了硬编码,但是嘿,这只是一个草图;根据需要调整。