UNPKG

10 kBJavaScriptView Raw
1import { Background } from '../styling/background';
2import { borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty } from '../styling/style-properties';
3import { booleanConverter } from '../core/view-base';
4import { View, CSSType } from '../core/view';
5import { TextBase, whiteSpaceProperty, textOverflowProperty } from '../text-base';
6import { layout } from '../../utils';
7import { ios } from '../styling/background';
8var FixedSize;
9(function (FixedSize) {
10 FixedSize[FixedSize["NONE"] = 0] = "NONE";
11 FixedSize[FixedSize["WIDTH"] = 1] = "WIDTH";
12 FixedSize[FixedSize["HEIGHT"] = 2] = "HEIGHT";
13 FixedSize[FixedSize["BOTH"] = 3] = "BOTH";
14})(FixedSize || (FixedSize = {}));
15let Label = class Label extends TextBase {
16 createNativeView() {
17 const view = TNSLabel.new();
18 view.userInteractionEnabled = true;
19 return view;
20 }
21 // @ts-ignore
22 get ios() {
23 return this.nativeTextViewProtected;
24 }
25 get textWrap() {
26 return this.style.whiteSpace === 'normal';
27 }
28 set textWrap(value) {
29 if (typeof value === 'string') {
30 value = booleanConverter(value);
31 }
32 this.style.whiteSpace = value ? 'normal' : 'nowrap';
33 }
34 _requestLayoutOnTextChanged() {
35 if (this._fixedSize === FixedSize.BOTH) {
36 return;
37 }
38 if (this._fixedSize === FixedSize.WIDTH && !this.textWrap && this.getMeasuredHeight() > 0) {
39 // Single line label with fixed width will skip request layout on text change.
40 return;
41 }
42 super._requestLayoutOnTextChanged();
43 }
44 onMeasure(widthMeasureSpec, heightMeasureSpec) {
45 const nativeView = this.nativeTextViewProtected;
46 if (nativeView) {
47 const width = layout.getMeasureSpecSize(widthMeasureSpec);
48 const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
49 const height = layout.getMeasureSpecSize(heightMeasureSpec);
50 const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
51 this._fixedSize = (widthMode === layout.EXACTLY ? FixedSize.WIDTH : FixedSize.NONE) | (heightMode === layout.EXACTLY ? FixedSize.HEIGHT : FixedSize.NONE);
52 let nativeSize;
53 if (this.textWrap) {
54 // https://github.com/NativeScript/NativeScript/issues/4834
55 // NOTE: utils.measureNativeView(...) relies on UIView.sizeThatFits(...) that
56 // seems to have various issues when laying out UILabel instances.
57 // We use custom measure logic here that relies on overriden
58 // UILabel.textRectForBounds:limitedToNumberOfLines: in TNSLabel widget.
59 nativeSize = this._measureNativeView(width, widthMode, height, heightMode);
60 }
61 else {
62 // https://github.com/NativeScript/NativeScript/issues/6059
63 // NOTE: _measureNativeView override breaks a scenario with StackLayout that arranges
64 // labels horizontally (with textWrap=false) e.g. we are measuring label #2 within 356px,
65 // label #2 needs more, and decides to show ellipsis(...) but because of this its native size
66 // returned from UILabel.textRectForBounds:limitedToNumberOfLines: logic becomes 344px, so
67 // StackLayout tries to measure label #3 within the remaining 12px which is wrong;
68 // label #2 with ellipsis should take the whole 356px and label #3 should not be visible at all.
69 nativeSize = layout.measureNativeView(nativeView, width, widthMode, height, heightMode);
70 }
71 let labelWidth = nativeSize.width;
72 if (this.textWrap && widthMode === layout.AT_MOST) {
73 labelWidth = Math.min(labelWidth, width);
74 }
75 const measureWidth = Math.max(labelWidth, this.effectiveMinWidth);
76 const measureHeight = Math.max(nativeSize.height, this.effectiveMinHeight);
77 const widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
78 const heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
79 this.setMeasuredDimension(widthAndState, heightAndState);
80 }
81 }
82 _measureNativeView(width, widthMode, height, heightMode) {
83 const view = this.nativeTextViewProtected;
84 const nativeSize = view.textRectForBoundsLimitedToNumberOfLines(CGRectMake(0, 0, widthMode === 0 /* layout.UNSPECIFIED */ ? Number.POSITIVE_INFINITY : layout.toDeviceIndependentPixels(width), heightMode === 0 /* layout.UNSPECIFIED */ ? Number.POSITIVE_INFINITY : layout.toDeviceIndependentPixels(height)), view.numberOfLines).size;
85 nativeSize.width = layout.round(layout.toDevicePixels(nativeSize.width));
86 nativeSize.height = layout.round(layout.toDevicePixels(nativeSize.height));
87 return nativeSize;
88 }
89 [whiteSpaceProperty.setNative](value) {
90 this.adjustLineBreak();
91 }
92 [textOverflowProperty.setNative](value) {
93 this.adjustLineBreak();
94 }
95 adjustLineBreak() {
96 const whiteSpace = this.whiteSpace;
97 const textOverflow = this.textOverflow;
98 const nativeView = this.nativeViewProtected;
99 switch (whiteSpace) {
100 case 'normal':
101 nativeView.lineBreakMode = 0 /* NSLineBreakMode.ByWordWrapping */;
102 nativeView.numberOfLines = this.maxLines;
103 break;
104 case 'initial':
105 nativeView.lineBreakMode = 4 /* NSLineBreakMode.ByTruncatingTail */;
106 nativeView.numberOfLines = 1;
107 break;
108 case 'nowrap':
109 switch (textOverflow) {
110 case 'clip':
111 nativeView.lineBreakMode = 2 /* NSLineBreakMode.ByClipping */;
112 nativeView.numberOfLines = this.maxLines;
113 break;
114 default:
115 nativeView.lineBreakMode = 4 /* NSLineBreakMode.ByTruncatingTail */;
116 nativeView.numberOfLines = 1;
117 break;
118 }
119 break;
120 }
121 }
122 _redrawNativeBackground(value) {
123 if (value instanceof Background) {
124 const nativeView = this.nativeTextViewProtected;
125 if (nativeView) {
126 ios.createBackgroundUIColor(this, (color) => {
127 const cgColor = color ? color.CGColor : null;
128 nativeView.layer.backgroundColor = cgColor;
129 }, true);
130 }
131 }
132 this._setNativeClipToBounds();
133 }
134 [borderTopWidthProperty.setNative](value) {
135 const nativeView = this.nativeTextViewProtected;
136 const border = nativeView.borderThickness;
137 nativeView.borderThickness = {
138 top: layout.toDeviceIndependentPixels(this.effectiveBorderTopWidth),
139 right: border.right,
140 bottom: border.bottom,
141 left: border.left,
142 };
143 }
144 [borderRightWidthProperty.setNative](value) {
145 const nativeView = this.nativeTextViewProtected;
146 const border = nativeView.borderThickness;
147 nativeView.borderThickness = {
148 top: border.top,
149 right: layout.toDeviceIndependentPixels(this.effectiveBorderRightWidth),
150 bottom: border.bottom,
151 left: border.left,
152 };
153 }
154 [borderBottomWidthProperty.setNative](value) {
155 const nativeView = this.nativeTextViewProtected;
156 const border = nativeView.borderThickness;
157 nativeView.borderThickness = {
158 top: border.top,
159 right: border.right,
160 bottom: layout.toDeviceIndependentPixels(this.effectiveBorderBottomWidth),
161 left: border.left,
162 };
163 }
164 [borderLeftWidthProperty.setNative](value) {
165 const nativeView = this.nativeTextViewProtected;
166 const border = nativeView.borderThickness;
167 nativeView.borderThickness = {
168 top: border.top,
169 right: border.right,
170 bottom: border.bottom,
171 left: layout.toDeviceIndependentPixels(this.effectiveBorderLeftWidth),
172 };
173 }
174 [paddingTopProperty.setNative](value) {
175 const nativeView = this.nativeTextViewProtected;
176 const padding = nativeView.padding;
177 nativeView.padding = {
178 top: layout.toDeviceIndependentPixels(this.effectivePaddingTop),
179 right: padding.right,
180 bottom: padding.bottom,
181 left: padding.left,
182 };
183 }
184 [paddingRightProperty.setNative](value) {
185 const nativeView = this.nativeTextViewProtected;
186 const padding = nativeView.padding;
187 nativeView.padding = {
188 top: padding.top,
189 right: layout.toDeviceIndependentPixels(this.effectivePaddingRight),
190 bottom: padding.bottom,
191 left: padding.left,
192 };
193 }
194 [paddingBottomProperty.setNative](value) {
195 const nativeView = this.nativeTextViewProtected;
196 const padding = nativeView.padding;
197 nativeView.padding = {
198 top: padding.top,
199 right: padding.right,
200 bottom: layout.toDeviceIndependentPixels(this.effectivePaddingBottom),
201 left: padding.left,
202 };
203 }
204 [paddingLeftProperty.setNative](value) {
205 const nativeView = this.nativeTextViewProtected;
206 const padding = nativeView.padding;
207 nativeView.padding = {
208 top: padding.top,
209 right: padding.right,
210 bottom: padding.bottom,
211 left: layout.toDeviceIndependentPixels(this.effectivePaddingLeft),
212 };
213 }
214};
215Label = __decorate([
216 CSSType('Label')
217], Label);
218export { Label };
219Label.prototype.recycleNativeView = 'auto';
220//# sourceMappingURL=index.ios.js.map
\No newline at end of file