swift-自定义Label可以设置label每行的高度设置字体大小等
在iOS应用开发中,Swift语言为我们提供了丰富的UI组件来展示文本信息,但有时系统默认的UILabel并不能满足所有需求。为了实现特定的界面效果,开发者往往需要进行自定义控件的封装。本文将深入探讨如何根据标题"swift-自定义Label可以设置label每行的高度设置字体大小等"以及描述,来创建一个自定义的UILabel子类,以实现更灵活的文本布局和格式化。 我们需要创建一个新的Swift文件,命名为`JSLineLabel.swift`,并继承自`UILabel`。在这个自定义类中,我们可以添加以下功能: 1. **设置每行高度**:默认情况下,UILabel会根据文字内容和字体大小自动调整行高。为了自定义行高,我们需要重写`intrinsicContentSize`方法,并在其中计算出符合设定行高的尺寸。 ```swift override var intrinsicContentSize: CGSize { let textHeight = max(fontSize * text!.boundingBox(forBounds: CGRect(x: 0, y: 0, width: bounds.width), font: font!, lineBreakMode: lineBreakMode).height, lineHeight) return CGSize(width: super.intrinsicContentSize.width, height: textHeight) } ``` 这里的`lineHeight`是用户可以设置的每行高度,`fontSize`是字体大小,通过`text!.boundingBox`计算出实际文本的高度,确保至少为设定的行高。 2. **设置字体大小**:Swift中的UILabel已经内置了设置字体大小的属性`font`,我们只需要在初始化或需要改变字体大小时,直接修改这个属性即可。 ```swift self.font = UIFont.systemFont(ofSize: fontSize) ``` 3. **获取Label的size和行数**:可以通过`sizeThatFits`方法计算出文本在限定宽度下的大小,同时通过计算`boundingBox`的高度来确定行数。 ```swift func getSizeAndLines() -> (size: CGSize, lines: Int) { let size = self.sizeThatFits(CGSize(width: bounds.width, height: .greatestFiniteMagnitude)) let lines = ceil(size.height / lineHeight) return (size, lines) } ``` 4. **在每行字下面加一条横线**:为了实现这个效果,我们可以自定义一个`drawRect`方法,遍历每一行文本,然后在每个行尾绘制一条线。 ```swift override func draw(_ rect: CGRect) { super.draw(rect) guard let text = text else { return } let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = lineBreakMode let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: font!, NSAttributedString.Key.paragraphStyle: paragraphStyle] let textRange = NSRange(location: 0, length: text.utf16.count) let boundingBox = text.boundingBox(forBounds: rect, withAttributes: attributes) let layoutManager = NSLayoutManager() layoutManager.addLayoutManager(self) layoutManager.addTextContainer(NSAttributedString.TextContainer(rect: rect, forGlyphRange: textRange)) for i in 0..<layoutManager.numberOfLines { let lineRange = layoutManager.lineFragmentRect(forGlyphAt: i, effectiveRange: nil) // 在行尾绘制横线 let lineEnd = CGPoint(x: lineRange.maxX, y: lineRange.maxY - 1) let linePath = UIBezierPath() linePath.move(to: lineEnd) linePath.addLine(to: CGPoint(x: rect.minX, y: lineEnd.y)) UIColor.gray.setStroke() linePath.stroke() } } ``` 这个自定义的JSLineLabel类不仅提供了设置行高、字体大小的功能,还能获取Label的尺寸和行数,同时实现每行文字下方的横线效果。这样的自定义Label对于创建类似日记风格的界面非常有用,可以根据需要进行扩展和定制,满足各种复杂的需求。 在实际项目中,你可以通过导入`JSLineLabel.swift`文件,并在界面设计中使用`JSLineLabel`替代`UILabel`,然后设置相应的属性,如`lineHeight`,以实现所需的文本显示效果。通过这样的自定义,开发者能够更好地控制UI元素,提升用户体验,同时展现出强大的编程灵活性。