jsbox-cview 1.6.6 → 1.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +4 -0
  2. package/dist/components/alert/input-alert.d.ts +22 -0
  3. package/dist/components/alert/login-alert.d.ts +21 -0
  4. package/dist/components/alert/plain-alert.d.ts +15 -0
  5. package/dist/components/alert/uialert.d.ts +29 -0
  6. package/{components/base.ts → dist/components/base.d.ts} +9 -28
  7. package/dist/components/custom-navigation-bar.d.ts +117 -0
  8. package/dist/components/dialogs/dialog-sheet.d.ts +46 -0
  9. package/dist/components/dialogs/dialog-sheet.js +3 -1
  10. package/dist/components/dialogs/form-dialog.d.ts +15 -0
  11. package/dist/components/dialogs/list-dialog.d.ts +23 -0
  12. package/dist/components/dialogs/list-dialog.js +1 -1
  13. package/dist/components/dialogs/text-dialog.d.ts +13 -0
  14. package/dist/components/dynamic-contextmenu-view.d.ts +40 -0
  15. package/dist/components/dynamic-itemsize-matrix.d.ts +79 -0
  16. package/dist/components/dynamic-itemsize-matrix.js +1 -0
  17. package/dist/components/dynamic-itemsize-section-matrix.d.ts +115 -0
  18. package/dist/components/dynamic-preference-listview.d.ts +63 -0
  19. package/dist/components/dynamic-rowheight-list.d.ts +38 -0
  20. package/dist/components/enhanced-imageview.d.ts +41 -0
  21. package/dist/components/flowlayout.d.ts +63 -0
  22. package/dist/components/image-pager.d.ts +49 -0
  23. package/dist/components/oc-webview.d.ts +64 -0
  24. package/dist/components/page-control.d.ts +45 -0
  25. package/dist/components/pageviewer-titlebar.d.ts +48 -0
  26. package/dist/components/pageviewer.d.ts +41 -0
  27. package/dist/components/refresh-button.d.ts +25 -0
  28. package/dist/components/rotating-view.d.ts +45 -0
  29. package/dist/components/searchbar.d.ts +118 -0
  30. package/dist/components/sheet.d.ts +42 -0
  31. package/dist/components/single-views.d.ts +289 -0
  32. package/dist/components/spinners/loading-dual-ring.d.ts +18 -0
  33. package/dist/components/spinners/loading-wedges.d.ts +15 -0
  34. package/dist/components/spinners/spinner-androidstyle.d.ts +30 -0
  35. package/dist/components/static-preference-listview.d.ts +389 -0
  36. package/dist/components/symbol-button.d.ts +39 -0
  37. package/dist/components/tabbar.d.ts +140 -0
  38. package/dist/controller/base-controller.d.ts +125 -0
  39. package/dist/controller/base-controller.js +11 -11
  40. package/dist/controller/controller-router.d.ts +48 -0
  41. package/dist/controller/pageviewer-controller.d.ts +38 -0
  42. package/dist/controller/presented-page-controller.d.ts +41 -0
  43. package/dist/controller/splitview-controller.d.ts +90 -0
  44. package/dist/controller/splitview-controller.js +4 -0
  45. package/dist/controller/tabbar-controller.d.ts +49 -0
  46. package/dist/controller/tabbar-controller.js +0 -2
  47. package/{index.ts → dist/index.d.ts} +1 -0
  48. package/dist/index.js +1 -0
  49. package/dist/utils/colors.d.ts +7 -0
  50. package/dist/utils/cvid.d.ts +11 -0
  51. package/dist/utils/l10n.d.ts +1 -0
  52. package/dist/utils/path.d.ts +8 -0
  53. package/dist/utils/rect.d.ts +38 -0
  54. package/dist/utils/uitools.d.ts +75 -0
  55. package/package.json +20 -6
  56. package/.prettierignore +0 -6
  57. package/.prettierrc +0 -3
  58. package/components/alert/input-alert.ts +0 -64
  59. package/components/alert/login-alert.ts +0 -66
  60. package/components/alert/plain-alert.ts +0 -39
  61. package/components/alert/uialert.ts +0 -107
  62. package/components/custom-navigation-bar.ts +0 -579
  63. package/components/dialogs/dialog-sheet.ts +0 -111
  64. package/components/dialogs/form-dialog.ts +0 -63
  65. package/components/dialogs/list-dialog.ts +0 -119
  66. package/components/dialogs/text-dialog.ts +0 -44
  67. package/components/dynamic-contextmenu-view.ts +0 -115
  68. package/components/dynamic-itemsize-matrix.ts +0 -206
  69. package/components/dynamic-itemsize-section-matrix.ts +0 -363
  70. package/components/dynamic-preference-listview.ts +0 -684
  71. package/components/dynamic-rowheight-list.ts +0 -77
  72. package/components/enhanced-imageview.ts +0 -132
  73. package/components/flowlayout.ts +0 -248
  74. package/components/image-pager.ts +0 -180
  75. package/components/oc-webview.ts +0 -177
  76. package/components/page-control.ts +0 -93
  77. package/components/pageviewer-titlebar.ts +0 -166
  78. package/components/pageviewer.ts +0 -125
  79. package/components/refresh-button.ts +0 -83
  80. package/components/rotating-view.ts +0 -133
  81. package/components/searchbar.ts +0 -398
  82. package/components/sheet.ts +0 -104
  83. package/components/single-views.ts +0 -956
  84. package/components/spinners/loading-dual-ring.ts +0 -97
  85. package/components/spinners/loading-wedges.ts +0 -106
  86. package/components/spinners/spinner-androidstyle.ts +0 -269
  87. package/components/static-preference-listview.ts +0 -1282
  88. package/components/symbol-button.ts +0 -108
  89. package/components/tabbar.ts +0 -453
  90. package/controller/base-controller.ts +0 -214
  91. package/controller/controller-router.ts +0 -73
  92. package/controller/pageviewer-controller.ts +0 -93
  93. package/controller/presented-page-controller.ts +0 -76
  94. package/controller/splitview-controller.ts +0 -359
  95. package/controller/tabbar-controller.ts +0 -131
  96. package/dist/test/custom-navigation-bar.js +0 -40
  97. package/dist/test/dialog-sheet.js +0 -40
  98. package/dist/test/dynamic-contextmenu-view.js +0 -66
  99. package/dist/test/dynamic-itemsize-matrix.js +0 -74
  100. package/dist/test/dynamic-itemsize-section-matrix.js +0 -138
  101. package/dist/test/dynamic-preference-listview.js +0 -150
  102. package/dist/test/flowlayout.js +0 -76
  103. package/dist/test/form-dialog.js +0 -51
  104. package/dist/test/oc-webview.js +0 -195
  105. package/dist/test/pageviewer-controller.js +0 -20
  106. package/dist/test/pageviewer-titlebar.js +0 -18
  107. package/dist/test/pageviewer.js +0 -32
  108. package/dist/test/refresh-button.js +0 -26
  109. package/dist/test/searchbar.js +0 -36
  110. package/dist/test/splitview-controller.js +0 -41
  111. package/dist/test/static-preference-listview.js +0 -143
  112. package/dist/test/tabbar-controller.js +0 -48
  113. package/test/custom-navigation-bar.ts +0 -40
  114. package/test/dialog-sheet.ts +0 -40
  115. package/test/dynamic-contextmenu-view.ts +0 -67
  116. package/test/dynamic-itemsize-matrix.ts +0 -74
  117. package/test/dynamic-itemsize-section-matrix.ts +0 -142
  118. package/test/dynamic-preference-listview.ts +0 -151
  119. package/test/flowlayout.ts +0 -79
  120. package/test/form-dialog.ts +0 -48
  121. package/test/oc-webview.ts +0 -197
  122. package/test/pageviewer-controller.ts +0 -21
  123. package/test/pageviewer-titlebar.ts +0 -18
  124. package/test/pageviewer.ts +0 -31
  125. package/test/refresh-button.ts +0 -26
  126. package/test/searchbar.ts +0 -38
  127. package/test/splitview-controller.ts +0 -42
  128. package/test/static-preference-listview.ts +0 -142
  129. package/test/tabbar-controller.ts +0 -49
  130. package/tsconfig.json +0 -122
  131. package/utils/colors.ts +0 -17
  132. package/utils/cvid.ts +0 -32
  133. package/utils/l10n.ts +0 -42
  134. package/utils/path.ts +0 -97
  135. package/utils/rect.ts +0 -90
  136. package/utils/uitools.ts +0 -122
