如何使用UITableViewController设置今天的扩展高度?

时间:2015-03-26 23:39:44

标签: ios swift height ios8-today-widget today-extension

我正在与我的小部件高度战斗大约一个星期,我仍然无法让它工作。我使用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

0 个答案:

没有答案