Browse Source

feat(PlayerView): 改进播放器视图的UI和动态文本布局

- 更新背景颜色、阴影和边框样式
- 重构语言标签布局,添加容器视图
- 实现动态文本行数限制以适应不同高度
- 优化字体颜色和行间距
newdev_shunjiawei
lxm 9 months ago
parent
commit
d4e7ae1599
  1. 129
      local_plugins/native_plugin/ios/Classes/PlayerView.swift

129
local_plugins/native_plugin/ios/Classes/PlayerView.swift

@ -3,9 +3,14 @@ import UIKit
public class PlayerView: UIView {
private let titleLabel: UILabel = UILabel()
private let langLabel: UILabel = UILabel()
private let langContainer: UIView = UIView()
private let cnLabel: UILabel = UILabel()
private let enLabel: UILabel = UILabel()
private let stackView: UIStackView
private var lastDynamicTextLines: Int = -1
private let langRow: UIStackView = UIStackView()
private var lastBoundsSize: CGSize = .zero
private var lastLangText: String? = nil
public override init(frame: CGRect) {
stackView = UIStackView()
@ -24,42 +29,84 @@ public class PlayerView: UIView {
}
private func setupUI() {
backgroundColor = .white
backgroundColor = UIColor(red: 40.0 / 255.0, green: 40.0 / 255.0, blue: 40.0 / 255.0, alpha: 90.0 / 255.0)
layer.cornerRadius = 16
layer.borderWidth = 1
layer.borderColor = UIColor(white: 1.0, alpha: 46.0 / 255.0).cgColor
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.35
layer.shadowRadius = 12
layer.shadowOffset = CGSize(width: 0, height: 4)
titleLabel.text = "实时翻译"
titleLabel.font = .boldSystemFont(ofSize: 22)
titleLabel.textColor = .black
titleLabel.textColor = UIColor(white: 1.0, alpha: 235.0 / 255.0)
titleLabel.textAlignment = .center
titleLabel.numberOfLines = 1
titleLabel.isHidden = true
langLabel.text = "中文(简体) -> 英语"
langLabel.font = .systemFont(ofSize: 14)
langLabel.textColor = .darkGray
langLabel.textAlignment = .left
langLabel.text = "src -> tgt"
langLabel.font = .systemFont(ofSize: 12)
langLabel.textColor = UIColor(white: 1.0, alpha: 235.0 / 255.0)
langLabel.textAlignment = .center
langLabel.numberOfLines = 1
langLabel.lineBreakMode = .byTruncatingTail
langLabel.translatesAutoresizingMaskIntoConstraints = false
langLabel.setContentHuggingPriority(.required, for: .horizontal)
langLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
langContainer.backgroundColor = UIColor(white: 1.0, alpha: 36.0 / 255.0)
langContainer.layer.cornerRadius = 10
langContainer.translatesAutoresizingMaskIntoConstraints = false
langContainer.setContentHuggingPriority(.required, for: .horizontal)
langContainer.setContentCompressionResistancePriority(.required, for: .horizontal)
langContainer.addSubview(langLabel)
NSLayoutConstraint.activate([
langLabel.topAnchor.constraint(equalTo: langContainer.topAnchor, constant: 6),
langLabel.leadingAnchor.constraint(equalTo: langContainer.leadingAnchor, constant: 10),
langLabel.trailingAnchor.constraint(equalTo: langContainer.trailingAnchor, constant: -10),
langLabel.bottomAnchor.constraint(equalTo: langContainer.bottomAnchor, constant: -6),
])
cnLabel.font = .systemFont(ofSize: 18)
cnLabel.textColor = .black
cnLabel.font = .systemFont(ofSize: 14)
cnLabel.textColor = UIColor(white: 1.0, alpha: 235.0 / 255.0)
cnLabel.textAlignment = .left
cnLabel.numberOfLines = 0
cnLabel.lineBreakMode = .byTruncatingTail
enLabel.font = .systemFont(ofSize: 18)
enLabel.textColor = UIColor(red: 0.24, green: 0.54, blue: 0.90, alpha: 1.0)
enLabel.font = .systemFont(ofSize: 15)
enLabel.textColor = UIColor(red: 144.0 / 255.0, green: 202.0 / 255.0, blue: 249.0 / 255.0, alpha: 1.0)
enLabel.textAlignment = .left
enLabel.numberOfLines = 0
enLabel.lineBreakMode = .byTruncatingTail
let para = NSMutableParagraphStyle()
para.lineSpacing = 4
cnLabel.attributedText = NSAttributedString(string: "正在识别...", attributes: [.paragraphStyle: para])
enLabel.attributedText = NSAttributedString(string: "翻译中...", attributes: [.paragraphStyle: para])
para.lineSpacing = 2
para.lineHeightMultiple = 1.1
cnLabel.attributedText = NSAttributedString(string: "", attributes: [.paragraphStyle: para])
enLabel.attributedText = NSAttributedString(string: "", attributes: [.paragraphStyle: para])
stackView.axis = .vertical
stackView.spacing = 12
stackView.spacing = 10
stackView.alignment = .fill
stackView.distribution = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(langLabel)
langRow.axis = .horizontal
langRow.alignment = .fill
langRow.distribution = .fill
langRow.translatesAutoresizingMaskIntoConstraints = false
let leftSpacer = UIView()
let rightSpacer = UIView()
leftSpacer.translatesAutoresizingMaskIntoConstraints = false
rightSpacer.translatesAutoresizingMaskIntoConstraints = false
langRow.addArrangedSubview(leftSpacer)
langRow.addArrangedSubview(langContainer)
langRow.addArrangedSubview(rightSpacer)
NSLayoutConstraint.activate([
leftSpacer.widthAnchor.constraint(equalTo: rightSpacer.widthAnchor),
])
stackView.addArrangedSubview(langRow)
stackView.addArrangedSubview(cnLabel)
stackView.addArrangedSubview(enLabel)
@ -86,13 +133,61 @@ public class PlayerView: UIView {
langLabel.text = lang
}
let para = NSMutableParagraphStyle()
para.lineSpacing = 4
para.lineSpacing = 2
para.lineHeightMultiple = 1.1
if let cn = cn {
cnLabel.attributedText = NSAttributedString(string: cn, attributes: [.paragraphStyle: para])
}
if let en = en {
enLabel.attributedText = NSAttributedString(string: en, attributes: [.paragraphStyle: para])
}
setNeedsLayout()
}
public override func layoutSubviews() {
super.layoutSubviews()
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath
let currentLangText = langLabel.text
if bounds.size != lastBoundsSize || currentLangText != lastLangText {
lastBoundsSize = bounds.size
lastLangText = currentLangText
updateDynamicTextLineLimit()
}
}
}
private func updateDynamicTextLineLimit() {
let fittingWidth = max(0, bounds.width - layoutMargins.left - layoutMargins.right)
if fittingWidth <= 0 { return }
let visibleArrangedSubviews = stackView.arrangedSubviews.filter { !$0.isHidden }
let fixedSubviews = visibleArrangedSubviews.filter { $0 !== cnLabel && $0 !== enLabel }
let fixedHeight = fixedSubviews.reduce(CGFloat(0)) { partialResult, view in
partialResult
+ view.systemLayoutSizeFitting(
CGSize(width: fittingWidth, height: UIView.layoutFittingCompressedSize.height),
withHorizontalFittingPriority: .required,
verticalFittingPriority: .fittingSizeLevel
).height
}
let totalSpacing = CGFloat(max(0, visibleArrangedSubviews.count - 1)) * stackView.spacing
let availableHeight =
bounds.height
- layoutMargins.top
- layoutMargins.bottom
- fixedHeight
- totalSpacing
let cnLineHeight = cnLabel.font.lineHeight * 1.1 + 2
let enLineHeight = enLabel.font.lineHeight * 1.1 + 2
let combinedLineHeight = cnLineHeight + enLineHeight
let perLabelLines = max(1, min(Int(availableHeight / combinedLineHeight), 6))
if perLabelLines != lastDynamicTextLines {
lastDynamicTextLines = perLabelLines
cnLabel.numberOfLines = perLabelLines
enLabel.numberOfLines = perLabelLines
}
}
}

Loading…
Cancel
Save