{"id":25930300,"url":"https://github.com/hanlunwang/dotpageindicator","last_synced_at":"2026-03-06T02:31:59.576Z","repository":{"id":279687729,"uuid":"939594963","full_name":"HanlunWang/DotPageIndicator","owner":"HanlunWang","description":"A modern, fully customizable dot-based page indicator for SwiftUI that goes beyond UIPageControl's limitations. Perfect for apps with scrollable content, carousels, or onboarding flows - especially when dealing with many pages. DotPageIndicator provides smooth scrolling animations and maintains great usability even with large numbers of pages.","archived":false,"fork":false,"pushed_at":"2025-02-26T20:59:27.000Z","size":4453,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-26T21:32:00.689Z","etag":null,"topics":["page-indicator","pagination","swift","swiftpackage","swiftui","ui-components"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HanlunWang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-26T19:44:52.000Z","updated_at":"2025-02-26T20:59:31.000Z","dependencies_parsed_at":"2025-02-26T21:32:03.219Z","dependency_job_id":"9eb6921d-9af7-4d48-82ae-6c9d1b3547e1","html_url":"https://github.com/HanlunWang/DotPageIndicator","commit_stats":null,"previous_names":["hanlunwang/dotpageindicator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HanlunWang%2FDotPageIndicator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HanlunWang%2FDotPageIndicator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HanlunWang%2FDotPageIndicator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HanlunWang%2FDotPageIndicator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HanlunWang","download_url":"https://codeload.github.com/HanlunWang/DotPageIndicator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241753170,"owners_count":20014251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["page-indicator","pagination","swift","swiftpackage","swiftui","ui-components"],"created_at":"2025-03-03T23:01:15.918Z","updated_at":"2026-03-06T02:31:59.542Z","avatar_url":"https://github.com/HanlunWang.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DotPageIndicator\n\nA modern, fully customizable dot-based page indicator for SwiftUI that goes beyond UIPageControl's limitations. Perfect for apps with scrollable content, carousels, or onboarding flows - especially when dealing with many pages. Unlike UIPageControl, DotPageIndicator provides smooth scrolling animations and maintains great usability even with large numbers of pages.\n\n![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)\n![Swift](https://img.shields.io/badge/swift-5.5%2B-orange.svg)\n![Platforms](https://img.shields.io/badge/platforms-iOS%2015.0+%20|%20macOS%2012.0+%20|%20tvOS%2014.0+%20|%20watchOS%207.0+-brightgreen.svg)\n\n## Preview\n\n![DotPageIndicator Preview](preview.gif)\n\n## Key Advantages\n\n- **Superior to UIPageControl**: Handles large page numbers gracefully with a scrolling interface\n- **Smooth Animations**: Beautiful scroll animations that UIPageControl lacks\n- **Highly Customizable**: Every aspect can be styled to match your app's design\n- **SwiftUI Native**: Built from ground up for SwiftUI with modern API design\n- **Easy to Implement**: Just a few lines of code to get started\n\n## Features\n\n- Support for both vertical and horizontal orientations\n- Customizable scroll directions (natural and reversed)\n- Customizable dot appearance (size, spacing, colors)\n- Smooth animations with spring effects\n- Adaptive scaling and opacity for better visual feedback\n- Optional content state indication for each dot\n- Multiple built-in styles (default, minimal, dark)\n- Background customization with material effects\n- iOS 15+, macOS 12+, tvOS 14+, watchOS 7+ support\n\n## Installation\n\n### Swift Package Manager\n\nYou can add DotPageIndicator to your project using Swift Package Manager by adding it as a dependency in your `Package.swift` file:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/HanlunWang/DotPageIndicator.git\", from: \"1.0.0\")\n]\n```\n\nOr in Xcode:\n\n1. Go to File \u003e Add Packages\n2. Enter package URL: `https://github.com/HanlunWang/DotPageIndicator.git`\n3. Click \"Add Package\"\n\n## System Requirements\n\n- iOS 15.0+\n- macOS 12.0+\n- tvOS 14.0+\n- watchOS 7.0+\n- Swift 5.5+\n\n## Usage\n\n### Basic Usage\n\n```swift\n@State private var currentPage = 0\nlet totalPages = 5\n\n// Vertical indicator (default - top to bottom)\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages\n)\n.frame(width: 50)\n\n// Vertical indicator (bottom to top)\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .init(\n        orientation: .vertical,\n        scrollDirection: .reversed\n    )\n)\n.frame(width: 50)\n\n// Horizontal indicator (left to right)\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .init(\n        orientation: .horizontal,\n        scrollDirection: .natural\n    )\n)\n.frame(height: 50)\n\n// Horizontal indicator (right to left)\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .init(\n        orientation: .horizontal,\n        scrollDirection: .reversed\n    )\n)\n.frame(height: 50)\n```\n\n### Custom Styling\n\n```swift\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: DotPageIndicatorStyle(\n        orientation: .horizontal,          // Choose orientation\n        scrollDirection: .natural,         // Choose scroll direction\n        dotSpacing: 12,                   // Space between dots\n        dotSize: 8,                       // Size of each dot\n        visibleDots: 5,                   // Number of visible dots\n        selectedDotColor: .blue,          // Color of the selected dot\n        activeDotColor: .gray,            // Color of active dots\n        inactiveDotColor: .gray.opacity(0.3), // Color of inactive dots\n        selectedDotScale: 1.4,            // Scale factor for selected dot\n        normalDotScale: 0.8               // Scale factor for other dots\n    )\n)\n```\n\n### Built-in Styles\n\n```swift\n// Default style\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .default\n)\n\n// Minimal style (transparent background)\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .minimal\n)\n\n// Dark style (white dots on dark background)\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .dark\n)\n```\n\n### Content State Indication\n\n```swift\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    hasContent: { index in\n        // Return true if the item at this index has content\n        return true\n    }\n)\n```\n\n## Customization\n\n### Using Built-in Styles\n\n```swift\n// Default style\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .default\n)\n\n// Minimal style\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .minimal\n)\n\n// Dark style\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: .dark\n)\n```\n\n### Custom Style Configuration\n\n```swift\nlet customStyle = DotPageIndicatorStyle(\n    dotSpacing: 12,              // Spacing between dots\n    dotSize: 6,                  // Size of each dot\n    visibleDots: 7,             // Number of visible dots\n    indicatorWidth: 20,         // Width of the indicator\n    verticalPadding: 8,         // Vertical padding\n    horizontalPadding: 4,       // Horizontal padding\n    backgroundCornerRadius: 20, // Corner radius of background\n    backgroundColor: AnyShapeStyle(.ultraThinMaterial),\n    selectedDotColor: .blue,    // Color for selected dot\n    activeDotColor: .blue.opacity(0.4), // Color for active dots\n    inactiveDotColor: .gray.opacity(0.2), // Color for inactive dots\n    selectedDotScale: 1.4,      // Scale for selected dot\n    normalDotScale: 0.8,        // Scale for normal dots\n    selectedDotOpacity: 1.0,    // Opacity for selected dot\n    normalDotOpacity: 0.2,      // Opacity for normal dots\n    animationResponse: 0.3,     // Animation response time\n    animationDampingFraction: 0.8 // Animation damping\n)\n\nDotPageIndicator(\n    currentIndex: $currentPage,\n    totalItems: totalPages,\n    style: customStyle\n)\n```\n\n## License\n\nDotPageIndicator is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhanlunwang%2Fdotpageindicator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhanlunwang%2Fdotpageindicator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhanlunwang%2Fdotpageindicator/lists"}