我正在开发一个以xib开头的UITableViewCell,以编程方式添加视图,并具有动态大小的高度。但是,在使用约束添加程序视图时,它与最初应用于xib的自动调整大小约束相冲突,并导致问题。请参阅以下内容:
让我的细胞出列:
//Table Delegate/Datasource
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:S360SSessionMatchTableCell? = tableView.dequeueReusableCellWithIdentifier(XIBFiles.SESSIONMATCHTABLECELL + String(indexPath.row)) as? S360SSessionMatchTableCell
if ((cell == nil)){
tableView.registerNib(UINib(nibName: XIBFiles.SESSIONMATCHTABLECELL, bundle: nil), forCellReuseIdentifier: XIBFiles.SESSIONMATCHTABLECELL + String(indexPath.row))
cell = tableView.dequeueReusableCellWithIdentifier(XIBFiles.SESSIONMATCHTABLECELL + String(indexPath.row)) as? S360SSessionMatchTableCell
}
cell!.setupEvents(sessionMatches[indexPath.row]["sessions"]! as! [[String:String]])
return cell!
}
自定义UITableViewCell中的设置事件方法:
func setupEvents(events:[[String:String]]){
//Set up start and end times
self.startTimeLbl.text = events[0]["startTime"]!
self.endTimeLbl.text = events[events.count - 1]["endTime"]!
//Set up events
var pastEventView:S360SScheduledEventView? = nil
var pastEvent:[String:String]? = nil
for (index, event) in events.enumerate(){
var topAnchor:NSLayoutConstraint!
//Create event view
let eventView:S360SScheduledEventView = NSBundle.mainBundle().loadNibNamed(XIBFiles.SCHEDULEDEVENTVIEW, owner: self, options: nil)[0] as! S360SScheduledEventView
//Deal with first view added
if pastEvent == nil{
//Top anchor setup for first view
topAnchor = NSLayoutConstraint(item: eventView, attribute: .Top, relatedBy: .Equal, toItem: toLbl, attribute: .Bottom, multiplier: 1, constant: 10)
}
else{
//Check for a break
let timeFormatter:NSDateFormatter = NSDateFormatter()
timeFormatter.dateFormat = "hh:mm a"
let startTime = timeFormatter.dateFromString(pastEvent!["endTime"]!)
let endTime = timeFormatter.dateFromString(event["startTime"]!)
if startTime != endTime {
//Create break view
let breakView = NSBundle.mainBundle().loadNibNamed(XIBFiles.SCHEDULEDBREAKVIEW, owner: self, options: nil)[0] as! S360SScheduledBreakView
//Setup breakview constraints
let bTopAnchor = NSLayoutConstraint(item: breakView, attribute: .Top, relatedBy: .Equal, toItem: pastEventView, attribute: .Bottom, multiplier: 1, constant: 0)
let bLeftAnchor = NSLayoutConstraint(item: breakView, attribute: .Leading, relatedBy: .Equal, toItem: self.contentView, attribute: .LeadingMargin, multiplier: 1, constant: 0)
let bRightAnchor = NSLayoutConstraint(item: breakView, attribute: .Trailing, relatedBy: .Equal, toItem: self.contentView, attribute: .TrailingMargin, multiplier: 1, constant: 0)
let bHeightAnchor = NSLayoutConstraint(item: breakView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 30)
//Add break view and constraints
self.addSubview(breakView)
self.addConstraints([bTopAnchor, bLeftAnchor, bRightAnchor, bHeightAnchor])
//Top anchor setup for subsequent view
topAnchor = NSLayoutConstraint(item: eventView, attribute: .Top, relatedBy: .Equal, toItem: breakView, attribute: .Bottom, multiplier: 1, constant: 0)
}
else{
//Top anchor setup for subsequent views
topAnchor = NSLayoutConstraint(item: eventView, attribute: .Top, relatedBy: .Equal, toItem: pastEventView, attribute: .Bottom, multiplier: 1, constant: 0)
}
}
//Setup other anchors
let leftAnchor = NSLayoutConstraint(item: eventView, attribute: .Leading, relatedBy: .Equal, toItem: self.contentView, attribute: .LeadingMargin, multiplier: 1, constant: 0)
let rightAnchor = NSLayoutConstraint(item: eventView, attribute: .Trailing, relatedBy: .Equal, toItem: self.contentView, attribute: .TrailingMargin, multiplier: 1, constant: 0)
let heightAnchor = NSLayoutConstraint(item: eventView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 60)
//Setup event view
eventView.iconImg.image = Images.get_event_image(event["title"]!)
eventView.titleLbl.text = event["title"]!
eventView.courtLbl.text = "court" + event["court"]!
eventView.timeLbl.text = event["startTime"]! + " to " + event["endTime"]!
//Add event view and constraints
self.addSubview(eventView)
self.addConstraints([topAnchor, leftAnchor, rightAnchor, heightAnchor])
//Prepare for next iteration
pastEventView = eventView
pastEvent = event
//Set up last cell with bottom bound
if index == events.count - 1 {
let bottomAnchor = NSLayoutConstraint(item: eventView, attribute: .Bottom, relatedBy: .Equal, toItem: self.contentView, attribute: .BottomMargin, multiplier: 1, constant: 0)
self.addConstraint(bottomAnchor)
}
}
}
这是我得到的错误(粘贴一次,但每个单元格都会出现):
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2016-07-05 15:13:01.654 Shoot360 Scheduler[32779:642808] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSAutoresizingMaskLayoutConstraint:0x7fedd85d5590 h=--& v=--& V:[UITableViewCellContentView:0x7fedda431120(44)]>",
"<NSLayoutConstraint:0x7fedda43a7e0 V:[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda438b20(60)]>",
"<NSLayoutConstraint:0x7fedda436590 UITableViewCellContentView:0x7fedda431120.topMargin == UILabel:0x7fedda4312a0'10:00 AM'.top - 15>",
"<NSLayoutConstraint:0x7fedda436630 UILabel:0x7fedda431c00'to'.top == UILabel:0x7fedda4312a0'10:00 AM'.top>",
"<NSLayoutConstraint:0x7fedda433b60 V:[UILabel:0x7fedda431c00'to']-(10)-[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda438b20]>",
"<NSLayoutConstraint:0x7fedda445910 V:[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda4443f0(60)]>",
"<NSLayoutConstraint:0x7fedda448310 V:[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda438b20]-(0)-[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda4443f0]>",
"<NSLayoutConstraint:0x7fedda449a00 V:[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda448540(60)]>",
"<NSLayoutConstraint:0x7fedda4479e0 V:[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda4443f0]-(0)-[Shoot360_Scheduler.S360SScheduledEventView:0x7fedda448540]>",
"<NSLayoutConstraint:0x7fedda44a100 Shoot360_Scheduler.S360SScheduledEventView:0x7fedda448540.bottom == UITableViewCellContentView:0x7fedda431120.bottomMargin>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fedda436590 UITableViewCellContentView:0x7fedda431120.topMargin == UILabel:0x7fedda4312a0'10:00 AM'.top - 15>
行高设置为动态:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//Styling
showAllBtn.layer.cornerRadius = Numbers.CORNERRADIUS
sessionsTbl.rowHeight = UITableViewAutomaticDimension
sessionsTbl.estimatedRowHeight = 500
sessionsTbl.layer.borderColor = Colors.REALLIGHTGREY.CGColor
sessionsTbl.layer.borderWidth = Numbers.BORDERREG
sessionsTbl.layer.cornerRadius = Numbers.CORNERRADIUS
sessionsTbl.separatorStyle = UITableViewCellSeparatorStyle.None
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
答案 0 :(得分:1)
约束
N:[UITableViewCellContentView:0x7fedda431120(44)
表示当您希望单元格高度为动态时,表格中的rowHeight
设置为默认值44pt
。您必须将rowHeight
设置为UITableViewAutomaticDimension
并设置estimatedRowHeight
。
另请注意,重复使用单元格,因此每次调用setupEvents
时都必须删除所有以前添加的视图。
另请注意,您不应该从tableView.registerNib(...)
方法中调用cellForRow
。注册单元格的好地方是viewDidLoad
。
答案 1 :(得分:0)
你似乎已经让自己的生活变得更加复杂。
如果我们看一下你现在拥有的东西:
这不适合表格视图,这意味着您正在编写大量代码并尝试将其全部填充到一个位置。
查看您的数据最好有类似的内容:
在这种情况下,您的约束是微不足道的,并且在代码中没有添加约束,您只需设置一些数据,其他一切都可以正常工作。该方案还打破了您的顾虑,并将每个不同部分的代码分离为逻辑部分。
您应该退一步看看您的方法,而不是尝试修复现有问题。