Skip to content

Commit

Permalink
Segment layout sizes update flow improvement (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
KazaiMazai authored Jun 15, 2024
1 parent 309f7d3 commit 97507a6
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions Sources/SegmentedPicker/SegmentedPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@

import SwiftUI


public struct SegmentedPicker<Element, Content, Selection>: View
where
Content: View,
Selection: View {

public typealias Data = [Element]

@State private var frames: [Data.Index: CGRect] = [:]
@State private var segmentSizes: [Data.Index: CGSize] = [:]
@Binding private var selectedIndex: Data.Index?

private let data: Data
Expand Down Expand Up @@ -42,8 +43,8 @@ public struct SegmentedPicker<Element, Content, Selection>: View

if let index = selectedIndex {
selection()
.frame(width: selectionFrame(at: index).width,
height: selectionFrame(at: index).height)
.frame(width: selectionSize(at: index).width,
height: selectionSize(at: index).height)
.alignmentGuide(.horizontalCenterAlignment) { dimensions in
dimensions[HorizontalAlignment.center]
}
Expand All @@ -56,10 +57,14 @@ public struct SegmentedPicker<Element, Content, Selection>: View
)
.buttonStyle(PlainButtonStyle())
.background(GeometryReader { proxy in
Color.clear.onAppear {
frames[index] = proxy.frame(in: .global)
}
Color.clear.preference(
key: SegmentSizePreferenceKey.self,
value: SegmentSize(index: index, size: proxy.size)
)
})
.onPreferenceChange(SegmentSizePreferenceKey.self) { segment in
segmentSizes[segment.index] = segment.size
}
.alignmentGuide(.horizontalCenterAlignment,
isActive: selectedIndex == index) { dimensions in
dimensions[HorizontalAlignment.center]
Expand All @@ -69,7 +74,24 @@ public struct SegmentedPicker<Element, Content, Selection>: View
}
}

private func selectionFrame(at index: Data.Index) -> CGRect {
frames[index] ?? .zero
private func selectionSize(at index: Data.Index) -> CGSize {
segmentSizes[index] ?? .zero
}
}

private extension SegmentedPicker {
struct SegmentSize: Equatable {
let index: Int
let size: CGSize
}

struct SegmentSizePreferenceKey: PreferenceKey {
static var defaultValue: SegmentSize { SegmentSize(index: .zero, size: .zero) }

static func reduce(value: inout SegmentSize,
nextValue: () -> SegmentSize) {

value = nextValue()
}
}
}

0 comments on commit 97507a6

Please sign in to comment.