Skip to content

Commit

Permalink
完善Debug段落样式设置
Browse files Browse the repository at this point in the history
  • Loading branch information
lixiang1994 committed Aug 14, 2020
1 parent e100025 commit 4798a51
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 24 deletions.
35 changes: 35 additions & 0 deletions Demo/Demo/Debug/Debug.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ extension Debug {
// paragraphs
var lineSpacing: CGFloat?
var lineHeightMultiple: CGFloat?
var minimumLineHeight: CGFloat?
var maximumLineHeight: CGFloat?
var paragraphSpacing: CGFloat?
var paragraphSpacingBefore: CGFloat?
var firstLineHeadIndent: CGFloat?
var headIndent: CGFloat?
var tailIndent: CGFloat?

init() {
font = .systemFont(ofSize: 17.0)
Expand All @@ -50,6 +57,13 @@ extension Debug {
case allowsDefaultTighteningForTruncation
case lineSpacing
case lineHeightMultiple
case minimumLineHeight
case maximumLineHeight
case paragraphSpacing
case paragraphSpacingBefore
case firstLineHeadIndent
case headIndent
case tailIndent
}

init(from decoder: Decoder) throws {
Expand Down Expand Up @@ -86,6 +100,20 @@ extension Debug {
self.lineSpacing = try container.decodeIfPresent(CGFloat.self, forKey: .lineSpacing)

self.lineHeightMultiple = try container.decodeIfPresent(CGFloat.self, forKey: .lineHeightMultiple)

self.minimumLineHeight = try container.decodeIfPresent(CGFloat.self, forKey: .minimumLineHeight)

self.maximumLineHeight = try container.decodeIfPresent(CGFloat.self, forKey: .maximumLineHeight)

self.paragraphSpacing = try container.decodeIfPresent(CGFloat.self, forKey: .paragraphSpacing)

self.paragraphSpacingBefore = try container.decodeIfPresent(CGFloat.self, forKey: .paragraphSpacingBefore)

self.firstLineHeadIndent = try container.decodeIfPresent(CGFloat.self, forKey: .firstLineHeadIndent)

self.headIndent = try container.decodeIfPresent(CGFloat.self, forKey: .headIndent)

self.tailIndent = try container.decodeIfPresent(CGFloat.self, forKey: .tailIndent)
}

func encode(to encoder: Encoder) throws {
Expand All @@ -102,6 +130,13 @@ extension Debug {
try container.encodeIfPresent(allowsDefaultTighteningForTruncation, forKey: .allowsDefaultTighteningForTruncation)
try container.encodeIfPresent(lineSpacing, forKey: .lineSpacing)
try container.encodeIfPresent(lineHeightMultiple, forKey: .lineHeightMultiple)
try container.encodeIfPresent(minimumLineHeight, forKey: .minimumLineHeight)
try container.encodeIfPresent(maximumLineHeight, forKey: .maximumLineHeight)
try container.encodeIfPresent(paragraphSpacing, forKey: .paragraphSpacing)
try container.encodeIfPresent(paragraphSpacingBefore, forKey: .paragraphSpacingBefore)
try container.encodeIfPresent(firstLineHeadIndent, forKey: .firstLineHeadIndent)
try container.encodeIfPresent(headIndent, forKey: .headIndent)
try container.encodeIfPresent(tailIndent, forKey: .tailIndent)
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions Demo/Demo/Debug/DebugLabelView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,45 @@ class DebugLabelView: UIView {
}
}

var paragraphSpacing: CGFloat = 0 {
didSet {
let value = paragraphSpacing
paragraphSpacingLabel.text = String(format: "%.2f", value)
paragraphSpacingSlider.value = .init(value)
}
}

var paragraphSpacingBefore: CGFloat = 0 {
didSet {
let value = paragraphSpacingBefore
paragraphSpacingBeforeLabel.text = String(format: "%.2f", value)
paragraphSpacingBeforeSlider.value = .init(value)
}
}

var firstLineHeadIndent: CGFloat = 0 {
didSet {
let value = firstLineHeadIndent
firstLineHeadIndentLabel.text = String(format: "%.2f", value)
firstLineHeadIndentSlider.value = .init(value)
}
}
var headIndent: CGFloat = 0 {
didSet {
let value = headIndent
headIndentLabel.text = String(format: "%.2f", value)
headIndentSlider.value = .init(value)
}
}

var tailIndent: CGFloat = 0 {
didSet {
let value = tailIndent
tailIndentLabel.text = String(format: "%.2f", value)
tailIndentSlider.value = .init(value)
}
}

@IBOutlet private weak var label: UILabel!

@IBOutlet private weak var widthLayoutConstraint: NSLayoutConstraint!
Expand Down Expand Up @@ -252,6 +291,13 @@ extension DebugLabelView {
// paragraphs
lineSpacing = info.lineSpacing ?? 0
lineHeightMultiple = info.lineHeightMultiple ?? 0
minimumLineHeight = info.minimumLineHeight ?? 0
maximumLineHeight = info.maximumLineHeight ?? 0
paragraphSpacing = info.paragraphSpacing ?? 0
paragraphSpacingBefore = info.paragraphSpacingBefore ?? 0
firstLineHeadIndent = info.firstLineHeadIndent ?? 0
headIndent = info.headIndent ?? 0
tailIndent = info.tailIndent ?? 0

// 刷新布局
layoutIfNeeded()
Expand Down
86 changes: 66 additions & 20 deletions Demo/Demo/Debug/DebugLabelViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class DebugLabelViewController: ViewController<DebugLabelView> {
super.viewDidLoad()

setup()
update()
updateText()
}

private func setup() {
Expand All @@ -41,24 +41,75 @@ class DebugLabelViewController: ViewController<DebugLabelView> {
}

private func set(info: Debug.Label) {

func update(_ style: AttributedString.Attribute.ParagraphStyle) {
paragraphs.removeAll(where: { $0 ~= style })
paragraphs.append(style)
}

func remove(_ style: AttributedString.Attribute.ParagraphStyle) {
paragraphs.removeAll(where: { $0 ~= style })
}

if let value = info.lineSpacing {
paragraphs.removeAll(where: { $0 == .lineSpacing(0) })
paragraphs.append(.lineSpacing(value))
update(.lineSpacing(value))

} else {
paragraphs.removeAll(where: { $0 == .lineSpacing(0) })
remove(.lineSpacing(0))
}
if let value = info.lineHeightMultiple {
paragraphs.removeAll(where: { $0 == .lineHeightMultiple(0) })
paragraphs.append(.lineHeightMultiple(value))
update(.lineHeightMultiple(value))

} else {
remove(.lineHeightMultiple(0))
}
if let value = info.minimumLineHeight {
update(.minimumLineHeight(value))

} else {
remove(.minimumLineHeight(0))
}
if let value = info.maximumLineHeight {
update(.maximumLineHeight(value))

} else {
remove(.maximumLineHeight(0))
}
if let value = info.paragraphSpacing {
update(.paragraphSpacing(value))

} else {
remove(.paragraphSpacing(0))
}
if let value = info.paragraphSpacingBefore {
update(.paragraphSpacingBefore(value))

} else {
remove(.paragraphSpacingBefore(0))
}
if let value = info.firstLineHeadIndent {
update(.firstLineHeadIndent(value))

} else {
remove(.firstLineHeadIndent(0))
}
if let value = info.headIndent {
update(.headIndent(value))

} else {
remove(.headIndent(0))
}
if let value = info.tailIndent {
update(.tailIndent(value))

} else {
paragraphs.removeAll(where: { $0 == .lineHeightMultiple(0) })
remove(.tailIndent(0))
}
container.set(info: info)
updateText()
}

private func update() {
private func updateText() {
container.set(text: .init(
attributedString,
with: attributes + [.paragraph(paragraphs)]
Expand Down Expand Up @@ -121,37 +172,32 @@ class DebugLabelViewController: ViewController<DebugLabelView> {
}

@IBAction func lineSpacingSliderAction(_ sender: UISlider) {
paragraphs.removeAll(where: { $0 == .lineSpacing(0) })
paragraphs.append(.lineSpacing(.init(sender.value)))
info.lineSpacing = .init(sender.value)
update()
}
@IBAction func lineHeightMultipleSliderAction(_ sender: UISlider) {
paragraphs.removeAll(where: { $0 == .lineHeightMultiple(0) })
paragraphs.append(.lineHeightMultiple(.init(sender.value)))
info.lineHeightMultiple = .init(sender.value)
update()
}

@IBAction func minimumLineHeightSliderAction(_ sender: UISlider) {
info.minimumLineHeight = .init(sender.value)
}
@IBAction func maximumLineHeightSliderAction(_ sender: UISlider) {
info.maximumLineHeight = .init(sender.value)
}

@IBAction func paragraphSpacingSliderAction(_ sender: UISlider) {
info.paragraphSpacing = .init(sender.value)
}
@IBAction func paragraphSpacingBeforeSliderAction(_ sender: UISlider) {
info.paragraphSpacingBefore = .init(sender.value)
}

@IBAction func firstLineHeadIndentSliderAction(_ sender: UISlider) {
info.firstLineHeadIndent = .init(sender.value)
}

@IBAction func headIndentSliderAction(_ sender: UISlider) {
info.headIndent = .init(sender.value)
}

@IBAction func tailIndentSliderAction(_ sender: UISlider) {
info.tailIndent = .init(sender.value)
}

}

extension DebugLabelViewController: UIScrollViewDelegate {
Expand Down
3 changes: 1 addition & 2 deletions Sources/Extension/UIKit/UILabel/UILabelExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ fileprivate extension UILabel {
guard let attributedString = AttributedString(text) else { return nil }

// 构建同步Label的TextKit
// 注: 目前还剩一个截断处理没解决 比如 "a\n\n\nb" numberOfLines=2
let delegate = UILabelLayoutManagerDelegate(scaledMetrics, with: baselineAdjustment)
let textStorage = NSTextStorage()
let textContainer = NSTextContainer(size: bounds.size)
Expand Down Expand Up @@ -450,7 +449,7 @@ extension UILabel {
) { (value, range, stop) in
guard let old = value as? NSParagraphStyle else { return }
guard let new = old.mutableCopy() as? NSMutableParagraphStyle else { return }
new.lineBreakMode = .byWordWrapping
new.lineBreakMode = numberOfLines == 1 ? .byCharWrapping : .byWordWrapping
if #available(iOS 11.0, *) {
new.setValue(1, forKey: "lineBreakStrategy")
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/ParagraphStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ extension AttributedString.Attribute.ParagraphStyle {
}
}

extension AttributedString.Attribute.ParagraphStyle: Equatable {
extension AttributedString.Attribute.ParagraphStyle {

public static func == (lhs: AttributedString.Attribute.ParagraphStyle, rhs: AttributedString.Attribute.ParagraphStyle) -> Bool {
public static func ~= (lhs: AttributedString.Attribute.ParagraphStyle, rhs: AttributedString.Attribute.ParagraphStyle) -> Bool {
return lhs.style.keys == rhs.style.keys
}
}

0 comments on commit 4798a51

Please sign in to comment.