【发布时间】:2019-03-26 02:22:47
【问题描述】:
我在 swift 中创建了一个自定义视图,并试图让它正确显示。它本质上是一张素材卡片,可以通过按更多按钮来扩展视图。指定底部约束时出现了我的问题。它是必需的,但设置它会扩展我的自定义视图。
我已经在 android 中实现了这个,我想我正在尝试找到 android:height='wrap_content' 的模拟。我尝试设置纵横比约束,这可以使我的视图保持适当的大小,但会阻止自定义视图在其子视图更改时扩展。此外,我尝试使用 lessThanOrEqualTo 约束,但这太模糊而无法满足底部约束。
这是我的 UIExpandableCard 视图的样子:
import Foundation
import MaterialComponents
@IBDesignable
public class UIExpandableCard: UIView {
// attributes
@IBInspectable var overlineText: String? {
didSet {
overlineLabel.text = overlineText?.uppercased()
}
}
@IBInspectable var headlineText: String? {
didSet {
headlineLabel.text = headlineText
}
}
@IBInspectable var bodyText: String? {
didSet {
bodyLabel.text = bodyText
}
}
@IBInspectable var logoImage: UIImage? {
didSet {
logoImageView.image = logoImage
}
}
var cardView: MDCCard!
var overlineLabel: UILabel!
var headlineLabel: UILabel!
var bodyLabel: UILabel!
var moreButton: UIButton!
var logoImageView: UIImageView!
var isCardExpanded = false
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
self.translatesAutoresizingMaskIntoConstraints = false
setupViews()
setupConstraints()
}
private func setupViews() {
self.clipsToBounds = true
cardView = MDCCard(frame: CGRect.zero)
cardView.translatesAutoresizingMaskIntoConstraints = false
cardView.isInteractable = false
self.addSubview(cardView)
overlineLabel = UILabel(frame: CGRect.zero)
overlineLabel.translatesAutoresizingMaskIntoConstraints = false
overlineLabel.font = UIFont.preferredFont(forTextStyle: .footnote)
overlineLabel.text = overlineText?.uppercased()
self.addSubview(overlineLabel)
headlineLabel = UILabel(frame: CGRect.zero)
headlineLabel.translatesAutoresizingMaskIntoConstraints = false
headlineLabel.font = UIFont.preferredFont(forTextStyle: .title1)
headlineLabel.text = headlineText
self.addSubview(headlineLabel)
bodyLabel = UILabel(frame: CGRect.zero)
bodyLabel.translatesAutoresizingMaskIntoConstraints = false
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
bodyLabel.numberOfLines = 1
bodyLabel.text = bodyText
self.addSubview(bodyLabel)
logoImageView = UIImageView(image: logoImage)
logoImageView.translatesAutoresizingMaskIntoConstraints = false
logoImageView.contentMode = .scaleAspectFit
self.addSubview(logoImageView)
moreButton = UIButton(type: .roundedRect)
moreButton.isUserInteractionEnabled = true
moreButton.translatesAutoresizingMaskIntoConstraints = false
moreButton.setTitle("More", for: .normal)
moreButton.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
self.addSubview(moreButton)
}
@objc func buttonClicked(_ sender: UIButton) {
if !isCardExpanded {
moreButton.setTitle("Less", for: .normal)
bodyLabel.numberOfLines = 0
} else {
moreButton.setTitle("More", for: .normal)
bodyLabel.numberOfLines = 1
}
isCardExpanded = !isCardExpanded
}
private func setupConstraints() {
NSLayoutConstraint.activate([
cardView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 8),
cardView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -8),
cardView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8),
cardView.bottomAnchor.constraint(lessThanOrEqualTo: self.bottomAnchor, constant: -8),
overlineLabel.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 16),
overlineLabel.topAnchor.constraint(equalTo: cardView.topAnchor, constant: 16),
headlineLabel.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 16),
headlineLabel.topAnchor.constraint(equalTo: overlineLabel.bottomAnchor, constant: 8),
NSLayoutConstraint(item: logoImageView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 48),
NSLayoutConstraint(item: logoImageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 48),
logoImageView.trailingAnchor.constraint(equalTo: cardView.trailingAnchor, constant: -16),
logoImageView.topAnchor.constraint(equalTo: cardView.topAnchor, constant: 16),
bodyLabel.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 16),
bodyLabel.topAnchor.constraint(equalTo: logoImageView.bottomAnchor, constant: 16),
bodyLabel.trailingAnchor.constraint(equalTo: cardView.trailingAnchor, constant: -8),
moreButton.topAnchor.constraint(greaterThanOrEqualTo: bodyLabel.bottomAnchor, constant: 8),
moreButton.leadingAnchor.constraint(equalTo: cardView.leadingAnchor, constant: 16),
moreButton.bottomAnchor.constraint(equalTo: cardView.bottomAnchor, constant: -8)
])
}
}
基本上我想要像左边这样的东西。但是,我做对了,其中一个视图(蓝色)被拉伸以填充约束。
我对 iOS 比较陌生,但对 android 有经验,所以任何与此相关的解释都会非常有帮助。
谢谢。
【问题讨论】:
标签: ios swift autolayout