【发布时间】:2021-04-09 09:08:47
【问题描述】:
我有这个 SwiftUI 组件
var body: some View {
let image = TypographyImage.image(for: typography, kind: kind)
let width = image.size.width + 4
let height = TypographyImage.height(for: typography) * (kind == .oneLine ? 1.0 : 2.0)
ScrollView(.horizontal) {
HStack {
Image(uiImage: image)
.frame(width: width, height: height, alignment: Alignment(horizontal: .center, vertical: .top))
.offset(y: TypographyImage.offset(for: typography))
.background(Color.red)
if isSwiftUI {
Text(text)
.typography(typography, theme: AmityTheme.shared)
.background(Color.red)
} else {
MyUILabel(text: text, typography: typography, theme: AmityTheme.shared).background(Color.red)
}
}
}
}
显示此 UI
请注意,在MyUILabel 中,我应用了背景红色。
HStack 内的 MyUILabel 的背景颜色和对齐方式在 MyUILabel 返回 UILabel 作为第一个子视图时正确显示
如下图
struct MyUILabel: UIViewRepresentable {
var text: String
var typography: AmityTheme.Typography
var theme: AmityTheme
func makeUIView(context: Context) -> UILabel {
let view = UILabel(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.setContentHuggingPriority(.defaultHigh, for: .vertical)
view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
updateUIView(view, context: context)
return view
}
func updateUIView(_ view: UILabel, context: Context) {
view.attributedText = NSAttributedString(string: text, attributes: theme.textAttributes(for: typography, palette: .black))
}
}
但是,如果我将其更改为返回我的自定义视图,例如
struct MyUILabel: UIViewRepresentable {
var text: String
var typography: AmityTheme.Typography
var theme: AmityTheme
func makeUIView(context: Context) -> PaddedUILabel {
let view = PaddedUILabel(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.setContentHuggingPriority(.defaultHigh, for: .vertical)
view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
updateUIView(view, context: context)
return view
}
func updateUIView(_ view: PaddedUILabel, context: Context) {
view.update(text: text, typography: typography, theme: theme)
}
}
class PaddedUILabel: UIView {
private var label: UILabel!
private var topConstraint: NSLayoutConstraint!
private var bottomConstraint: NSLayoutConstraint!
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.setContentHuggingPriority(.defaultHigh, for: .vertical)
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
self.label = label
addSubview(label)
topConstraint = label.topAnchor.constraint(equalTo: topAnchor)
bottomConstraint = label.bottomAnchor.constraint(equalTo: bottomAnchor)
let constraints: [NSLayoutConstraint] = [
label.leadingAnchor.constraint(equalTo: leadingAnchor),
label.trailingAnchor.constraint(equalTo: trailingAnchor),
topConstraint,
bottomConstraint
]
NSLayoutConstraint.activate(constraints)
}
func update(text: String, typography: AmityTheme.Typography, theme: AmityTheme) {
let attributes = theme.textAttributes(for: typography, palette: .black)
label.attributedText = NSAttributedString(string: text, attributes: attributes)
}
}
结果是
背景颜色消失了,HStack 中心垂直对齐不被尊重。我似乎不知道为什么会这样。
谁能建议我如何解决这个问题?
谢谢
【问题讨论】:
-
为什么要使用自定义视图 PaddedUILabel (UILabel)?
-
因为这是我们应用程序的一种中心框架,我必须确保我们的 NSAttributedString 主题在 SwiftUI 和 UIKit 上都能正常工作。
PaddedUILabel将在框架端实现,以使显示的文本与设计者的预期完全相同(NSAttributedString的 key 属性是不够的)。这就是PaddedUILabel的原因