Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Create a Stretchy Header Effect for UITableView in Swift for iOS

DZone 's Guide to

Create a Stretchy Header Effect for UITableView in Swift for iOS

Create a dynamic and user-friendly header for iOS applications.

· Web Dev Zone ·
Free Resource

Creating a Single View App Xcode projectA stretchable Table View header can make your application more interactive and intuitive. Android users have been taking advantage of this effect for years. Now, this feature is available for iOS applications as well. 

What You May Need to Know

You must have a clear understanding of Xcode Basics, UIKit Basics, and Autolayout.

Now let’s get into the real business.

Create a Stretchy Header Effect 

Create an Xcode project. In Xcode, open a new project and choose Single View App under iOS (Application) and select Swift as your language.

Creating a Single View App Xcode project


Set up the Table View. First, we need to create a Table View. For that, you will be required to add a UITableView to the ViewController.Adding UITableView to the ViewController


Adding UITableView to the ViewController


Set up the height of TopView and HeaderView.

After this, we need to set up the contentInset. For that, the top value that is set here is 318, which is the initial normal height for the header ImageView. The Table View’s frame will start at (0, 0), and the first cell will start at (0, 318).

var topViewSize:CGFloat = 318 // Topview height
var navigationHeight:CGFloat = 82 // Headerview height

tableView.contentInset = UIEdgeInsetsMake(topViewSize, 0, 0, 0)


Make TopView as UIView and add it to TableView Here, we have created a UIView with height 318 and added it to the current view above TableView.

var topView = TopView()
override func viewDidLoad() {
super.viewDidLoad()
let view = Bundle.main.loadNibNamed("TopView", owner: self, options: nil)![0] as! TopView
view.frame = CGRect(x: 0, y: statusHeight, width: self.view.frame.width, height: self.view.frame.width)
self.view.addSubview(view)
topView = view
tableView.estimatedRowHeight = 50
tableView.contentInset = UIEdgeInsetsMake(topViewSize, 0, 0, 0)


Here, we will load TableView and add data to it.

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
        cell.titleLabel.text = "\(indexPath.row+1). Music name."
        return cell
    }
}


After loading the Tableview, set scrollViewDidScroll() function. Here, all the UI elements are wrapped under scrollViewDidScroll(). This section of code is mostly responsible for the Stretchy Header effect.

func scrollViewDidScroll(_ scrollView: UIScrollView){
    let y = topViewSize - (scrollView.contentOffset.y + topViewSize)
    let newHeaderViewHeight = topView.frame.height - scrollView.contentOffset.y

    if(y >= navigationHeight){
        if(y<=148 && y >= navigationHeight){
            let percent:Float = (Float((148-y) / y));
            topView.albumTopButton.alpha = CGFloat(percent)
        }else{
            topView.albumTopButton.alpha = 0
        }

        topView.albumTopButton.frame.origin.y = y

        if(isOpenButton == 1){
            isOpenButton = 0
            UIView.animate(withDuration: 0.1, animations: {
                self.topView.btnAlbum.frame.origin.x = self.topView.btnAlbum.frame.origin.x + 5
                self.topView.btnMusic.frame.origin.x = self.topView.btnMusic.frame.origin.x - 5
            }) { (Bool) in
                self.shakeAnimation()
            }
        }
    }else{
        if(isOpenButton == 0){
            isOpenButton = 1
            UIView.animate(withDuration: 0.1, animations: {
                self.topView.btnAlbum.frame.origin.x = self.topView.btnAlbum.frame.origin.x - 5
                self.topView.btnMusic.frame.origin.x = self.topView.btnMusic.frame.origin.x + 5
            }) { (Bool) in
                self.shakeAnimation()
            }
        }
        topView.albumTopButton.alpha = 1
        topView.albumTopButton.frame.origin.y = 100
    }

    let height = min(max(y, navigationHeight), 800)
    topView.frame = CGRect(x: 0, y: statusHeight, width: UIScreen.main.bounds.size.width, height: height)

    if(y >= topViewSize){
        topView.albumimage.transform = CGAffineTransform(scaleX: (y/topViewSize), y: (y/topViewSize))
        topView.albumTop.constant = 25
    }else{
        topView.albumTop.constant = (y-(topViewSize-25))+((y-topViewSize)*0.6)
    }

    if(y >= topViewSize){
        let final = ((450)-y) / ((450) - topViewSize)
        topView.albumButton.alpha = CGFloat(final)
    }else if (newHeaderViewHeight > topViewSize){
        let alphavalue = (newHeaderViewHeight/topViewSize) - 1
        topView.albumButton.alpha = CGFloat(alphavalue)
    }
}


Compile and run the code.

This is the result we get after adjusting the table header height and other UI parameters.

Final product

Final product

Looking for an iOS development company who can handle this for you?

Choose Artoon Solutions Pvt. Ltd., as we are always happy to help you. Being one of the finest iOS app development service providers, Artoon Solutions Pvt. Ltd. has offered quality mobile app development services across the globe. Our extensively knowledgeable and experienced developers have delivered masterpieces to client worldwide that has helped their businesses stay ahead of the curve.

Topics:
swift ,swift for ios ,ios phone extended warranty ,headers ,swift methods ,swift programming tutorial with examples ,swift programming language ,web dev

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}