在不同的边上添加不同宽度的边框
Posted
技术标签:
【中文标题】在不同的边上添加不同宽度的边框【英文标题】:Add border of varying width to different sides 【发布时间】:2021-03-04 12:46:46 【问题描述】:我有一个要求,我需要在 uiview 的顶部、左侧和底部边框宽度为 1 (CGFloat),在右侧边框宽度为 0 (CGFloat)。我尝试为每一侧添加多个 CALayers,但视图并不好,因为滚动边框时没有使用 uiview 滚动。
我尝试使用的代码:
enum ViewSide: String
case left
case right
case top
case bottom
func addBorderToAllSides(color: UIColor, thickness: CGFloat)
addBorder(toSides: [.left, .right, .bottom, .top], withColor: color, andThickness: thickness)
func addBorder(toSides sides: [ViewSide], withColor color: UIColor, andThickness thickness: CGFloat)
sides.forEach (side) in
///remove previously added sublayer
layer.sublayers?.removeAll(where: $0.name == side.rawValue)
let border = CALayer()
border.backgroundColor = color.cgColor
switch side
case .left:
border.frame = CGRect(x: frame.minX, y: frame.minY, width: thickness, height: frame.height)
case .right:
border.frame = CGRect(x: frame.maxX, y: frame.minY, width: thickness, height: frame.height)
case .top:
border.frame = CGRect(x: frame.minX, y: frame.minY, width: frame.width, height: thickness)
case .bottom:
border.frame = CGRect(x: frame.minX, y: frame.maxY, width: frame.width, height: thickness)
border.name = side.rawValue
layer.addSublayer(border)
src - https://gist.github.com/MrJackdaw/6ffbc33fc274838412bfe3ad48592b9b
我想要达到的目标:
这里对于每个项目,在每边添加相同的边框宽度会导致 2 个项目中间的边框是双倍宽度。想要摆脱它。
感谢任何帮助
【问题讨论】:
向我们展示您的代码,以及使用此扩展程序运行代码时的输出。 我认为使用两个UIViews
是可能的,其中“边框”是一个高2 磅、宽1 磅的视图。将“实际”视图正确放置在顶部。如果您使用自动布局,最好将这两个视图放在一个容器视图中。
有多种方法可以实现这一点...在您的图像中,您是否显示UIStackView
?它是否水平滚动以显示“Sun thru Sat”?或者,它是否连续滚动,再次“环绕”到“太阳”?
@dfd,我曾想过使用 UIView,但不认为这会是最有效的解决方案。希望有更好的解决方案。
@DonMag,它是一个集合视图,水平滚动并且不会连续滚动。即停在星期六
【参考方案1】:
有多种方法可以做到这一点,但您可能喜欢的一种方法是将CAShapeLayer
添加为单个子层,并使用UIBezierPath
作为侧面。
这是一个简单的例子:
class SidesCell: UICollectionViewCell
enum ViewSide: String
case left
case right
case top
case bottom
var sides: [ViewSide] = []
let sidesLayer: CAShapeLayer = CAShapeLayer()
override init(frame: CGRect)
super.init(frame: frame)
commonInit()
required init?(coder: NSCoder)
super.init(coder: coder)
commonInit()
func commonInit() -> Void
contentView.layer.addSublayer(sidesLayer)
sidesLayer.fillColor = UIColor.clear.cgColor
sidesLayer.strokeColor = UIColor.gray.cgColor
sidesLayer.lineWidth = 1.0
// modify this based on what you're setting in the cell
// label text, colors, whatever...
func setData(_ str: String, sides: [ViewSide]) -> Void
self.sides = sides
// use other data
// this will be called when the cell is ready for layout
override func layoutSubviews()
super.layoutSubviews()
let pth = UIBezierPath()
if sides.contains(.left)
pth.move(to: CGPoint(x: bounds.minX, y: bounds.minY))
pth.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
if sides.contains(.top)
pth.move(to: CGPoint(x: bounds.minX, y: bounds.minY))
pth.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
if sides.contains(.right)
pth.move(to: CGPoint(x: bounds.maxX, y: bounds.minY))
pth.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
if sides.contains(.bottom)
pth.move(to: CGPoint(x: bounds.minX, y: bounds.maxY))
pth.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
sidesLayer.path = pth.cgPath
然后,在cellForItemAt
中,您将设置每个单元格所需的边。
例如,如果您有 7 个单元格,并且您希望前 6 个上/左/下“侧线”:
let c = collectionView.dequeueReusableCell(withReuseIdentifier: "myIdentifier", for: indexPath) as! SidesCell
if indexPath.item == 6
c.setData("Test", sides: [.top, .bottom])
else
c.setData("Test", sides: [.top, .left, .bottom])
return c
【讨论】:
以上是关于在不同的边上添加不同宽度的边框的主要内容,如果未能解决你的问题,请参考以下文章
为啥 IE 和 Chrome 呈现 css 边框底部宽度不同?