Skip to content

Commit

Permalink
Merge pull request #56 from skiptools/navbarappearance
Browse files Browse the repository at this point in the history
Make nav bar appear transparent when unscrolled
  • Loading branch information
aabewhite authored Sep 17, 2024
2 parents 738bfac + fd5f175 commit da90316
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 12 deletions.
9 changes: 6 additions & 3 deletions Sources/SkipUI/SkipUI/Commands/Toolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,16 @@ struct ToolbarPreferences: Equatable {
let titleDisplayMode: ToolbarTitleDisplayMode?
let titleMenu: View?
let backButtonHidden: Bool?
let isSystemBackground: Bool?
let navigationBar: ToolbarBarPreferences?
let bottomBar: ToolbarBarPreferences?

init(content: [View]? = nil, titleDisplayMode: ToolbarTitleDisplayMode? = nil, titleMenu: View? = nil, backButtonHidden: Bool? = nil, navigationBar: ToolbarBarPreferences? = nil, bottomBar: ToolbarBarPreferences? = nil) {
init(content: [View]? = nil, titleDisplayMode: ToolbarTitleDisplayMode? = nil, titleMenu: View? = nil, backButtonHidden: Bool? = nil, isSystemBackground: Bool? = nil, navigationBar: ToolbarBarPreferences? = nil, bottomBar: ToolbarBarPreferences? = nil) {
self.content = content
self.titleDisplayMode = titleDisplayMode
self.titleMenu = titleMenu
self.backButtonHidden = backButtonHidden
self.isSystemBackground = isSystemBackground
self.navigationBar = navigationBar
self.bottomBar = bottomBar
}
Expand All @@ -330,6 +332,7 @@ struct ToolbarPreferences: Equatable {
self.titleDisplayMode = nil
self.titleMenu = nil
self.backButtonHidden = nil
self.isSystemBackground = nil
}

func reduce(_ next: ToolbarPreferences) -> ToolbarPreferences {
Expand All @@ -339,7 +342,7 @@ struct ToolbarPreferences: Equatable {
} else {
rcontent = next.content ?? content
}
return ToolbarPreferences(content: rcontent, titleDisplayMode: next.titleDisplayMode ?? titleDisplayMode, titleMenu: next.titleMenu ?? titleMenu, backButtonHidden: next.backButtonHidden ?? backButtonHidden, navigationBar: reduceBar(navigationBar, next.navigationBar), bottomBar: reduceBar(bottomBar, next.bottomBar))
return ToolbarPreferences(content: rcontent, titleDisplayMode: next.titleDisplayMode ?? titleDisplayMode, titleMenu: next.titleMenu ?? titleMenu, backButtonHidden: next.backButtonHidden ?? backButtonHidden, isSystemBackground: next.isSystemBackground ?? isSystemBackground, navigationBar: reduceBar(navigationBar, next.navigationBar), bottomBar: reduceBar(bottomBar, next.bottomBar))
}

private func reduceBar(_ bar: ToolbarBarPreferences?, _ next: ToolbarBarPreferences?) -> ToolbarBarPreferences? {
Expand All @@ -351,7 +354,7 @@ struct ToolbarPreferences: Equatable {
}

public static func ==(lhs: ToolbarPreferences, rhs: ToolbarPreferences) -> Bool {
guard lhs.titleDisplayMode == rhs.titleDisplayMode, lhs.backButtonHidden == rhs.backButtonHidden, lhs.navigationBar == rhs.navigationBar, lhs.bottomBar == rhs.bottomBar else {
guard lhs.titleDisplayMode == rhs.titleDisplayMode, lhs.backButtonHidden == rhs.backButtonHidden, lhs.isSystemBackground == rhs.isSystemBackground, lhs.navigationBar == rhs.navigationBar, lhs.bottomBar == rhs.bottomBar else {
return false
}
guard (lhs.content?.count ?? 0) == (rhs.content?.count ?? 0), (lhs.titleMenu != nil) == (rhs.titleMenu != nil) else {
Expand Down
3 changes: 2 additions & 1 deletion Sources/SkipUI/SkipUI/Containers/List.swift
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ public final class List : View {
})
modifier = modifier.reorderable(reorderableState)

PreferenceValues.shared.contribute(context: context, key: ToolbarPreferenceKey.self, value: ToolbarPreferences(isSystemBackground: styling.style != ListStyle.plain && styling.backgroundVisibility != Visibility.hidden))
// Integrate with our scroll-to-top and ScrollViewReader
let coroutineScope = rememberCoroutineScope()
PreferenceValues.shared.contribute(context: context, key: ScrollToTopPreferenceKey.self, value: {
Expand Down Expand Up @@ -480,7 +481,7 @@ public final class List : View {
// Vertical padding
ComposeFooter(styling: styling, safeAreaHeight: 0.dp, hasBottomSection: true)
}
let backgroundColor = BackgroundColor(styling: styling.withStyle(ListStyle.automatic), isItem: false)
let backgroundColor = BackgroundColor(styling: styling, isItem: false)
let modifier = Modifier
.zIndex(Float(0.5))
.background(backgroundColor)
Expand Down
24 changes: 20 additions & 4 deletions Sources/SkipUI/SkipUI/Containers/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
Expand All @@ -69,6 +70,7 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
Expand Down Expand Up @@ -196,6 +198,7 @@ public struct NavigationStack<Root> : View where Root: View {
let effectiveTitleDisplayMode = navigator.value.titleDisplayMode(for: arguments.state, preference: arguments.toolbarPreferences.titleDisplayMode)
let isInlineTitleDisplayMode = useInlineTitleDisplayMode(for: effectiveTitleDisplayMode, safeArea: arguments.safeArea)
let toolbarItems = ToolbarItems(content: arguments.toolbarPreferences.content ?? [])
let isSystemBackground = arguments.toolbarPreferences.isSystemBackground == true

let searchFieldPadding = 16.dp
let density = LocalDensity.current
Expand Down Expand Up @@ -230,20 +233,25 @@ public struct NavigationStack<Root> : View where Root: View {
mutableStateOf(with(density) { safeAreaTopPx + 112.dp.toPx() })
}
let topBarBackgroundColor: androidx.compose.ui.graphics.Color
let unscrolledTopBarBackgroundColor: androidx.compose.ui.graphics.Color
let topBarBackgroundBrush: androidx.compose.ui.graphics.Brush?
if topBarPreferences?.backgroundVisibility == Visibility.hidden {
topBarBackgroundColor = Color.clear.colorImpl()
topBarBackgroundColor = androidx.compose.ui.graphics.Color.Transparent
unscrolledTopBarBackgroundColor = androidx.compose.ui.graphics.Color.Transparent
topBarBackgroundBrush = nil
} else if let background = topBarPreferences?.background {
if let color = background.asColor(opacity: 1.0, animationContext: nil) {
topBarBackgroundColor = color
unscrolledTopBarBackgroundColor = color
topBarBackgroundBrush = nil
} else {
topBarBackgroundColor = Color.clear.colorImpl()
topBarBackgroundColor = androidx.compose.ui.graphics.Color.Transparent
unscrolledTopBarBackgroundColor = androidx.compose.ui.graphics.Color.Transparent
topBarBackgroundBrush = background.asBrush(opacity: 1.0, animationContext: nil)
}
} else {
topBarBackgroundColor = Color.systemBarBackground.colorImpl()
unscrolledTopBarBackgroundColor = isSystemBackground ? topBarBackgroundColor : topBarBackgroundColor.copy(alpha: Float(0.0))
topBarBackgroundBrush = nil
}
let topBar: @Composable () -> Void = {
Expand Down Expand Up @@ -287,7 +295,7 @@ public struct NavigationStack<Root> : View where Root: View {
topBarModifier = topBarModifier.background(topBarBackgroundBrush)
}
let topBarColors = TopAppBarDefaults.topAppBarColors(
containerColor: topBarBackgroundColor,
containerColor: unscrolledTopBarBackgroundColor,
scrolledContainerColor: topBarBackgroundColor,
titleContentColor: MaterialTheme.colorScheme.onSurface
)
Expand Down Expand Up @@ -417,7 +425,15 @@ public struct NavigationStack<Root> : View where Root: View {
var topPadding = 0.dp
let searchableState: SearchableState? = arguments.isRoot ? (EnvironmentValues.shared._searchableState ?? searchableStatePreference.value.reduced) : nil
if let searchableState {
let searchFieldModifier = Modifier.height(searchFieldHeight.dp + searchFieldPadding).align(androidx.compose.ui.Alignment.TopCenter).offset({ IntOffset(0, Int(searchFieldOffsetPx.value)) }).background(topBarBackgroundColor).padding(start: searchFieldPadding, bottom: searchFieldPadding, end: searchFieldPadding).fillMaxWidth()
let searchFieldFadeOffset = searchFieldHeightPx / 3
let searchFieldModifier = Modifier.height(searchFieldHeight.dp + searchFieldPadding)
.align(androidx.compose.ui.Alignment.TopCenter)
.offset({ IntOffset(0, Int(searchFieldOffsetPx.value)) })
.background(unscrolledTopBarBackgroundColor)
.padding(start: searchFieldPadding, bottom: searchFieldPadding, end: searchFieldPadding)
// Offset is negative. Fade out quickly as it scrolls in case it is moving up under transparent nav bar
.graphicsLayer { alpha = max(Float(0.0), (searchFieldFadeOffset + searchFieldOffsetPx.value) / searchFieldFadeOffset) }
.fillMaxWidth()
SearchField(state: searchableState, context: context.content(modifier: searchFieldModifier))
let searchFieldPlaceholderPadding = searchFieldHeight.dp + searchFieldPadding + (with(LocalDensity.current) { searchFieldOffsetPx.value.toDp() })
topPadding = searchFieldPlaceholderPadding
Expand Down
2 changes: 1 addition & 1 deletion Sources/SkipUI/SkipUI/Containers/TabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public struct TabView : View {
}
}
let colorScheme = reducedTabBarPreferences.colorScheme ?? ColorScheme.fromMaterialTheme()
let indicatorColor = colorScheme == .dark ? androidx.compose.ui.graphics.Color.White.copy(alpha: Float(0.2)) : androidx.compose.ui.graphics.Color.Black.copy(alpha: Float(0.2))
let indicatorColor = colorScheme == .dark ? androidx.compose.ui.graphics.Color.White.copy(alpha: Float(0.1)) : androidx.compose.ui.graphics.Color.Black.copy(alpha: Float(0.1))
let tabBarBackgroundColor: androidx.compose.ui.graphics.Color
let tabBarItemColors: NavigationBarItemColors
if reducedTabBarPreferences.backgroundVisibility == Visibility.hidden {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SkipUI/SkipUI/Controls/Picker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ extension View {
}

#if SKIP
@Composable private func processPickerContent<SelectionValue>(content: ComposeBuilder, selection: Binding<SelectionValue>, context: ComposeContext, requireTagViews: Bool = false) -> (View, [TagModifierView]?) {
@Composable func processPickerContent<SelectionValue>(content: ComposeBuilder, selection: Binding<SelectionValue>, context: ComposeContext, requireTagViews: Bool = false) -> (View, [TagModifierView]?) {
let selectedTag = selection.wrappedValue
let viewCollectingComposer = PickerViewCollectingComposer(selectedTag: selectedTag, requireTagViews: requireTagViews)
let viewCollector = context.content(composer: viewCollectingComposer)
Expand Down
4 changes: 2 additions & 2 deletions Tests/SkipUITests/SkipUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ final class SkipUITests: SkipUITestCase {
rule.onNodeWithTag("label").assertIsDisplayed()
rule.onNodeWithTag("label").assert(hasTextExactly("0%"))
rule.onNodeWithTag("slider").performGesture {
down(Offset(Float(0.0), Float(0.0)))
moveTo(Offset(Float(1000.0), Float(0.0)))
down(Offset(Float(10.0), Float(20.0)))
moveTo(Offset(Float(1000.0), Float(20.0)))
up()
}
//rule.onNodeWithTag("label").assert(hasTextExactly("100%"))
Expand Down

0 comments on commit da90316

Please sign in to comment.