diff --git a/local_plugins/native_plugin/ios/Classes/PlayerView.swift b/local_plugins/native_plugin/ios/Classes/PlayerView.swift index 8b2b4cf77..98e624768 100644 --- a/local_plugins/native_plugin/ios/Classes/PlayerView.swift +++ b/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 + } + } +}