UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: How to make a button that "cycles through" multiple options?

Forums > SwiftUI

I would like to create a button that, each time the user taps it, it cycles to the next option in an array of options. Something like this:

                    switch book.bookStatus {
                        case .inProgress:
                            Button(action: book.bookStatus = .completed,
                                   label: {
                                    Image(systemName: "book")
                                        .foregroundColor(.blue)
                                   })
                        case .completed:
                            Button(action: book.bookStatus = .favorite,
                                   label: {
                                    Image(systemName: "checkmark")
                                        .foregroundColor(.green)
                                   })
                        case .favorite:
                            Button(action: book.bookStatus = .unread,
                                   label: {
                                    Image(systemName: "heart.fill")
                                        .foregroundColor(.red)
                                   })
                        default:
                            Button(action: book.bookStatus = .completed,
                                   label: {
                                    Image(systemName: "book.closed.fill")
                                        .foregroundColor(.gray)
                                   })
                    }

For a while, I had separate properties for book that were boolean values: favorite, completed, etc. I was able to alter those properties using a button or toggle, but I'd really like to wrap it up all in a single icon, so that if the user taps it once, it will mark the book read. If they tap it again, it will mark the book as a favorite, and so forth. But I don't know any way to select one of multiple (more than two) values other than using a picker.

3      

You can do something like this:

import SwiftUI

enum BookStatus {
    case inProgress
    case completed
    case favorite
    case unread

    var nextStatus: BookStatus {
        switch self {
        case .inProgress: return .completed
        case .completed: return .favorite
        case .favorite: return .unread
        case .unread: return .inProgress
        }
    }

    var icon: String {
        switch self {
        case .inProgress: return "book"
        case .completed: return "checkmark"
        case .favorite: return "heart.fill"
        case .unread: return "book.closed.fill"
        }
    }

    var color: Color {
        switch self {
        case .inProgress: return .blue
        case .completed: return .green
        case .favorite: return .red
        case .unread: return .gray
        }
    }
}

struct SwitcherButton: View {
    @State private var bookStatus: BookStatus = .unread

    var body: some View {
        Button { bookStatus = bookStatus.nextStatus }
            label: {
                Image(systemName: bookStatus.icon)
                    .foregroundColor(bookStatus.color)
            }
    }
}

Since I don't have the rest of your code, I had to simplify things a bit. And I made an assumption that if the current status of the book is .unread then the next status would be .inProgress. Obviously, though, this is just an example that you can hopefully use as inspiration.

5      

Thank you. That's definately what I was going for, I just hadn't thought of making the nextStatus a property of the enum. Thank you.

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.