我正在与我的小部件高度战斗大约一个星期,我仍然无法让它工作。我使用tableView作为自动布局的扩展的主要视图。
该应用程序显示手机的当前余额。根据计划,我加载不同的自定义视图。
加载扩展程序时似乎工作正常(https://www.dropbox.com/s/zkoddb7o3zlvdl8/widget-normal.png?dl=0)但是当我点击重新加载按钮时,窗口小部件的高度会受到挤压(https://www.dropbox.com/s/u2gruah8268162d/widget-squeezed.png?dl=0)
这是我的代码:
class TodayTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, NCWidgetProviding {
<...>
// ask the `NSFetchedResultsController` for the section
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let info = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
return min(2, info.numberOfObjects)
}
// MARK: - table footer height
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 1.0
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return UIView(frame: CGRectZero)
}
override func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 44.0
}
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let info = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
if info.numberOfObjects > 0 {
return expandButton
} else {
let label = UILabel()
label.text = "No data"
label.textAlignment = .Center
label.textColor = UIColor.lightTextColor()
label.font = UIFont.systemFontOfSize(12.0)
return label
}
}
// create and configure each `UITableViewCell`
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let item = self.fetchedResultsController.objectAtIndexPath(indexPath) as Lines
let cell = tableView.dequeueReusableCellWithIdentifier("Carrier Cell", forIndexPath: indexPath) as CarrierCell
// Configure the cell
cell.configure(item, atIndexPath: indexPath)
let formatter = NSNumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US")
formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
var balanceView:UIView = UIView()
var frameHeight:CGFloat = 0.0
// Detect carrier
switch item.carrier {
case Constants.Carrier1.carrierName:
if let balance:Carrier1 = item.lastUpdatedBalance() {
cell.lastUpdateLabel.text = "Updated\n\(balance.date.timeAgo.lowercaseString)"
cell.refreshButton.enabled = true
// detect plan type
switch balance.planType {
case Carrier1PlanType.Prepaid.rawValue:
frameHeight = 50.0 // 40.0
let aView = Carrier1PrepaidBalanceView(frame: CGRectMake(0, 0, tableView.contentSize.width, frameHeight))
aView.realSaldoValueLabel?.text = "$" + formatter.stringFromNumber( balance.taDeposited )!
aView.virtualSaldoValueLabel?.text = "$" + formatter.stringFromNumber( balance.taGifted )!
aView.totalSaldoValueLabel?.text = "$" + formatter.stringFromNumber( balance.taTotal )!
balanceView = aView
case Carrier1PlanType.Postpaid.rawValue:
frameHeight = 129.0 // 106.0
let aView = Carrier1PostpaidBalanceView(frame: CGRectMake(0, 0, tableView.contentSize.width, frameHeight))
<...>
balanceView = aView
case Carrier1PlanType.Hybrid.rawValue:
frameHeight = 139.0 // 114
let aView = Carrier1HybridBalanceView(frame: CGRectMake(0, 0, tableView.contentSize.width, frameHeight))
<...>
balanceView = aView
default:
NSLog("Unknown plan type: \(balance.planType)")
abort()
}
} else {
println("No data found")
// start fetching data
startFetchingData(forPhoneNumber: item.phoneNumber, fromCarrier: item.carrier, completeHandler: {
cell.refreshButton.enabled = true
self.updateView()
})
}
default:
NSLog("Unknown carrier: \(item.carrier)")
abort()
}
// Add subview and constraints
let heightConstraint = NSLayoutConstraint(
item: cell.dataView!,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: NSLayoutAttribute.NotAnAttribute,
multiplier: 1.0,
constant: frameHeight
)
cell.dataView.addConstraint(heightConstraint)
cell.dataView.frame = CGRectMake(0, 0, tableView.contentSize.width, frameHeight)
cell.dataView.addSubview(balanceView)
return cell
}
override var preferredContentSize:CGSize {
willSet {
tableView.layoutIfNeeded()
}
}
let expandButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
expandButton.setTitle("Show all", forState: .Normal)
expandButton.addTarget(self, action: "showAlldButtonTouched", forControlEvents: .TouchUpInside)
expandButton.setTitleColor(UIColor.lightGrayColor(), forState: .Highlighted)
tableView.estimatedRowHeight = 52.0
tableView.rowHeight = UITableViewAutomaticDimension
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
preferredContentSize = tableView.contentSize
println("Width on appear: \(self.tableView.contentSize.width)")
println("Height on appear: \(self.tableView.contentSize.height)")
}
@IBAction func reloadButtonTouched(button: UIButton) {
button.enabled = false
let indexPath = NSIndexPath(forRow: button.tag, inSection: 0)
let item = self.fetchedResultsController.objectAtIndexPath(indexPath) as Lines
// start fetching data
println("fetch started \(item.phoneNumber)")
startFetchingData(forPhoneNumber: item.phoneNumber, fromCarrier: item.carrier, completeHandler: { [unowned self] in
button.enabled = true
self.updateView()
println("Width on reload: \(self.tableView.contentSize.width)")
println("Height on reload: \(self.tableView.contentSize.height)")
})
}
func updateView() {
tableView.reloadData()
preferredContentSize = tableView.contentSize
}
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
println("Width on update: \(tableView.contentSize.width)")
println("Height on update: \(tableView.contentSize.height)")
updateView()
completionHandler(NCUpdateResult.NewData)
}
}
class CarrierCell: UITableViewCell {
@IBOutlet weak var lineNameLabel: UILabel!
@IBOutlet weak var phoneNumberLabel: UILabel!
@IBOutlet weak var lastUpdateLabel: UILabel!
@IBOutlet weak var refreshButton: UIButton!
@IBOutlet weak var dataView: UIView!
override func awakeFromNib() {
super.awakeFromNib()
}
func configure(item: Lines, atIndexPath indexPath: NSIndexPath) {
<...>
}
}
日志:
balanceRequestFinished
Width on reload: 320.0
Height on reload: 335.0
Width on update: 320.0
Height on update: 335.0
Width on appear: 320.0
Height on appear: 335.0
Width on update: 320.0
Height on update: 335.0
Width on appear: 320.0
Height on appear: 335.0
更新28/03/2015于10:42 更新了updateView方法:
func updateView() {
println( "View height before updateView: \(self.view.frame.size.height)")
println( "TableView height before updateView: \(tableView.contentSize.height)" )
tableView.reloadData()
preferredContentSize = tableView.contentSize
println( "View height after updateView: \(self.view.frame.size.height)")
println( "TableView height after updateView: \(tableView.contentSize.height)" )
}
高度正确时记录:
Width on update: 320.0
Height on update: 335.0
View height before updateView: 335.0
TableView height before updateView: 335.0
View height after updateView: 335.0
TableView height after updateView: 335.0
Width on appear: 320.0
Height on appear: 335.0
在扩展名被挤压时记录:
balanceRequestFinished
View height before updateView: 335.0
TableView height before updateView: 335.0
View height after updateView: 335.0
TableView height after updateView: 335.0
Width on reload: 320.0
Height on reload: 335.0