Skip to content

Commit 561d2ea

Browse files
committed
feat(ios): searchAutoHide wip
1 parent fb7a23e commit 561d2ea

File tree

5 files changed

+96
-11
lines changed

5 files changed

+96
-11
lines changed

apps/toolbox/src/main-page.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
22
<Page.actionBar>
3-
<ActionBar title="Dev Toolbox" icon="" class="action-bar" iosLargeTitle="true" iosShadow="false">
3+
<ActionBar title="Dev Toolbox" icon="" class="action-bar">
44
</ActionBar>
55
</Page.actionBar>
66
<StackLayout>

apps/toolbox/src/pages/list-page.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<GridLayout backgroundColor="#efefef">
99
<ListView class="list-group" items="{{ countries }}" itemTap="{{ componentsItemTap }} " separatorColor="#00000000" itemTemplateSelector="{{ selectItemTemplate }}" stickyHeader="true" sectioned="true" stickyHeaderTopPadding="false" stickyHeaderTemplate="<GridLayout><Label text='{{ title }}' fontSize='18' fontWeight='bold' color='#009bff' padding='8 0 8 12' borderBottomWidth='1' borderBottomColor='#ccc' borderTopWidth='1' borderTopColor='#ccc' backgroundColor='#fff' /></GridLayout>" stickyHeaderHeight="45" itemLoading="{{ itemLoading }}"
1010
showSearch="true"
11+
searchAutoHide="true"
1112
searchChange="{{ onSearchTextChange }}">
1213
<ListView.itemTemplates>
1314
<template key="main">

packages/core/ui/list-view/index.d.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,22 @@ export class ListView extends View {
146146
sectioned: boolean;
147147

148148
/**
149-
* Gets or sets a value indicating whether the ListView should show a search bar.
149+
* Gets or sets whether search functionality is enabled.
150150
* When enabled on iOS, uses native UISearchController for optimal performance.
151151
*
152152
* @nsProperty
153153
*/
154154
showSearch: boolean;
155155

156156
/**
157+
* Gets or sets whether the search bar should auto-hide when scrolling (iOS only).
158+
* When true, the search bar will automatically hide when the user scrolls down
159+
* and reappear when scrolling up, using iOS native behavior.
160+
* Only applies when showSearch is true and running on iOS with navigation controller.
161+
*
162+
* @nsProperty
163+
*/
164+
searchAutoHide: boolean; /**
157165
* Forces the ListView to reload all its items.
158166
*/
159167
refresh();
@@ -339,3 +347,8 @@ export const sectionedProperty: Property<ListView, boolean>;
339347
* Represents the observable property backing the showSearch property of each ListView instance.
340348
*/
341349
export const showSearchProperty: Property<ListView, boolean>;
350+
351+
/**
352+
* Represents the observable property backing the searchAutoHide property of each ListView instance.
353+
*/
354+
export const searchAutoHideProperty: Property<ListView, boolean>;

packages/core/ui/list-view/index.ios.ts

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ItemEventData, SearchEventData, ItemsSource } from '.';
2-
import { ListViewBase, separatorColorProperty, itemTemplatesProperty, iosEstimatedRowHeightProperty, stickyHeaderProperty, stickyHeaderTemplateProperty, stickyHeaderHeightProperty, sectionedProperty, showSearchProperty } from './list-view-common';
2+
import { ListViewBase, separatorColorProperty, itemTemplatesProperty, iosEstimatedRowHeightProperty, stickyHeaderProperty, stickyHeaderTemplateProperty, stickyHeaderHeightProperty, sectionedProperty, showSearchProperty, searchAutoHideProperty } from './list-view-common';
33
import { CoreTypes } from '../../core-types';
44
import { View, KeyedTemplate, Template } from '../core/view';
55
import { Length } from '../styling/length-shared';
@@ -499,36 +499,62 @@ export class ListView extends ListViewBase {
499499
// 2. Tell it who will update results
500500
this._searchController.searchResultsUpdater = this._searchDelegate;
501501

502-
// 3. Don't dim or obscure your table by default
502+
// 3. Critical: Don't dim or obscure the table, and prevent extra content
503503
this._searchController.obscuresBackgroundDuringPresentation = false;
504+
this._searchController.dimsBackgroundDuringPresentation = false;
505+
this._searchController.hidesNavigationBarDuringPresentation = false;
504506

505-
// 4. Placeholder text
507+
// 4. Placeholder text and styling
506508
this._searchController.searchBar.placeholder = 'Search';
507509
this._searchController.searchBar.searchBarStyle = UISearchBarStyle.Minimal;
508510

509-
// 5. CRITICAL: Make sure the search bar doesn't remain on screen if the user navigates
511+
// 5. CRITICAL: Proper presentation context setup
510512
const viewController = this._getViewController();
511513
if (viewController) {
512514
viewController.definesPresentationContext = true;
515+
viewController.providesPresentationContextTransitionStyle = true;
513516

514-
// 6a. If we're in a UINavigationController...
517+
// 6a. If we're in a UINavigationController (iOS 11+)...
515518
if (SDK_VERSION >= 11.0 && viewController.navigationItem) {
516519
viewController.navigationItem.searchController = this._searchController;
517-
viewController.navigationItem.hidesSearchBarWhenScrolling = false;
520+
521+
// Set auto-hide behavior based on searchAutoHide property
522+
viewController.navigationItem.hidesSearchBarWhenScrolling = this.searchAutoHide;
523+
524+
// Optional: Enable large titles for better auto-hide effect when searchAutoHide is true
525+
// if (this.searchAutoHide && viewController.navigationController && viewController.navigationController.navigationBar) {
526+
// // Only set large titles if not already configured
527+
// if (!viewController.navigationController.navigationBar.prefersLargeTitles) {
528+
// viewController.navigationController.navigationBar.prefersLargeTitles = true;
529+
// }
530+
// // Set large title display mode for this specific view controller
531+
// if (viewController.navigationItem.largeTitleDisplayMode === UINavigationItemLargeTitleDisplayMode.Automatic) {
532+
// viewController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Always;
533+
// }
534+
// }
518535
} else {
519-
// 6b. Or just put it at the top of our table
536+
// 6b. Fallback: put it at the top of our table
520537
this.nativeViewProtected.tableHeaderView = this._searchController.searchBar;
521538
}
522539
} else {
523540
// Fallback: no view controller found, use table header
524541
this.nativeViewProtected.tableHeaderView = this._searchController.searchBar;
525542
}
526543

527-
// Ensure search bar is properly sized
544+
// 7. Ensure search bar is properly sized and prevent content inset issues
528545
this._searchController.searchBar.sizeToFit();
529546

547+
// 8. Disable automatic content inset adjustment that can cause spacing issues
548+
if (this.nativeViewProtected.respondsToSelector('setContentInsetAdjustmentBehavior:')) {
549+
// iOS 11+ - prevent automatic content inset adjustments
550+
this.nativeViewProtected.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Never;
551+
} else {
552+
// iOS 10 and below - disable automatic content inset
553+
this.nativeViewProtected.automaticallyAdjustsScrollIndicatorInsets = false;
554+
}
555+
530556
if (Trace.isEnabled()) {
531-
Trace.write(`ListView: UISearchController setup complete`, Trace.categories.Debug);
557+
Trace.write(`ListView: UISearchController setup complete with searchAutoHide: ${this.searchAutoHide}`, Trace.categories.Debug);
532558
}
533559
}
534560

