{"id":16807114,"url":"https://github.com/toshi0383/yokoso","last_synced_at":"2025-04-11T01:11:53.057Z","repository":{"id":62015423,"uuid":"550815247","full_name":"toshi0383/Yokoso","owner":"toshi0383","description":"Simple spotlight instruction framework for UIKit iOS","archived":false,"fork":false,"pushed_at":"2024-07-03T05:22:57.000Z","size":97,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-11T01:11:49.014Z","etag":null,"topics":["coach-marks","swiftui","tour","uikit","walkthrough"],"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/toshi0383.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}},"created_at":"2022-10-13T11:24:14.000Z","updated_at":"2025-04-09T10:22:51.000Z","dependencies_parsed_at":"2022-10-25T05:45:18.179Z","dependency_job_id":null,"html_url":"https://github.com/toshi0383/Yokoso","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toshi0383%2FYokoso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toshi0383%2FYokoso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toshi0383%2FYokoso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toshi0383%2FYokoso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toshi0383","download_url":"https://codeload.github.com/toshi0383/Yokoso/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248322571,"owners_count":21084337,"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":["coach-marks","swiftui","tour","uikit","walkthrough"],"created_at":"2024-10-13T09:52:58.233Z","updated_at":"2025-04-11T01:11:53.041Z","avatar_url":"https://github.com/toshi0383.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌸Yokoso🗻\n\nYet another super simple spotlight instruction framework for UIKit iOS.\n\n## Why Yokoso?\n\n- [x] Checks if interested view is inside window's bounds\n- [x] Supports device rotation / iPad SplitView\n- [x] Swift Concurrency\n- [ ] Swift 6 Concurrency Check Mode ( work in progress )\n\n## Unique Error Feature\n\nYou don't want to show spotlight on an invisible view, right?\nOne good thing about Yokoso, is that it checks if the interested view is fully visible to your user.\nOtherwise `InstructionError.interestedViewOutOfBounds` is thrown.\nWith Yokoso, your tutorial UI/UX is better than ever.\n\n## Screenshot\n\nhttps://user-images.githubusercontent.com/6007952/197309254-e7a0ed85-89c0-4d5a-a022-6e02c1fadb3b.mp4\n\n## How to use\n\nIt's super simple.\nImport the module,\n\n```swift\nimport Yokoso\n```\n\ninitialize `InstructionManager`,\n\n```swift\nlet manager = InstructionManager(overlayBackgroundColor: .overlayBackground)\n```\n\nthen use `InstructionManager`'s interface to show or close your `Instruction`.\n\n### Showing single Instruction\n\n```swift\ndo {\n\n    try instructionManager.show(\n        .init(\n            message: .init(\n                attributedString: attributedString,\n                backgroundColor: uicolor\n            ),\n            nextButton: .simple(\"Next\"),\n            sourceView: label\n        ),\n        in: view\n    )\n\n} catch {\n    if let error = error as? InstructionError {\n        assertionFailure(error.localizedDescription)\n    }\n}\n```\n\nPlease refer to the Example app for further customization.\n\n## SwiftUI\n\nYou can use Yokoso for SwiftUI view, at least if you're embedding with `UIHostingController`.\n\nFirst you need to retrieve interested view's frame via `ObservableObject` + `GeometryReader`.\n\n```swift\nclass ViewModel: ObservableObject {\n    @Published var interestedViewRect: CGRect?\n}\n\nstruct YourView: View {\n    @ObservedObject var viewModel: ViewModel\n    var body: some View {\n        GeometryReader { p in\n            yourLayout\n                .onAppear {\n                    viewModel.interestedViewRect = p.frame(in: .global)\n                }\n        }\n    }\n\n}\n```\n\nThen pass that frame to `sourceRect` parameter of `InstructionManager.show`.\n\n```swift\n    try await instructionManager?.show(\n        .init(\n            message: .init(attributedString: message, backgroundColor: .v4.monotone8),\n            nextButton: .custom(...),\n            sourceView: view,\n            sourceRect: sourceRect,\n            blocksTapOutsideCutoutPath: true,\n            ignoresTapInsideCutoutPath: true\n        ),\n        in: view\n    )\n```\n\n## Requirements\n\n- iOS 14+\n\n## Install\n\n- [x] Swift Package Manager\n\n## Contributing\n\nAny contributions are warmly welcomed.😊\n\n- Feature Request / Pull Request\n- Bug Report\n- Question!\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoshi0383%2Fyokoso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoshi0383%2Fyokoso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoshi0383%2Fyokoso/lists"}