Skip to content

Conversation

@Kyle-Ye
Copy link
Collaborator

@Kyle-Ye Kyle-Ye commented Oct 19, 2025

Summary

Implements the View.tag(_:includeOptional:) API to enable tagging views for selection in containers like Picker and TabView.

Closes #583

Changes

Adds Sources/OpenSwiftUICore/View/Tag.swift with complete implementation:

Public API

  • View.tag(_:includeOptional:): Sets unique tag values on views for identification in selectable containers
  • View._untagged(): Marks views as auxiliary content that should not be wrapped by containers

Internal Components

  • TagValueTraitKey<V>: Trait key for storing tag values with support for both tagged and untagged states
  • IsAuxiliaryContentTraitKey: Trait key for marking auxiliary/untagged content
  • ViewTraitCollection extensions: Methods for reading and writing tag values
    • tagValue(for:) - Get tag value regardless of auxiliary status
    • tag(for:) - Get tag value (returns nil for auxiliary content)
    • setTagIfUnset(for:value:) - Set tag only if not already set
    • setTag(for:value:) - Unconditionally set tag value
  • Binding extensions: Tag-based binding projections
    • selecting(_:) - Create boolean binding for tag selection
    • projectingTagIndex(viewList:) - Project binding to tag index in view list
  • TagIndexProjection: Internal projection class for efficient tag-to-index mapping

API Overview

extension View {
    func tag<V>(_ tag: V, includeOptional: Bool = true) -> some View where V: Hashable
    func _untagged() -> some View
}

Example Usage

struct FlavorPicker: View {
    enum Flavor: String, CaseIterable, Identifiable {
        case chocolate, vanilla, strawberry
        var id: Self { self }
    }
    
    @State private var selectedFlavor: Flavor = .chocolate
    
    var body: some View {
        Picker("Flavor", selection: $selectedFlavor) {
            ForEach(Flavor.allCases) { flavor in
                Text(flavor.rawValue)
                    .tag(flavor)
            }
        }
    }
}

Implementation Details

  • Uses trait-based storage for tag values
  • Supports both optional and non-optional tag types via includeOptional parameter
  • Efficient tag-to-index mapping for large view lists

@github-actions github-actions bot added enhancement New feature or request P1 Medium priority labels Oct 19, 2025
@codecov
Copy link

codecov bot commented Oct 19, 2025

Codecov Report

❌ Patch coverage is 0% with 90 lines in your changes missing coverage. Please review.
✅ Project coverage is 32.02%. Comparing base (b5860b3) to head (3448b25).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
Sources/OpenSwiftUICore/View/Tag.swift 0.00% 90 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #584      +/-   ##
==========================================
- Coverage   32.11%   32.02%   -0.10%     
==========================================
  Files         526      527       +1     
  Lines       30650    30740      +90     
==========================================
  Hits         9844     9844              
- Misses      20806    20896      +90     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Kyle-Ye Kyle-Ye merged commit e9b3227 into main Oct 19, 2025
9 checks passed
@Kyle-Ye Kyle-Ye deleted the feature/tag branch October 19, 2025 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request P1 Medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement View.tag API

2 participants