@@ -1,77 +0,0 @@
1
- import { Base } from "./base";
2
-
3
- interface DynamicRowHeightListProps extends Omit<UiTypes.ListProps, "data" | "template"> {}
4
- interface DynamicRowHeightListEvents extends Omit<UiTypes.ListEvents, "rowHeight"> {}
5
- interface DynamicRowHeightListCView extends Base<any, any> {
6
- heightToWidth: (width: number) => number;
7
- }
8
-
9
- /**
10
- * # cview Dynamic RowHeight List
11
- *
12
- * 可以自动更新 rowHeight 的 list
13
- *
14
- * 核心策略为 list 的所有行均为 cview,且每一个 cview 需要实现一个方法:
15
- * heightToWidth(width: number) => number
16
- * 通过这个方法汇报自己在某个宽度的时候所需要的高度,这必须任何时候均立即可用;
17
- *
18
- * 特别参数
19
- * sections: {title: string, rows: cview[]}[]
20
- * rows: cview[]
21
- * 两者不能同时存在,否则rows不起作用
22
- *
23
- * 除了 props.data, props.template 和 events.rowHeight 不可用,其他均和 list 一致
24
- */
25
- export class DynamicRowHeightList extends Base<UIListView, UiTypes.ListOptions> {
26
- _defineView: () => UiTypes.ListOptions;
27
- constructor({
28
- sections,
29
- rows,
30
- props,
31
- layout,
32
- events,
33
- }: {
34
- sections?: { title: string; rows: DynamicRowHeightListCView[] }[];
35
- rows?: DynamicRowHeightListCView[];
36
- props: DynamicRowHeightListProps;
37
- layout: (make: MASConstraintMaker, view: UIListView) => void;
38
- events: DynamicRowHeightListEvents;
39
- }) {
40
- super();
41
- this._defineView = () => {
42
- let data: any;
43
- if (sections && sections.length > 0) {
44
- data = sections.map((n) => ({
45
- title: n.title,
46
- rows: n.rows.map((r) => r.definition),
47
- }));
48
- } else if (rows && rows.length > 0) {
49
- data = rows.map((r) => r.definition);
50
- } else {
51
- throw new Error("sections or rows must be provided");
52
- }
53
- return {
54
- type: "list",
55
- props: {
56
- id: this.id,
57
- data,
58
- ...props,
59
- },
60
- layout,
61
- events: {
62
- rowHeight: (sender, indexPath) => {
63
- if (sections) {
64
- const cview = sections[indexPath.section].rows[indexPath.row];
65
- return cview.heightToWidth(sender.frame.width);
66
- } else if (rows) {
67
- return rows[indexPath.row].heightToWidth(sender.frame.width);
68
- } else {
69
- throw new Error("sections or rows must be provided");
70
- }
71
- },
72
- ...events,
73
- },
74
- };
75
- };
76
- }
77
- }
@@ -1,132 +0,0 @@
1
- import { Base } from "./base";
2
- import { Scroll } from "./single-views";
3
- import { cvid } from "../utils/cvid";
4
-
5
- /**
6
- * 此组件是为了加强 imageView,实现以下目的:
7
- * 1. 点击实现上下翻页
8
- * 2. 双指放大缩小(但不可以双击放大缩小)
9
- *
10
- * 请注意:此组件使用了Runtime代码重新设置了Tapped事件。
11
- * 与以前使用touchesEnded事件来实现相比,可以避免在滑动手指时误触发。
12
- * 但因此带来了副作用:必须在关闭前通过releaseGestureObject释放掉此视图中自定义的NSObject,
13
- * 否则再次启动可能会有问题。
14
- *
15
- * Props:
16
- * src: string, 图片地址
17
- * maxZoomScale: number, 最大缩放倍数,默认为2
18
- *
19
- * Events:
20
- * upperLocationTouched: (sender: EnhancedImageView) => void, 上半部分被点击
21
- * lowerLocationTouched: (sender: EnhancedImageView) => void, 下半部分被点击
22
- */
23
- export class EnhancedImageView extends Base<UIView, UiTypes.ViewOptions> {
24
- private _props: { src: string; maxZoomScale: number };
25
- private _scroll: Scroll;
26
- private _gestureObject: any;
27
- _defineView: () => UiTypes.ViewOptions;
28
-
29
- constructor({
30
- props,
31
- layout,
32
- events = {},
33
- }: {
34
- props: { src: string; maxZoomScale?: number };
35
- layout: (make: MASConstraintMaker, view: UIView) => void;
36
- events?: {
37
- upperLocationTouched?: (sender: EnhancedImageView) => void;
38
- lowerLocationTouched?: (sender: EnhancedImageView) => void;
39
- };
40
- }) {
41
- super();
42
- this._props = { maxZoomScale: 2, ...props };
43
- this._scroll = new Scroll({
44
- props: {
45
- zoomEnabled: true,
46
- doubleTapToZoom: false,
47
- maxZoomScale: this._props.maxZoomScale,
48
- },
49
- layout: $layout.fill,
50
- views: [
51
- {
52
- type: "image",
53
- props: {
54
- id: "image",
55
- src: this._props.src,
56
- contentMode: 1,
57
- },
58
- layout: $layout.fill,
59
- },
60
- ],
61
- events: {
62
- ready: (view) => {
63
- $delay(0.1, () =>
64
- this._addGesture(view, (gesture: any) => {
65
- const location = gesture.$locationInView(view.ocValue());
66
- const realLocation = $point(location.x - view.bounds.x, location.y - view.bounds.y);
67
- const frame = this.view.frame;
68
- if (realLocation.y <= frame.height / 2) {
69
- if (events.upperLocationTouched) events.upperLocationTouched(this);
70
- } else {
71
- if (events.lowerLocationTouched) events.lowerLocationTouched(this);
72
- }
73
- }),
74
- );
75
- },
76
- },
77
- });
78
- this._defineView = () => {
79
- return {
80
- type: "view",
81
- props: {
82
- id: this.id,
83
- },
84
- views: [this._scroll.definition],
85
- layout,
86
- events: {
87
- layoutSubviews: (sender) => {
88
- $delay(0.1, () => (this.src = this.src));
89
- $delay(0.3, () => (this.src = this.src));
90
- },
91
- },
92
- };
93
- };
94
- }
95
-
96
- private _addGesture(view: AllUIView, event: (gesture: any) => void) {
97
- const objectId = cvid.newId;
98
- $define({
99
- type: objectId + ": NSObject",
100
- events: {
101
- tapped: event,
102
- },
103
- });
104
- const object = $objc(objectId).$new();
105
- $objc_retain(object); // 此步骤是必须的,否则将很快被系统释放掉,
106
- // 但是必须在关闭时手动释放掉,否则再次启动可能会有问题
107
- this._gestureObject = object;
108
- const tapGestureRecognizer = $objc("UITapGestureRecognizer")
109
- .$alloc()
110
- .$initWithTarget_action(this._gestureObject, "tapped:");
111
- view.ocValue().$addGestureRecognizer(tapGestureRecognizer);
112
- }
113
-
114
- releaseGestureObject() {
115
- if (this._gestureObject) $objc_release(this._gestureObject);
116
- }
117
-
118
- get src() {
119
- return this._props.src;
120
- }
121
-
122
- set src(src) {
123
- this._props.src = src;
124
- const view = this._scroll.view.get("image") as UIImageView;
125
- view.src = src;
126
- }
127
-
128
- get image() {
129
- const view = this._scroll.view.get("image") as UIImageView;
130
- return view.image;
131
- }
132
- }
@@ -1,248 +0,0 @@
1
- import { Base } from "./base";
2
-
3
- /**
4
- * 流式布局:间距固定,项目高度固定但宽度不定,左对齐,自动换行,不能滚动。
5
- *
6
- * 注意事项:
7
- * 1. 此控件默认是可变高度的,但前提是布局中必须有关于高度的约束。
8
- * 如果不需要可变高度,可以设置fixedHeight为true
9
- * 1. 此控件的边缘是不留白的,这和Matrix不同
10
- * 2. itemWidth 如果超过总宽度,会被设定为总宽度
11
- * 3. maxRows 可以控制最大行数,如果超过则会被截断
12
- *
13
- * ## 属性
14
- * 属性的写法尽可能和Matrix的风格保持一致
15
- * - items: FlowlayoutItem[] 关键参数,必须实现一个方法itemWidth(): number, 用于告知自身理想的宽度
16
- * - spacing: number
17
- * - itemHeight: number
18
- * - maxRows?: number
19
- * - fixedHeight?: boolean
20
- * - menu?: UiTypes.ContextMenuOptions
21
- * - bgcolor?: UIColor
22
- *
23
- * ## 事件
24
- * - didSelect: (sender: Flowlayout, index: number, item: FlowlayoutItem) => void
25
- * - didLongPress: (sender: Flowlayout, index: number, item: FlowlayoutItem) => void
26
- *
27
- * ## 方法
28
- * - heightToWidth(width: number): height: number 根据宽度计算其应有的高度
29
- * - cell(index: number): FlowlayoutItem 获取对应位置的 cview
30
- * - set items(items: FlowlayoutItem[]) 设置子视图
31
- * - get items(): FlowlayoutItem[] 获取子视图
32
- */
33
- export class Flowlayout<T extends FlowlayoutItem> extends Base<UIView, UiTypes.ViewOptions> {
34
- private _width: number; // 缓存宽度,用于判断是否需要重新布局
35
- private _props: {
36
- items: T[];
37
- spacing: number;
38
- itemHeight: number;
39
- fixedRows?: number;
40
- fixedHeight?: boolean;
41
- menu?: UiTypes.ContextMenuOptions<UIView>;
42
- bgcolor?: UIColor;
43
- };
44
- private _wrappers: WrapperView<T>[];
45
- private _events?: {
46
- didSelect?: (sender: Flowlayout<T>, index: number, item: T) => void;
47
- didLongPress?: (sender: Flowlayout<T>, index: number, item: T) => void;
48
- };
49
- _defineView: () => UiTypes.ViewOptions;
50
-
51
- constructor({
52
- props,
53
- layout,
54
- events,
55
- }: {
56
- props: {
57
- items: T[];
58
- spacing: number;
59
- itemHeight: number;
60
- fixedRows?: number;
61
- fixedHeight?: boolean;
62
- menu?: UiTypes.ContextMenuOptions<UIView>;
63
- bgcolor?: UIColor;
64
- };
65
- layout: (make: MASConstraintMaker, view: UIView) => void;
66
- events?: {
67
- didSelect?: (sender: Flowlayout<T>, index: number, item: T) => void;
68
- didLongPress?: (sender: Flowlayout<T>, index: number, item: T) => void;
69
- };
70
- }) {
71
- super();
72
- this._width = 0;
73
- this._props = props;
74
- this._events = events;
75
- this._wrappers = props.items.map(
76
- (item, index) =>
77
- new WrapperView({
78
- item,
79
- menu: props.menu,
80
- didSelect: events?.didSelect,
81
- didLongPress: events?.didLongPress,
82
- flowlayout: this,
83
- index,
84
- }),
85
- );
86
- this._defineView = () => ({
87
- type: "view",
88
- props: {
89
- id: this.id,
90
- bgcolor: props.bgcolor,
91
- },
92
- layout,
93
- events: {
94
- layoutSubviews: (sender) => {
95
- if (this._width !== sender.frame.width) {
96
- this._width = sender.frame.width;
97
- const height = this._layoutWrappers();
98
- if (!this._props.fixedHeight) sender.updateLayout((make) => make.height.equalTo(height));
99
- }
100
- },
101
- },
102
- views: this._wrappers.map((wrapper) => wrapper.definition),
103
- });
104
- }
105
-
106
- cell(index: number): T {
107
- return this._props.items[index];
108
- }
109
-
110
- get items(): T[] {
111
- return this._props.items;
112
- }
113
-
114
- set items(items: T[]) {
115
- this._props.items = items;
116
- this._wrappers = items.map(
117
- (item, index) =>
118
- new WrapperView({
119
- item,
120
- menu: this._props.menu,
121
- didSelect: this._events?.didSelect,
122
- didLongPress: this._events?.didLongPress,
123
- flowlayout: this,
124
- index,
125
- }),
126
- );
127
- this.view.views.forEach((v) => v.remove());
128
- this._wrappers.forEach((wrapper) => this.view.add(wrapper.definition));
129
- const height = this._layoutWrappers();
130
- if (!this._props.fixedHeight) this.view.updateLayout((make) => make.height.equalTo(height));
131
- }
132
-
133
- _layoutWrappers(): number {
134
- const totalWidth = this._width;
135
- const itemHeight = this._props.itemHeight;
136
- const itemSpacing = this._props.spacing;
137
- let x = 0;
138
- let y = 0;
139
- let line = 1;
140
- this._wrappers.forEach((wrapper, index) => {
141
- const itemWidth = wrapper.item.itemWidth();
142
- const width = Math.min(itemWidth, totalWidth);
143
- if (x + width > totalWidth) {
144
- x = 0;
145
- y += itemHeight + itemSpacing;
146
- line++;
147
- }
148
- if (this._props.fixedRows && line > this._props.fixedRows) {
149
- wrapper.hidden = true;
150
- } else {
151
- wrapper.hidden = false;
152
- }
153
- wrapper.frame = $rect(x, y, width, itemHeight);
154
- x += width + itemSpacing;
155
- });
156
- if (this._props.fixedRows && line > this._props.fixedRows) {
157
- return this._props.fixedRows * (itemHeight + itemSpacing) - itemSpacing;
158
- }
159
- return y + itemHeight;
160
- }
161
-
162
- heightToWidth(width: number): number {
163
- const totalWidth = width;
164
- const itemHeight = this._props.itemHeight;
165
- const itemSpacing = this._props.spacing;
166
- let x = 0;
167
- let y = 0;
168
- let line = 1;
169
- this._wrappers.forEach((wrapper, index) => {
170
- const itemWidth = wrapper.item.itemWidth();
171
- const width = Math.min(itemWidth, totalWidth);
172
- if (x + width > totalWidth) {
173
- x = 0;
174
- y += itemHeight + itemSpacing;
175
- line++;
176
- }
177
- x += width + itemSpacing;
178
- });
179
- if (this._props.fixedRows && line > this._props.fixedRows) {
180
- return this._props.fixedRows * (itemHeight + itemSpacing) - itemSpacing;
181
- }
182
- return y + itemHeight;
183
- }
184
- }
185
-
186
- interface FlowlayoutItem extends Base<any, any> {
187
- itemWidth: () => number;
188
- }
189
-
190
- class WrapperView<T extends FlowlayoutItem> extends Base<UIView, UiTypes.ViewOptions> {
191
- _defineView: () => UiTypes.ViewOptions;
192
- item: T;
193
- constructor({
194
- item,
195
- menu,
196
- didSelect,
197
- didLongPress,
198
- flowlayout,
199
- index,
200
- }: {
201
- item: T;
202
- menu?: UiTypes.ContextMenuOptions<UIView>;
203
- didSelect?: (sender: Flowlayout<T>, index: number, item: T) => void;
204
- didLongPress?: (sender: Flowlayout<T>, index: number, item: T) => void;
205
- flowlayout: Flowlayout<T>;
206
- index: number;
207
- }) {
208
- super();
209
- this.item = item;
210
- const props: UiTypes.ViewProps = {
211
- id: this.id,
212
- frame: $rect(0, 0, 0, 0),
213
- userInteractionEnabled: true,
214
- };
215
- if (menu) {
216
- props.menu = menu;
217
- }
218
- this._defineView = () => ({
219
- type: "view",
220
- props,
221
- views: [item.definition],
222
- events: {
223
- tapped: (sender) => {
224
- if (didSelect) didSelect(flowlayout, index, item);
225
- },
226
- longPressed: (sender) => {
227
- if (didLongPress) didLongPress(flowlayout, index, item);
228
- },
229
- },
230
- });
231
- }
232
-
233
- set frame(frame: JBRect) {
234
- this.view.frame = frame;
235
- }
236
-
237
- get frame(): JBRect {
238
- return this.view.frame;
239
- }
240
-
241
- set hidden(hidden: boolean) {
242
- this.view.hidden = hidden;
243
- }
244
-
245
- get hidden(): boolean {
246
- return this.view.hidden;
247
- }
248
- }
@@ -1,180 +0,0 @@
1
- import { Base } from "./base";
2
- import { Matrix } from "./single-views";
3
-
4
- /**
5
- * 图片浏览组件
6
- *
7
- * 与内置的Gallery组件相比,ImagePager组件可以动态刷新,
8
- * 适用于图片数量较多的场景,以及需要动态加载图片列表的场景
9
- *
10
- */
11
- export class ImagePager extends Base<UIView, UiTypes.ViewOptions> {
12
- _props: {
13
- srcs: string[];
14
- page: number;
15
- doubleTapToZoom: boolean;
16
- };
17
- _matrix: Matrix;
18
- _pageLoadRecorder: { [key: number]: boolean };
19
- _defineView: () => UiTypes.ViewOptions;
20
-
21
- /**
22
- *
23
- * @param props
24
- * - srcs: string[] - 图片地址列表
25
- * - page: number - 当前页码
26
- * - doubleTapToZoom: boolean - 是否双击放大,默认为true
27
- * @param layout
28
- * @param events
29
- * - changed: (page: number) => void - 页码变化时触发
30
- * - tapped: (sender: ImagePager) => void - 点击图片时触发
31
- */
32
- constructor({
33
- props,
34
- layout,
35
- events = {},
36
- }: {
37
- props: {
38
- srcs?: string[];
39
- page?: number;
40
- doubleTapToZoom?: boolean;
41
- };
42
- layout: (make: MASConstraintMaker, view: UIView) => void;
43
- events: {
44
- changed?: (page: number) => void;
45
- tapped?: (sender: ImagePager) => void;
46
- };
47
- }) {
48
- super();
49
- this._props = {
50
- srcs: [],
51
- page: 0,
52
- doubleTapToZoom: true,
53
- ...props,
54
- };
55
- this._pageLoadRecorder = {};
56
- this._matrix = new Matrix({
57
- props: {
58
- direction: $scrollDirection.horizontal,
59
- pagingEnabled: true,
60
- alwaysBounceVertical: false,
61
- showsVerticalIndicator: false,
62
- showsHorizontalIndicator: false,
63
- template: {
64
- views: [
65
- {
66
- type: "scroll",
67
- props: {
68
- id: "scroll",
69
- zoomEnabled: true,
70
- maxZoomScale: 3,
71
- doubleTapToZoom: this._props.doubleTapToZoom,
72
- },
73
- layout: $layout.fill,
74
- views: [
75
- {
76
- type: "image",
77
- props: {
78
- id: "image",
79
- contentMode: $contentMode.scaleAspectFit,
80
- },
81
- },
82
- ],
83
- },
84
- ],
85
- },
86
- data: this._props.srcs.map((n) => {
87
- return { image: { src: n } };
88
- }),
89
- },
90
- layout: $layout.fill,
91
- events: {
92
- ready: (sender) => {
93
- // 如果没有此处的relayout,则会出现莫名其妙的bug
94
- sender.relayout();
95
- if (!this._matrix.view) return;
96
- this.page = this.page;
97
- this.loadsrc(this.page);
98
- },
99
- itemSize: (sender, indexPath) => {
100
- return $size(sender.frame.width, sender.frame.height);
101
- },
102
- forEachItem: (view, indexPath) => {
103
- const scroll = view.get("scroll") as UIScrollView;
104
- scroll.zoomScale = 0;
105
- //$delay(0.01, () => {});
106
- },
107
- willEndDragging: (sender, velocity, target) => {
108
- const oldPage = this.page;
109
- this._props.page = Math.round(target.x / sender.frame.width);
110
- //this.loadsrc(this.page, true);
111
- if (oldPage !== this.page && events.changed) events.changed(this.page);
112
- },
113
- didScroll: (sender) => {
114
- this.loadsrc(this.page + 1, true);
115
- this.loadsrc(this.page - 1, true);
116
- },
117
- },
118
- });
119
- this._defineView = () => {
120
- return {
121
- type: "view",
122
- props: {
123
- id: this.id,
124
- },
125
- layout,
126
- views: [this._matrix.definition],
127
- events: {
128
- layoutSubviews: (sender) => {
129
- this._pageLoadRecorder = {};
130
- sender.relayout();
131
- if (!this._matrix.view) return;
132
- this._matrix.view.reload();
133
- this.page = this.page;
134
- $delay(0.1, () => this.loadsrc(this.page, true));
135
- $delay(0.3, () => this.loadsrc(this.page, true));
136
- },
137
- },
138
- };
139
- };
140
- }
141
-
142
- loadsrc(page: number, forced = false) {
143
- if (page < 0 || page >= this._props.srcs.length) return;
144
- const cell = this._matrix.view.cell($indexPath(0, page));
145
- if (!cell) return;
146
- const image = cell.get("image") as UIImageView;
147
- if (forced || !image.image || !this._pageLoadRecorder[page]) {
148
- const scroll = cell.get("scroll") as UIScrollView;
149
- scroll.zoomScale = 0;
150
- this._pageLoadRecorder[page] = true;
151
- }
152
- }
153
-
154
- get page() {
155
- return this._props.page;
156
- }
157
-
158
- get currentImage() {
159
- const cell = this._matrix.view.cell($indexPath(0, this.page));
160
- if (!cell) return;
161
- const image = cell.get("image") as UIImageView;
162
- return image.image;
163
- }
164
-
165
- set page(page) {
166
- this._matrix.view.scrollTo({
167
- indexPath: $indexPath(0, page),
168
- animated: false,
169
- });
170
- this._props.page = page;
171
- }
172
-
173
- scrollToPage(page: number) {
174
- this._matrix.view.scrollTo({
175
- indexPath: $indexPath(0, page),
176
- animated: true,
177
- });
178
- this._props.page = page;
179
- }
180
- }