avatarCharles E.

Summary

The article details the process of recreating a Dribbble app design with UIKit, focusing on the creation of 'pill' buttons and the completion of the app header.

Abstract

The article is the second part of a series that guides readers through the author's approach to programmatically recreating a Dribbble app design using UIKit. It picks up from the previous installment, discussing the creation of custom 'pill' shaped UIViews with UILabels for text. The author explains the use of a horizontal UIStackView to arrange these views, setting their spacing and distribution properties to achieve the desired layout. The article also addresses the fine-tuning of UI elements, such as changing the color of specific text parts using NSAttributedString to style an exclamation mark in the greeting text. The process concludes with the completion of the app header, and the author directs readers to the next part of the series and the accompanying GitHub repository for reference.

Opinions

  • The author believes that the 'pill' design adds an interesting and attractive element to the UI.
  • They suggest that using a UIStackView simplifies the layout process for arranging multiple UIViews.
  • The use of system spacing and multipliers for constraints is presented as a straightforward method for achieving consistent spacing.
  • The author emphasizes the importance of attention to detail, such as the color of an exclamation

Recreate a Dribbble App Design with UIKit Episode 1 — Part 2

This article will guide you through my thought process and approach to programmatically recreating a cool UI design.

Recreating Dribbble Designs

Welcome back to the article series(missed part one? click here ) on how I recreated this Dribbble design using UIKit. Picking up right where we left off…it seems that I may have promised you guys some ‘pills’…didn’t I?

What I’m aiming for.

The approach to this was a bit of an interesting one,

  1. I created a custom UIView, styled in the shape of the ‘pills’ — some background color with rounded corners and some text on the inside.
  2. Added them to a horizontal UIStackview (distributed equally).
  3. Placed the UIStackview within the parent view.

Here’s how the custom UIView was made, I’ve called it a CategoryView

//CategoryView inherts from UIView
class CategoryView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
    
        configViews()
        configConstraints()
    }
            
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

//This view contains a UILabel,
// which will be used to set the text for the 'pills'
    var categoryLbl: UILabel = {
        let label = UILabel()
        label.font = .preferredFont(forTextStyle: .caption1)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()


    func configViews(){
//The view's corners are rounded to give it the 'pill' shape
        layer.cornerRadius = 16
//The label is added to the parent view
        addSubview(categoryLbl)
    }
    
    func configConstraints(){
//The label is then then centered horizontally within the view
//with 24 pts of space from the view's leading and trailing anchors
        NSLayoutConstraint.activate([
            categoryLbl.leadingAnchor.constraint(equalToSystemSpacingAfter: leadingAnchor, multiplier: 3),
            categoryLbl.centerYAnchor.constraint(equalTo: centerYAnchor),
            trailingAnchor.constraint(equalToSystemSpacingAfter: categoryLbl.trailingAnchor, multiplier: 3)
        ])
    }

}

Next I created 3 instances of this CategoryView, and a horizontal UIStackView to place them into

//The first instance of the CategoryView, 
//The text value of the UILabel within it is set to "New", 
//While the text color of the UILabel is set to "black"
//And fnally the view's background color is set to "white"  
var newCategory: CategoryView = {
       let category = CategoryView()
        category.categoryLbl.text = "New"
        category.categoryLbl.textColor = .black
        category.backgroundColor = .white
        category.translatesAutoresizingMaskIntoConstraints = false
        return category
}()

// This CategoryView is set to "Featured"
// And is basically a reverse of the previous
var featuredCategory: CategoryView = {
       let category = CategoryView()
        category.categoryLbl.text = "Featured"
        category.categoryLbl.textColor = .white
        category.backgroundColor = .black
        category.translatesAutoresizingMaskIntoConstraints = false
        return category
}()

// The final Category view is pretty much a copy of the first
// Scroll up and take another look at the 'pills' image for a quick refresher
var trendyCategory: CategoryView = {
       let category = CategoryView()
        category.categoryLbl.text = "Trendy"
        category.categoryLbl.textColor = .black
        category.backgroundColor = .white
        category.translatesAutoresizingMaskIntoConstraints = false
        return category
}()

// The stackview has it's spacing and distribution properties set
let categoryStackView: UIStackView = {
        let stackView = UIStackView()
        stackView.spacing = 8
        stackView.axis = .horizontal
        stackView.alignment = .center
        stackView.distribution = .equalSpacing
        stackView.translatesAutoresizingMaskIntoConstraints = false
        return stackView
    }()

That wasnt so bad huh? It’s not done as yet tho, we still need to add all these new (for lack of a better word) ‘components’ to the parent view, and then handle how they are constrained.

func configViews(){

// First, the stackview is added
  view.addSubview(categoryStackView)

// Then each of the categoryView items
// are added to the stackview, in order
  categoryStackView.addArrangedSubview(newCategory)
  categoryStackView.addArrangedSubview(featuredCategory)
  categoryStackView.addArrangedSubview(trendyCategory)
}

// This constraint stuff should be pretty straight forward by now, right?
// ...right??
func configConstraints() {
  NSLayoutConstraint.activate([ 
  categoryStackView.topAnchor.constraint(
  equalToSystemSpacingBelow: searchView.bottomAnchor, multiplier: 3),
  
  categoryStackView.leadingAnchor.constraint(
  equalToSystemSpacingAfter: view.leadingAnchor, multiplier: 4),
  categoryStackView.heightAnchor.constraint(equalToConstant: 32),
  view.trailingAnchor.constraint(equalToSystemSpacingAfter: categoryStackView.trailingAnchor, multiplier: 4),
                    
// The CategoryViews are given a height of 32,
// in order for those rounded corners which were set to 16
// to give it a circular shape
  newCategory.heightAnchor.constraint(equalToConstant: 32),
  featuredCategory.heightAnchor.constraint(equalToConstant: 32),
  trendyCategory.heightAnchor.constraint(equalToConstant: 32), 
])
}

And voila, pills.

the header

The header is pretty much finished, except for one minor detail ; the exclamation mark in the greeting isn’t the correct color. To resolve this, we’ll use the UILabel’s attributedText property to apply styling to a specific portion of the string.

// This function requires two strings
// the first being the greeting
// the second being the exclamation mark
// it will then set the color of the exclamation mark to orange
func configAttributedTitle(_ greeting: String,_ coloredGreeting: String) -> NSAttributedString {
  let attributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: greeting, attributes: [.font: UIFont.preferredFont(forTextStyle: .callout),.foregroundColor: UIColor.label]))
  attributedText.append(NSAttributedString(string: coloredGreeting, attributes: [.font:UIFont.preferredFont(forTextStyle: .callout), .foregroundColor: UIColor(named: "orangeColor")!]))
  return attributedText
}

// Set the attributedText on the label by calling the function in configViews 
func configViews(){
  greetingLabel.attributedText = configAttributedTitle("Hi, Charles", "!")
}
Completed header

Now the header is complete! Thanks for reading, you can find part 3 below.

As always, check out the github repo, in case you missed a step!

Swift
iOS Development
UI Design
iOS App Development
Dribbble
Recommended from ReadMedium