# SwipeMenuViewController: a swipeable tab bar with a paging content area for iOS

> SwipeMenuViewController is an MIT-licensed Swift package that puts a scrollable tab bar above a horizontally paging content area and keeps the two in sync. It works from UIKit through data source and delegate protocols, and from SwiftUI on iOS 18 with a selection binding.

**yysskk/SwipeMenuViewController** — Swipe-based paging UI for iOS

- Repository: https://github.com/yysskk/SwipeMenuViewController
- Website: https://yysskk.github.io/SwipeMenuViewController/documentation/swipemenuviewcontroller/
- Stars: 1,277 · Forks: 127
- Language: Swift
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/yysskk-swipemenuviewcontroller

## Two views that have to agree

SwipeMenuViewController is a swipe-based paging UI for iOS. The structure is a scrollable tab bar above a horizontally paging content area, and swiping the content keeps the tab selection in sync.

That last clause is the whole point of the component, and it is worth being clear about because it is what separates this from a plain tab bar controller. A conventional tab bar switches the visible page and the tab highlight moves with it. Here, the user can swipe the content area sideways, and the tab bar follows, scrolls to keep the selected tab visible, and updates its underline or indicator. Two independent gestures have to stay consistent, and that consistency is the value the library provides.

The result is a paging pattern used by settings screens and by apps that want content to feel continuous rather than tabbed. The README shows three visual configurations as demo gifs, a segmented tab with an underline, a flexible tab with an underline, and a flexible tab with a circle indicator, which tells you the tab appearance is configurable rather than fixed.

The package is MIT licensed, the primary language is Swift, and the homepage is the DocC documentation site at yysskk.github.io/SwipeMenuViewController. The last push was on 2026-07-23, and the release history has a striking shape: 2.0.8 and 2.1.0 both in May 2018, then 5.0.0 in July 2026.

## Toolchain requirements, and what 5.0 means

The requirements are stated in two lines and they are the first thing to check.

iOS 16.0 or later, with the SwiftUI `SwipeMenu` requiring iOS 18.0 or later, and Xcode 26.0 or later with Swift 6.2. The badges agree, showing Swift 6.2 and an SPM compatible marker.

For anyone on an older toolchain, the README points to the 4.x releases. That is the important operational detail: the 5.0 line moved the floor up, and the migration path is a different major version rather than a compatibility flag.

The version history explains why. After 2.1.0 in May 2018, the next tag in the list is 5.0.0 on 2026-07-06, which means several major versions were shipped over eight years and the visible tags are sparse. What that gap suggests is a library that changed shape considerably rather than a library that sat still, and the jump from 2.x to 5.x is consistent with that.

The repository layout is the standard Swift Package Manager shape. There is `Package.swift` at the root, `Sources/` and `Tests/` directories, an `Example/` directory with its own project, a `.swift-format` file for formatting, a `.spi.yml` for Swift Package Index metadata, and a CHANGELOG and CONTRIBUTING document. The CI badge points at a `test.yml` workflow on the main branch.

## Two ways in: subclassing and embedding a view

The UIKit path starts with subclassing `SwipeMenuViewController` and adding your pages as child view controllers. Each child becomes a page, its `title` is the tab title and its view is the page content.

```swift
import SwipeMenuViewController

final class MenuViewController: SwipeMenuViewController {

    override func viewDidLoad() {
        pages.forEach { addChild($0) }
        super.viewDidLoad()
    }

    private let pages: [UIViewController] = {
        let first = UIViewController()
        first.title = "First"
        let second = UIViewController()
        second.title = "Second"
        return [first, second]
    }()
}
```

The order of operations is the part to copy exactly. The child view controllers are added before `super.viewDidLoad()` is called, because the base class reads the children to build the tab list, so adding them afterwards would produce an empty tab bar.

There is a second UIKit approach for when you already have a view hierarchy. You add a `SwipeMenuView` directly and drive it through `SwipeMenuViewDataSource`. The Getting Started article walks through both, and the existence of the separate data source protocol is the clue: the view does not need to be a controller, it can be embedded anywhere in a screen you already have.

That distinction is the practical reason to use this library over writing your own. The tab bar, the paging view and the synchronisation between them are one component, and the data source and delegate protocols are the seam that lets it drop into an existing screen rather than requiring you to restructure around it.

## The SwiftUI wrapper and what it does not give you

On iOS 18 and later the same UI can be driven from SwiftUI with the `SwipeMenu` type.

```swift
import SwiftUI
import SwipeMenuViewController

struct ContentView: View {

    @State private var selection = 0

    private let titles = ["First", "Second"]

    var body: some View {
        SwipeMenu(selection: $selection, titles: titles) { index in
            Text(titles[index])
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}
```

