我有一个可重用的视图类,将函数.addDisapearingView()
添加到另一个视图后,将在函数参数中显示文本。标签及其容器视图都是以编程方式创建的。当标签中有长文本时,我希望标签和视图的高度都增加。当标签的文本太长时,标签不会增长-随后文本也不会剪切/转到下一行。我正在尝试使容器视图基于文本以编程方式扩展。
我尝试了一种扩展功能,该功能可以检测标签何时被截断。使用该扩展名,我在标签和视图上使用了+=
运算符,但没有运气就扩展了它们两者。
while label.isTruncated {
print("printing while truncating in the while loop")
regView.frame.size.height += 5
label.frame.size.height += 5
}
有趣的是,我之前使用过该代码,并在情节提要中将视图的高度限制加5以扩大文本标签的大小,并且可以正常工作。那使我相信我的问题可能存在于编辑regView
的高度约束中。
我尝试了
的无数变体 label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 3
label.lineBreakMode = .byWordWrapping
label.translatesAutoresizingMaskIntoConstraints = false
label.frame.size.height = regView.frame.size.height
label.sizeToFit()
regView.layoutSubviews()
我尝试过更改视图和标签的框架,更改代码顶部的内容以及其他问题的答案。
代码:
截断的标签扩展名:
extension UILabel {
var isTruncated: Bool {
guard let labelText = text else {
return false
}
let labelTextSize = (labelText as NSString).boundingRect(
with: CGSize(width: frame.size.width, height: .greatestFiniteMagnitude),
options: .usesLineFragmentOrigin,
attributes: [.font: font],
context: nil).size
return labelTextSize.height > bounds.size.height
}
}
查看约束更改器:
extension UIView {
func updateConstraint(attribute: NSLayoutAttribute, constant: CGFloat) -> Void {
if let constraint = (self.constraints.filter{$0.firstAttribute == attribute}.first) {
constraint.constant = constant
self.layoutIfNeeded()
}
}
}
整个功能:
func addDisapearingView(toview: UIView, text: String, textColor: UIColor, colorView: UIColor, alpha: CGFloat, height: CGFloat){
regView.backgroundColor = colorView
regView.alpha = alpha
regView.frame = CGRect(x: toview.bounds.minX, y: toview.bounds.minY, width: toview.frame.size.width, height: height)
toview.addSubview(regView)
regView.translatesAutoresizingMaskIntoConstraints = false
if #available(iOS 11.0, *) {
let guide = toview.safeAreaLayoutGuide
regView.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
regView.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
regView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
regView.heightAnchor.constraint(equalToConstant: height).isActive = true
} else {
NSLayoutConstraint(item: regView,
attribute: .top,
relatedBy: .equal,
toItem: toview, attribute: .top,
multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: regView,
attribute: .leading,
relatedBy: .equal, toItem: toview,
attribute: .leading,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: regView, attribute: .trailing,
relatedBy: .equal,
toItem: toview,
attribute: .trailing,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: regView, attribute: NSLayoutAttribute.height, relatedBy: .equal, toItem: toview, attribute: .height, multiplier: 1.0, constant: height).isActive = true
//regView.heightAnchor.constraint(equalToConstant: height).isActive = true
}
let label = UILabel(frame: CGRect(x: regView.frame.origin.x, y: regView.frame.origin.y, width: regView.frame.width, height: height))
label.text = text
label.font = UIFont(name: "Arial", size: 12)
label.textColor = textColor
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 3
label.lineBreakMode = .byWordWrapping
label.translatesAutoresizingMaskIntoConstraints = false
label.frame.size.height = regView.frame.size.height
label.sizeToFit()
regView.layoutSubviews()
regView.addSubview(label)
print("Label Height: \(label.frame.height)")
print("Reg view height: \(regView.frame.height)")
while label.isTruncated {
print("label is truncated")
regView.frame.size.height += 5
label.frame.size.height += 5
label.updateConstraint(attribute: NSLayoutAttribute.height, constant: regView.frame.height)
label.updateConstraint(attribute: NSLayoutAttribute.width, constant: regView.frame.width)
regView.layoutSubviews()
label.sizeToFit()
print("Label Height: \(label.frame.height)")
print("Reg view height: \(regView.frame.height)")
}
//remove
Timer.scheduledTimer(withTimeInterval: 2.8, repeats: false) { (action) in
UIView.animate(withDuration: 2.8, animations: {
self.regView.removeFromSuperview()
label.removeFromSuperview()
})
}
}
其调用者为:ReusableView().addDisapearingView(toview: self.view, text: "Anonymous posts will still show up in your profile page!, more text text to test in teh view that doen't work!", textColor: UIColor.white, colorView: UIColor.darkGray, alpha: 0.9, height: 20)
有趣的事情(我尝试修复)是,即使将高度设置为40
或可以容纳两行文本的值,标签仍然不会不会展开/截断,如果高度参数为20
,则不会。
任何帮助将不胜感激!
答案 0 :(得分:1)
我想您完全需要自动布局,并使regView
根据标签文本展开而没有任何高度限制
let regView = UIView()
func addDisapearingView(toview: UIView, text: String, textColor: UIColor, colorView: UIColor, alpha: CGFloat, height: CGFloat){
regView.backgroundColor = colorView
regView.alpha = alpha
toview.addSubview(regView)
regView.translatesAutoresizingMaskIntoConstraints = false
if #available(iOS 11.0, *) {
let guide = toview.safeAreaLayoutGuide
NSLayoutConstraint.activate([
regView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
regView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
regView.topAnchor.constraint(equalTo: guide.topAnchor),
// regView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
// regView.heightAnchor.constraint(equalToConstant: height).isActive = true
])
} else {
NSLayoutConstraint(item: regView,
attribute: .top,
relatedBy: .equal,
toItem: toview, attribute: .top,
multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: regView,
attribute: .leading,
relatedBy: .equal, toItem: toview,
attribute: .leading,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: regView, attribute: .trailing,
relatedBy: .equal,
toItem: toview,
attribute: .trailing,
multiplier: 1.0,
constant: 0).isActive = true
// NSLayoutConstraint(item: regView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: .equal, toItem: toview, attribute: .height, multiplier: 1.0, constant: height).isActive = true
//regView.heightAnchor.constraint(equalToConstant: height).isActive = true
}
let label = UILabel()
label.text = text
label.font = UIFont(name: "Arial", size: 12)
label.textColor = textColor
label.numberOfLines = 3
label.lineBreakMode = .byWordWrapping
label.translatesAutoresizingMaskIntoConstraints = false
regView.addSubview(label)
NSLayoutConstraint.activate([
label.trailingAnchor.constraint(equalTo: regView.trailingAnchor),
label.leadingAnchor.constraint(equalTo: regView.leadingAnchor),
label.topAnchor.constraint(equalTo: regView.topAnchor),
label.bottomAnchor.constraint(equalTo: regView.bottomAnchor) // this is the key behind expanding
])
Timer.scheduledTimer(withTimeInterval:3, repeats: false) { (action) in
UIView.animate(withDuration: 2.8, animations: {
self.regView.removeFromSuperview()
})
}
}
编辑:
let regView = UIView()
func addDisapearingView(toview: UIView, text: String, textColor: UIColor, colorView: UIColor, alpha: CGFloat, height: CGFloat){
regView.backgroundColor = colorView
regView.alpha = alpha
toview.addSubview(regView)
regView.translatesAutoresizingMaskIntoConstraints = false
var topCon:NSLayoutConstraint!
if #available(iOS 11.0, *) {
let guide = toview.safeAreaLayoutGuide
topCon = regView.bottomAnchor.constraint(equalTo: guide.topAnchor)
topCon.isActive = true
NSLayoutConstraint.activate([
regView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
regView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
// regView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
// regView.heightAnchor.constraint(equalToConstant: height).isActive = true
])
} else {
topCon = NSLayoutConstraint(item: regView,
attribute: .bottom,
relatedBy: .equal,
toItem: toview, attribute: .top,
multiplier: 1.0, constant: 0)
topCon.isActive = true
NSLayoutConstraint(item: regView,
attribute: .leading,
relatedBy: .equal, toItem: toview,
attribute: .leading,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: regView, attribute: .trailing,
relatedBy: .equal,
toItem: toview,
attribute: .trailing,
multiplier: 1.0,
constant: 0).isActive = true
// NSLayoutConstraint(item: regView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: .equal, toItem: toview, attribute: .height, multiplier: 1.0, constant: height).isActive = true
//regView.heightAnchor.constraint(equalToConstant: height).isActive = true
}
let label = UILabel()
label.text = text
label.font = UIFont(name: "Arial", size: 12)
label.textColor = textColor
label.numberOfLines = 3
label.lineBreakMode = .byWordWrapping
label.translatesAutoresizingMaskIntoConstraints = false
regView.addSubview(label)
NSLayoutConstraint.activate([
label.trailingAnchor.constraint(equalTo: regView.trailingAnchor),
label.leadingAnchor.constraint(equalTo: regView.leadingAnchor),
label.topAnchor.constraint(equalTo: regView.topAnchor),
label.bottomAnchor.constraint(equalTo: regView.bottomAnchor) // this is the key behind expanding
])
regView.layoutIfNeeded()
topCon.constant += self.regView.frame.height
UIView.animate(withDuration: 2) {
toview.layoutIfNeeded()
}
Timer.scheduledTimer(withTimeInterval:3, repeats: false) { (action) in
UIView.animate(withDuration: 2.8, animations: {
self.regView.removeFromSuperview()
})
}
}