swift - 更改对象的框架大小后更新自动布局
问题描述
我正在使用自动布局创建一个视图,结果就是这样。
视图加载后,我抓取一些文本数据并填充 UITextView。“关于我”项目可以是多行,因此我调整了该特定框架的大小。然后,我得到以下信息。
你看到关于我的文本视图是如何覆盖下一个字段的吗?如何使用新的 about me textview 大小调整自动布局的大小?我搜索并找到了一些使用 setNeedsLayout 和 layoutIfNeeded 的建议,但没有一个有效。
我正在设置自动布局,如下所示:
inputsContainerView.addSubview(ageInput)
ageInput.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
ageInput.topAnchor.constraint(equalTo: inputsContainerView.topAnchor, constant: 10).isActive = true
ageInput.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
ageInput.heightAnchor.constraint(equalToConstant: 60).isActive = true
inputsContainerView.addSubview(genderInput)
genderInput.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
genderInput.topAnchor.constraint(equalTo: ageInput.bottomAnchor).isActive = true
genderInput.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
genderInput.heightAnchor.constraint(equalToConstant: 60).isActive = true
inputsContainerView.addSubview(aboutInput)
aboutInput.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
aboutInput.topAnchor.constraint(equalTo: genderInput.bottomAnchor).isActive = true
aboutInput.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
aboutInput.heightAnchor.constraint(equalToConstant: 60).isActive = true
inputsContainerView.addSubview(memberSinceInput)
memberSinceInput.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
memberSinceInput.topAnchor.constraint(equalTo: aboutInput.bottomAnchor).isActive = true
memberSinceInput.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
memberSinceInput.heightAnchor.constraint(equalToConstant: 60).isActive = true
视图加载后,我使用以下函数获取数据并调整 about me textview 框架的大小:
func resizeTextView(_ textView: UITextView) {
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame
}
解决方案
如果我是你,我会使用UITableView
创建此表单并在单元格内添加标签和 UITextView。
你可以UITableViewCell
像下面这样我将标签的高度设置为 60 并自动布局它。UITextView 也使用自动布局并适合单元格的底部。
import UIKit
class UserDetailCell: UITableViewCell {
var userDetailLabel : UILabel = {
var label = UILabel()
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.lightGray
return label
}()
var userDetailTextView : UITextView = {
var tv = UITextView()
tv.translatesAutoresizingMaskIntoConstraints = false
tv.isScrollEnabled = false
return tv
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupUI()
}
func setupUI(){
addSubview(userDetailLabel)
NSLayoutConstraint.activate([
userDetailLabel.topAnchor.constraint(equalTo: topAnchor),
userDetailLabel.leftAnchor.constraint(equalTo: leftAnchor, constant: 8),
userDetailLabel.rightAnchor.constraint(equalTo: rightAnchor),
userDetailLabel.heightAnchor.constraint(equalToConstant: 60)
])
addSubview(userDetailTextView)
NSLayoutConstraint.activate([
userDetailTextView.topAnchor.constraint(equalTo: userDetailLabel.bottomAnchor),
userDetailTextView.leftAnchor.constraint(equalTo: leftAnchor, constant: 8),
userDetailTextView.rightAnchor.constraint(equalTo: rightAnchor),
userDetailTextView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
那么你UIViewController
应该像下面这样。我在cellForRowAt indexPath
方法内为 UITextView 设置了一个委托。由于我设置了委托,因此textViewDidChange
将调用委托方法。它写在扩展中。
import UIKit
class UserDetailsController: UITableViewController {
let cellId = "cell"
var person = Person(myAge: 20, myGender: "Male", aboutMe: "Hello my name is jake waisee. What is your name? goayngeHello my name is jake waisee. What is your name? goayngeHello my name is jake waisee. What is your name? goayngeHello my name is jake waisee. What is your name? goaynge")
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UserDetailCell.self, forCellReuseIdentifier: cellId)
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 100
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserDetailCell
cell.userDetailTextView.delegate = self
cell.userDetailTextView.tag = indexPath.row
if indexPath.row == 0{
cell.userDetailLabel.text = "Age"
cell.userDetailTextView.text = "\(person.age)"
}else if indexPath.row == 1{
cell.userDetailLabel.text = "Gender"
cell.userDetailTextView.text = person.gender
}else if indexPath.row == 2{
cell.userDetailLabel.text = "About me"
cell.userDetailTextView.text = person.aboutMe
}
return cell
}
}
extension UserDetailsController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
print(textView.text)
if textView.tag == 2 {
person.aboutMe = textView.text
}else if textView.tag == 0 {
person.age = Int(textView.text) ?? 0
}else if textView.tag == 1 {
person.gender = textView.text
}
//this will keep the textview growing as we type
tableView.beginUpdates()
tableView.endUpdates()
}
}
推荐阅读
- c# - 将 Json 反序列化为数组类型属性
- javascript - TypeError: Cannot read property 'minify' of undefined in Nuxt.js
- android - OSM 的边界框像素坐标
- python - 尝试多进程时如何修复“TypeError:无法序列化'_io.BufferedReader'对象”错误
- javascript - 在 Azure Functions 中共享 SFTP 连接
- svn - Tortoise SVN 无法连接
- java - Android 状态栏和导航问题
- mysql - 在 Rails has_many 中排序,将字符串类型转换为十进制
- selenium - 无法使用 NightwatchJS 关闭浏览器
- u-sql - U-SQL 文本提取器整数