Search code examples
iosswiftuitableviewstoryboard

How to create UITableview first index cell show on half banner view using Swift?


My scenario, I am trying to create UITableview with card effects and top banner. I have added It will work like stretchable tableview header. Everything I am done by using storyboard but I am stuck in showing half of tableview first index cell show on banner head. I tried multiple ideas but I didn’t completed. Provide some idea for achieve this design.

Current Output:

Current output screen

Expected Output:

Expected output screen


Solution

  • From your demo project HERE I have made some changes to you existing code like your scrollViewDidScroll will be:

    var lastContentOffset: CGFloat = 0
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        self.lastContentOffset = scrollView.contentOffset.y
    }
    
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
    
        if self.lastContentOffset < scrollView.contentOffset.y {
            //Up
            let y = 220 - (scrollView.contentOffset.y + 220)
            let height = min(max(y, 60), 220)
            if height >= 128 {
                imageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: height + 70)
            }
        } else if self.lastContentOffset > scrollView.contentOffset.y {
            //Down
            let y = 300 - (scrollView.contentOffset.y + 300)
            let height = min(max(y, 60), 400)
            imageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: height + 80)
        }
    }
    

    With above code I have added different conditions for up and down as per your requirement and from storyboard I have change top constraint to 84 so that your table will not scroll to top.

    enter image description here

    So your full code will look like:

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var tableView: UITableView!
    
        let imageView = UIImageView()
        var lastContentOffset: CGFloat = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
            tableView.estimatedRowHeight = 50
            tableView.contentInset = UIEdgeInsetsMake(220, 0, 0, 0)
            tableView.backgroundColor = UIColor.darkGray
    
    
            imageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 300)
            imageView.image = UIImage.init(named: "poster")
            imageView.contentMode = .scaleAspectFill
            imageView.clipsToBounds = true
            view.addSubview(imageView)
            self.tableView.backgroundColor = .clear
            self.view.bringSubview(toFront: tableView)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
    
    extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 20
        }
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return UITableViewAutomaticDimension
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
            switch indexPath.row % 2 {
            case 0:
                cell.titleLabel.text = "Lorem Ipsum is simply dummy text ."
                cell.contentView.backgroundColor = UIColor.darkGray
            default:
                cell.contentView.backgroundColor = UIColor.black
                cell.titleLabel.text = "There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."
                cell.titleLabel.textColor = .white
            }
            return cell
        }
    
        func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
            self.lastContentOffset = scrollView.contentOffset.y
        }
    
    
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
    
            if self.lastContentOffset < scrollView.contentOffset.y {
                let y = 220 - (scrollView.contentOffset.y + 220)
                let height = min(max(y, 60), 220)
                if height >= 128 {
                    imageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: height + 70)
                }
            } else if self.lastContentOffset > scrollView.contentOffset.y {
                let y = 300 - (scrollView.contentOffset.y + 300)
                let height = min(max(y, 60), 400)
                imageView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: height + 80)
            }
        }
    }
    

    And result will be:

    enter image description here

    HERE is the link for your updated project.