The selected page is a binding, and setting it is the equivalent of calling `jump(to:animated:)`. The pages come from a view builder that takes the index, so the builder renders whichever page the current index points at, and the appearance is configured with `SwipeMenuOptions`.

It is worth being precise about what this wrapper is not. It is not a full SwiftUI port of the component with a different set of capabilities, it is a bridge onto the same UIKit view. The documentation article for it covers the options, the paging callbacks, and the differences from the UIKit view, and that last part is the useful reading, because the differences are where the friction lives when you move between the two worlds.

The dependency on iOS 18 is the practical constraint. If your deployment target is iOS 16, you use the UIKit path and you do not get the SwiftUI binding.

## Documentation, appearance and the example project

The full API reference is published with DocC, and the README lists three articles worth knowing about. Getting Started covers setting up `SwipeMenuView` or `SwipeMenuViewController`. Customizing Appearance covers every `SwipeMenuViewOptions` field. SwipeMenu in SwiftUI covers the options, the paging callbacks and the differences from the UIKit view.

The fact that appearance is a struct of options rather than a set of overridable methods is a design statement, and a useful one for anyone maintaining a codebase with a house style. You describe the look in a value and hand it over, rather than subclassing and overriding, and the article that enumerates every field is the real reference for that.

The documentation can be built locally in Xcode with Product, Build Documentation, and the repository ships an Example app to explore. The example's Xcode project is generated with XcodeGen rather than committed as a project file, which is visible in the tree as `Example/project.yml` and `Example/README.md`.

That last detail is a small piece of engineering hygiene that pays off. A generated project file means the project definition lives in a reviewable text file, and the diff on a pull request shows what changed in the project configuration rather than showing noise from a regenerated pbxproj.

The Contributing guide covers how to build, test, format and document changes, and the test suite is run with xcodebuild against an iOS simulator.

## Conclusion

SwipeMenuViewController fits an iOS team that wants a tab bar that stays in step with a paged content area, and that is on Xcode 26 with Swift 6.2 and an iOS 16 deployment target, or iOS 18 if the SwiftUI wrapper is wanted. It does not fit a project pinned to an older toolchain, since the current major requires Xcode 26 and the 4.x releases are the fallback there. Before adopting it, add the package with `.upToNextMajor(from: "5.0.0")`, and read the Customizing Appearance article, because every visual detail lives in the `SwipeMenuViewOptions` fields rather than in subclass overrides.

## FAQ

### What does SwipeMenuViewController do?

It provides a swipe-based paging UI for iOS: a scrollable tab bar above a horizontally paging content area, where swiping the content keeps the tab selection in sync. The MIT-licensed Swift package works from UIKit through data source and delegate protocols, and from SwiftUI on iOS 18 and later.

### How do I add SwipeMenuViewController to a project?

It is distributed with Swift Package Manager, so you add it in Xcode through File, Add Package Dependencies, or add `.package(url: "https://github.com/yysskk/SwipeMenuViewController.git", .upToNextMajor(from: "5.0.0"))` to your Package.swift manifest.

### What are the requirements for SwipeMenuViewController 5.0?

iOS 16.0 or later, with the SwiftUI SwipeMenu requiring iOS 18.0 or later, and Xcode 26.0 or later with Swift 6.2. If you need an older toolchain or deployment target, the README points to the 4.x releases.

### How is the SwiftUI version of SwipeMenu used?

With a selection binding, where setting it is the equivalent of jump(to:animated:). Pages come from a view builder that takes the index, and the appearance is configured with SwipeMenuOptions. The documentation covers the options, the paging callbacks and the differences from the UIKit view.

### How do I run the SwipeMenuViewController test suite?

With `xcodebuild test -scheme SwipeMenuViewController -destination 'platform=iOS Simulator,name=iPhone 16'`. The contributing guide covers how to build, test, format and document changes, and the example project's Xcode project is generated with XcodeGen.

## Sources

- [License: MIT](https://github.com/yysskk/SwipeMenuViewController/blob/main/LICENSE)
- [Project website](https://yysskk.github.io/SwipeMenuViewController/documentation/swipemenuviewcontroller/)
- [README](https://github.com/yysskk/SwipeMenuViewController/blob/main/README.md)
- [Releases](https://github.com/yysskk/SwipeMenuViewController/releases)
- [yysskk/SwipeMenuViewController on GitHub](https://github.com/yysskk/SwipeMenuViewController)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/yysskk-swipemenuviewcontroller
