Khant Thu Linn
Khant Thu Linn

Reputation: 6133

iOS update tableheader height after image is downloaded (constraint is not updated)

I have an image in Tableheader like this.

enter image description here

After image is downloaded, I need to update height of that image and also update height for tableheader.

[self.ivMain setImageWithURL:[NSURL URLWithString:@"http://www.naturefineartphotos.com/wordpress/wp-content/uploads/2014/11/utah_aspenfamilyportrait_1001.jpg"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

    dispatch_async(dispatch_get_main_queue(), ^{
        CGFloat height = (image.size.height/ image.size.width) * CGRectGetWidth(self.frame);
        [self.constraintIVMainHeight setConstant:height];

        [self.delegate setTableHeader];
    });

} usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

But tableheader height is not changed. I guess tableview restrict and I try to update my layout outside like this.

- (void)setTableHeader {
        [self.vwEventDetail removeFromSuperview];
        [self.tblDetail setTableHeaderView:[[UIView alloc] initWithFrame:CGRectZero]];
        [self.vwEventDetail layoutSubviews];
        [self.vwEventDetail setNeedsLayout];
        [self.tblDetail setTableHeaderView:self.vwEventDetail];
}

It is also not okay. How shall I do? If I use auto-resizing, it is easy. Why using constraint is difficult? Am I doing something wrong?

Upvotes: 1

Views: 182

Answers (1)

hasan
hasan

Reputation: 24185

Fact: Constraints doesn't apply to the tableheader view. It always needs to set its frame to resize.

Problems:

(1) you are layouting a view that does not have a superview. That doesn't work.

[self.vwEventDetail removeFromSuperview];

(2) when you set the tableview header the view you used became the header view. and header view doesn't work with height constraint. it will just ignore it. even if you layout it after you set it.

Proposed solution:

  1. Define a global int variable that holds the tableview all the time. init it with zero.
  2. When download complete set the new height to that var.
  3. update the height constraint on you image or its superview.
  4. then, layout the controller view. (self.view).
  5. in layout viewDidLayoutSubviews set the table header frame by using the height var.

note: keep your views on the header view all the time. add them in storyboard and don't remove it in runtime.

Snapshot: enter image description here

Code Sample (Swift):

class ViewController: UIViewController {

    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var headerView: UIView!
    @IBOutlet weak var imageHeightConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func donwloadFinished() {
        imageHeightConstraint.constant 
                  = (image.size.height/ image.size.width) * CGRectGetWidth(self.frame);
        self.view.layoutIfNeeded()
        self.view.layoutSubviews()
        self.view.setNeedsLayout()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        headerView.frame = containerView.frame
    }
}

Public github project

Upvotes: 2

Related Questions