4

I have a UITableViewController. This table view has an header view. I use main.storyboard with autolayout to set my controller.

In my main.storyboard, for w:Any h:Any, the preview of my view controller is set with the default size 600x600. Inside, my header view is set to 600x200.

In my header view, I have an imageView set to the Aspect Fill mode:

main.storyboard

The constraints :

constraints

In the assets, my image has @2x and @3x sizes.

When I compile, in the simulator I obtain for iPhone 5:

IPH5

For iPhone 6:

IPH6

For iPhone 6+:

IPH6+

  • For the iPhone 5, the image starts below the status bar. I don't understand why?
  • For the iPhone 6 and iPhone 6+, the image crops the first cell of my table view. And the top of the image isn't adjust with the top of the view.

I don't know how to adjust the height of the tableHeaderView to the height of my image, because this height depends on the device.

I have tried to set programmatically the frame of the header, in vain:

 var frame:CGRect!
 frame.size.width = self.bgHeaderImageView.image?.size.width
 frame.size.height = self.bgHeaderImageView.image?.size.height
 self.tableView.tableHeaderView?.frame = frame

I got 2 errors : "Value optional type CGFloat? not unwrapped"

And if I correct with

 var frame:CGRect!
 frame.size.width = self.bgHeaderImageView.image?.size.width!
 frame.size.height = self.bgHeaderImageView.image?.size.height!
 self.tableView.tableHeaderView?.frame = frame

I got 2 errors : "Operand of postfix ! should have optional type"

Is it to possible to adjust the size in the storyboard directly and not programmatically ?

I'm probably missing something here...

3 Answers 3

4

The UITableView tableHeaderView has no option for aspect ratio and autolayout usage of the tableHeaderView is limited in InterfaceBuilder. There are many ways to achieve a dynamic height of the tableHeaderView. If you want to have a tableHeaderView height based on the ratio of a header image you can use:

let width = UIScreen.mainScreen().bounds.size.width
self.height = (width/640) * 209 //calculate new height
self.tableView.tableHeaderView?.frame.size = CGSize(width: self.tableView.tableHeaderView!.frame.size.width, height: self.height)
Sign up to request clarification or add additional context in comments.

Comments

3

I found a solution, it's not very clean, but it works.

  var kTableHeaderHeight:CGFloat! //expected height of the header tableview

  var image: UIImage = UIImage(named: "my-image")!

  var frame:CGRect!=self.tableView.tableHeaderView?.frame
  if UIScreen.mainScreen().bounds.size.width <= 320 { //iPhone 5 and less
      frame.size.width = 320
      frame.size.height = 212
   } else { //iPhone 6 @2x and iPhone 6+ @3x
      frame.size.width = image.size.width
      frame.size.height = image.size.height
   }
   self.tableView.tableHeaderView?.frame = frame

2 Comments

thanks for sharing your solution! you helped me with a similar problem, which I want to share just in case someone else experienced it: instead of an uiimageView as background I have a uisearchbar and uibuttons and the height of the tableHeaderView (and tableFooterView as well) would be way to big and stretch over the whole screen height. I couldn't believe there was no possibility in Interface Builder to fix that, or that this error occured in the first place - to me this seems like a bug in the SDK and setting the frame explicitly in viewDidLoad solved it. (iOS 8.2 & XCode 6.2 & OS X 10.9.5)
this is terrible.
0

Try this

    self.edgesForExtendedLayout = UIRectEdge.None
    self.automaticallyAdjustsScrollViewInsets = false
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)

And this too

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0
    {
        return 1
    }
    else
    {
        return 40; // your other headers height value
    }
}

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if section == 0
    {
        // Note CGFloat.min for swift
        // For Objective-c CGFLOAT_MIN
        let headerView = UIView.init(frame: CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, CGFloat.min))
        return headerView
    }
    else
    { 
        // Construct your other headers here 
        return UIView()
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.