NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>


Your challenge this time is not to build a project from scratch. Instead, I want you to implement three Swift language extensions using what you learned in project 24. I’ve ordered them easy to hard, so you should work your way from first to last if you want to make your life easy!

Here are the extensions I’d like you to implement:

  1. Extend UIView so that it has a bounceOut(duration:) method that uses animation to scale its size down to 0.0001 over a specified number of seconds.
  2. Extend Int with a times() method that runs a closure as many times as the number is high. For example, 5.times { print("Hello!") } will print “Hello” five times.
  3. Extend Array so that it has a mutating remove(item:) method. If the item exists more than once, it should remove only the first instance it finds. Tip: you will need to add the Comparable constraint to make this work!

As per usual, please try and complete this challenge yourself before you read my hints below. And again, don’t worry if you find this challenge challenging – the clue is in the name, these are designed to make you think!

Here are some hints in case you hit problems:

  1. Animation timings are specified using a TimeInterval, which is really just a Double behind the scenes. You should specify your method as bounceOut(duration: TimeInterval).
  2. If you’ve forgotten how to scale a view, look up CGAffineTransform in project 15.
  3. To add times() you’ll need to make a method that accepts a closure, and that closure should accept no parameters and return nothing: () -> Void.
  4. Inside times() you should make a loop that references self as the upper end of a range – that’s the value of the integer you’re working with.
  5. Integers can be negative. What happens if someone writes let count = -5 then uses count.times { … } and how can you make that better?
  6. When it comes to implementing the remove(item:) method, make sure you constrain your extension like this: extension Array where Element: Comparable.
  7. You can implement remove(item:) using a call to firstIndex(of:) then remove(at:).

Those hints ought to be enough for you to solve the complete challenge, but if you still hit problems then read over my solutions below, or put this all into a playground to see it in action.

import UIKit

// extension 1: animate out a UIView
extension UIView {
    func bounceOut(duration: TimeInterval) {
        UIView.animate(withDuration: duration) { [unowned self] in
            self.transform = CGAffineTransform(scaleX: 0.0001, y: 0.0001)

// extension 2: create a times() method for integers
extension Int {
    func times(_ closure: () -> Void) {
        guard self > 0 else { return }

        for _ in 0 ..< self {

// extension 3: remove an item from an array
extension Array where Element: Comparable {
    mutating func remove(item: Element) {
        if let location = self.firstIndex(of: item) {
            self.remove(at: location)

// some test code to make sure everything works
let view = UIView()
view.bounceOut(duration: 3)

5.times { print("Hello") }

var numbers = [1, 2, 3, 4, 5]
numbers.remove(item: 3)
Hacking with Swift is sponsored by Stream

SPONSORED Build Chat messaging quickly with Stream Chat. The Stream iOS Chat SDK is highly flexible, customizable, and crazy optimized for performance. Take advantage of this top-notch developer experience, get started for free today!

Click here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.