更新基于UIScrollView的UITableView高度

时间:2015-05-26 11:36:23

标签: ios uitableview swift uiscrollview

我在更新UIScrollView的尺寸时遇到了一些问题,无法调整到UITableView高度变化。

我的UITableView不可滚动。相反,我的视图大小会根据UITableView中的单元格数量而变化。

我有一个UIViewController我用来加载3个不同的数据集。 (这需要更新我的UITableView以经常容纳不同数量的数据)

因此,当我加载第一个数据集时,它可以正常工作。

然而,如果我之后加载一个新的,具有不同数量的单元格。我的UIScrollView的contentSize现在错了。 (它保持了以前数据集的大小)。

以下是一个例子:

enter image description here

我从拥有更多单元格的数据集开始。对少一个。你可以看到我能够向下滚动得比我应该的更多。 (contentSize的结尾应该在白色区域后停止16点。

尝试解决这个问题一段时间之后,我确实设法让一些工作正常。我从API获取数据,有时需要很长时间才能获取。但是,当它完成更新我的tableView中的所有数据时,我能够使用以下代码行将contentize修复为我想要的内容:

self.scrollView.contentSize = CGSize(width:self.view.bounds.width, height: self.contentView.frame.height)

之后的第一个动作就是提前做好。 (在我尝试更新数据之前。)但不幸的是,它似乎根本没有做任何事情。

那么,一旦我用CoreData中的数据重新加载我的UITableView(在尝试获取新数据之前),我怎么能正确设置我的contentSize?

这是加载数据的函数。 (这会立即发生。重新加载后,这是此函数的结束,我需要修复内容。

func loadPortfolio() {

    println("----- Loading Portfolio Data -----")
    // Set the managedContext again.
    managedContext = appDelegate.managedObjectContext!

    // Check what API to get the data from
    if Formula == 1 {
        formulaEntity = "PortfolioBasic"
        println("Setting Entity: \(formulaEntity)")
        formulaAPI = NSURL(string: "http://api.com/json/monthly_entry.json")
    } else if Formula == 2 {
        formulaEntity = "PortfolioPremium"
        formulaAPI = NSURL(string: "http://api.com/json/monthly_proff.json")
        println("Setting Entity: \(formulaEntity)")
    } else if Formula == 3 {
        formulaEntity = "PortfolioBusiness"
        println("Setting Entity: \(formulaEntity)")
        formulaAPI = NSURL(string: "http://api.com/json/monthly_fund.json")
    } else {
        println("Errror - Formula out of range.")
    }

    // Delete all the current objects in the dataset
    let fetchRequest = NSFetchRequest(entityName: formulaEntity)
    let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
    stocks.removeAll(keepCapacity: false)
    for mo in a {
        stocks.append(mo)
    }

    // Saving the now empty context.
    managedContext.save(nil)


    // Setting the first cell to be white
    cellAlteration = 0

    // Reload the tableview with the new data.
    self.pHoldingsTable.reloadData()

    tableHeight.constant = CGFloat(stocks.count*50)


    // This doesn't work here for some reason?
    self.scrollView.contentSize = CGSize(width:self.view.bounds.width, height: self.contentView.frame.height)

println("Finished loading portfolio")


    self.view.hideLoading()

    dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {
        self.updatePortfolio()
    }

}

我还尝试在约束更新之前放置scrollView相关行,但这也不起作用。

然而。下面是我的updatePortfolio()函数,它使用完全相同的代码行,并且工作正常。一旦完成运行,我的contentView将被设置为正确的大小。

func updatePortfolio() {
    println("Updating Portfolio")
    if Reachability.isConnectedToNetwork() == false {
        println("ERROR: - No Internet Connection")
    } else {
        // Delete all the current objects in the dataset
        let fetchRequest = NSFetchRequest(entityName: formulaEntity)
        let a = managedContext.executeFetchRequest(fetchRequest, error: nil) as! [NSManagedObject]
        for mo in a {
            managedContext.deleteObject(mo)
        }
        // Removing them from the array
        stocks.removeAll(keepCapacity: false)
        // Saving the now empty context.
        managedContext.save(nil)

        // Set up a fetch request for the API data
        let entity =  NSEntityDescription.entityForName(formulaEntity, inManagedObjectContext:managedContext)
        var request = NSURLRequest(URL: formulaAPI!)
        var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
        var formula = JSON(data: data!)

        // Loop through the api data.
        for (index: String, portfolio: JSON) in formula["portfolio"] {

            // Save the data into temporary variables
            stockName = portfolio["name"].stringValue.lowercaseString.capitalizedString
            ticker = portfolio["ticker"].stringValue
            purchasePrice = portfolio["purchase_price"].floatValue
            weight = portfolio["percentage_weight"].floatValue


            // Set up CoreData for inserting a new object.
            let stock = NSManagedObject(entity: entity!,insertIntoManagedObjectContext:managedContext)

            // Save the temporary variables into coreData
            stock.setValue(stockName, forKey: "name")
            stock.setValue(ticker, forKey: "ticker")
            stock.setValue(action, forKey: "action")
            stock.setValue(purchasePrice, forKey: "purchasePrice")
            stock.setValue(weight, forKey: "weight")

            // Doing a bunch of API calls here. Irrelevant to the question and took up a ton of code, so skipped it to make it more readable.


            // This can simply be set, because it will be 0 if not found.
            stock.setValue(lastPrice, forKey: "lastPrice")

            // Error handling
            var error: NSError?
            if !managedContext.save(&error) {
                println("Could not save \(error), \(error?.userInfo)")
            }
            // Append the object to the array. Which fills the UITableView
            stocks.append(stock)
        }

        NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
            // Setting the first cell to be white
            cellAlteration = 0
            self.tableHeight.constant = CGFloat(self.stocks.count*50)
            self.pHoldingsTable.reloadData()
            self.scrollView.contentSize = CGSize(width:self.view.bounds.width, height: self.contentView.frame.height)
            println("Finished Updating Portfolio")
        })
    }
}

我还尝试将tableHeight约束置于重载之上,就像它在更新函数中一样。但它并没有什么不同。

以下是我的UIScrollView设置方式:

    override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    scrollView.frame = view.bounds
    scrollView.contentSize = CGSize(width:self.view.bounds.width, height: contentView.frame.height)
}

第一次始终获得正确的尺寸。但是因为tableView更改时不调用此函数。它不会自动更新contentSize。

我的contentView.frame.height会根据UITableView中的单元格数量而变化。它不是一个固定的高度。 (我从不希望我的UITableView本身在它的框内滚动)

另外,如果我的问题与约束相关而不是我的函数,我会以编程方式完成所有操作。我没有使用故事板或XIB文件。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

我认为你要找的是分组的tableviews风格。

可以肯定的是:你唯一想要的就是不要在最后一个单元格下方放置无限单元格,对吧?如果是这样,您应该使用分组表视图样式。

使用该样式可以为您节省大量的工作。如果我理解你的问题。

答案 1 :(得分:0)

这是在视图和子视图之间固定约束的问题。

在scrollView中,确保tableView的顶部和底部固定到scrollview。然后,如果您希望使用tableView缩短scrollView,请确保scrollView未固定到其父视图的底部。