@@ -545,6 +571,15 @@ export class ListView extends ListViewBase {
545571
this.nativeViewProtected.tableHeaderView = null;
546572
}
547573

574+
// Reset content inset adjustment behavior
575+
if (this.nativeViewProtected.respondsToSelector('setContentInsetAdjustmentBehavior:')) {
576+
// iOS 11+ - restore automatic content inset adjustments
577+
this.nativeViewProtected.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentBehavior.Automatic;
578+
} else {
579+
// iOS 10 and below - restore automatic content inset
580+
this.nativeViewProtected.automaticallyAdjustsScrollIndicatorInsets = true;
581+
}
582+
548583
// Cleanup references
549584
this._searchController.searchResultsUpdater = null;
550585
this._searchController = null;
@@ -1087,4 +1122,32 @@ export class ListView extends ListViewBase {
10871122
this._cleanupSearchController();
10881123
}
10891124
}
1125+
1126+
[searchAutoHideProperty.getDefault](): boolean {
1127+
return false;
1128+
}
1129+
[searchAutoHideProperty.setNative](value: boolean) {
1130+
if (Trace.isEnabled()) {
1131+
Trace.write(`ListView: searchAutoHide set to ${value}`, Trace.categories.Debug);
1132+
}
1133+
1134+
// If search is already enabled, update the existing search controller
1135+
if (this.showSearch && this._searchController) {
1136+
const viewController = this._getViewController();
1137+
if (viewController && viewController.navigationItem && SDK_VERSION >= 11.0) {
1138+
viewController.navigationItem.hidesSearchBarWhenScrolling = value;
1139+
1140+
// Enable large titles for better auto-hide effect when searchAutoHide is true
1141+
// if (value && viewController.navigationController && viewController.navigationController.navigationBar) {
1142+
// if (!viewController.navigationController.navigationBar.prefersLargeTitles) {
1143+
// viewController.navigationController.navigationBar.prefersLargeTitles = true;
1144+
// }
1145+
// if (viewController.navigationItem.largeTitleDisplayMode === UINavigationItemLargeTitleDisplayMode.Automatic) {
1146+
// viewController.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Always;
1147+
// }
1148+
// }
1149+
}
1150+
}
1151+
// If search is not enabled yet, the property will be used when _setupSearchController is called
1152+
}
10901153
}

packages/core/ui/list-view/list-view-common.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export abstract class ListViewBase extends ContainerView implements ListViewDefi
5858
public stickyHeaderTopPadding: boolean;
5959
public sectioned: boolean;
6060
public showSearch: boolean;
61+
public searchAutoHide: boolean;
6162

6263
get separatorColor(): Color {
6364
return this.style.separatorColor;
@@ -349,3 +350,10 @@ export const showSearchProperty = new Property<ListViewBase, boolean>({
349350
valueConverter: booleanConverter,
350351
});
351352
showSearchProperty.register(ListViewBase);
353+
354+
export const searchAutoHideProperty = new Property<ListViewBase, boolean>({
355+
name: 'searchAutoHide',
356+
defaultValue: false,
357+
valueConverter: booleanConverter,
358+
});
359+
searchAutoHideProperty.register(ListViewBase);

0 commit comments

Comments
 (0)