@@ -18,7 +18,12 @@ import {
18
18
paddingRightProperty ,
19
19
paddingTopProperty
20
20
} from '@nativescript/core/ui/styling/style-properties' ;
21
- import { letterSpacingProperty , textDecorationProperty , whiteSpaceProperty } from '@nativescript/core/ui/text-base' ;
21
+ import {
22
+ formattedTextProperty ,
23
+ letterSpacingProperty ,
24
+ textDecorationProperty ,
25
+ whiteSpaceProperty
26
+ } from '@nativescript/core/ui/text-base' ;
22
27
import { getClosestPropertyValue , lineHeightProperty } from '@nativescript/core/ui/text-base/text-base-common' ;
23
28
import { isNullOrUndefined , isString } from '@nativescript/core/utils/types' ;
24
29
import { iOSNativeHelper , layout } from '@nativescript/core/utils/utils' ;
@@ -31,6 +36,7 @@ import {
31
36
linkColorProperty ,
32
37
linkUnderlineProperty ,
33
38
maxLinesProperty ,
39
+ needFontComputation ,
34
40
needFormattedStringComputation ,
35
41
selectableProperty ,
36
42
textShadowProperty
@@ -41,6 +47,8 @@ export * from './label-common';
41
47
42
48
const majorVersion = iOSNativeHelper . MajorVersion ;
43
49
50
+ const AttributeOriginalFontSize = 'OriginalFontSize' ;
51
+
44
52
enum FixedSize {
45
53
NONE = 0 ,
46
54
WIDTH = 1 ,
@@ -404,6 +412,7 @@ export class Label extends LabelBase {
404
412
const height = layout . getMeasureSpecSize ( heightMeasureSpec ) ;
405
413
const heightMode = layout . getMeasureSpecMode ( heightMeasureSpec ) ;
406
414
if ( this . autoFontSize ) {
415
+ // this.needsAutoFontSize = true;
407
416
this . textViewDidChange (
408
417
nativeView ,
409
418
layout . toDeviceIndependentPixels ( width ) ,
@@ -460,7 +469,9 @@ export class Label extends LabelBase {
460
469
lineHeight : this . lineHeight ,
461
470
textAlignment : this . nativeTextViewProtected . textAlignment
462
471
} ,
463
- this
472
+ this ,
473
+ this . autoFontSize ,
474
+ this . fontSizeRatio
464
475
) as NSMutableAttributedString ;
465
476
let hasLink = false ;
466
477
result &&
@@ -482,24 +493,30 @@ export class Label extends LabelBase {
482
493
if ( this . nativeViewProtected ) {
483
494
this . nativeViewProtected . attributedText = this . attributedString ;
484
495
}
485
- this . _requestLayoutOnTextChanged ( ) ;
486
496
}
487
497
updateHTMLString ( fontSize ?: number ) {
488
498
// when in collectionView or pager
489
499
// if this is done sync (without DTCoreText) while init the cell
490
500
// it breaks the UICollectionView :s
491
501
if ( usingIOSDTCoreText ( ) ) {
492
502
this . _updateHTMLString ( ) ;
493
- } else {
494
- setTimeout ( ( ) => {
495
- this . _updateHTMLString ( ) ;
496
- } , 0 ) ;
503
+ } else {
504
+ // setTimeout(() => {
505
+ this . _updateHTMLString ( ) ;
506
+ // }, 0);
497
507
}
498
508
}
499
- [ colorProperty . setNative ] ( value : Color | string ) {
500
- const color = ! value || value instanceof Color ? ( value as Color ) : new Color ( value ) ;
501
- const nativeView = this . nativeTextViewProtected ;
502
- nativeView . textColor = color ? color . ios : null ;
509
+ _setColor ( color ) {
510
+ if ( this . nativeTextViewProtected instanceof UIButton ) {
511
+ this . nativeTextViewProtected . setTitleColorForState ( color , 0 /* Normal */ ) ;
512
+ this . nativeTextViewProtected . titleLabel . textColor = color ;
513
+ } else {
514
+ if ( this . formattedText || this . html ) {
515
+ this . _setNativeText ( ) ;
516
+ } else {
517
+ this . nativeTextViewProtected . textColor = color ;
518
+ }
519
+ }
503
520
}
504
521
[ linkColorProperty . setNative ] ( value : Color | string ) {
505
522
const color = ! value || value instanceof Color ? ( value as Color ) : new Color ( value ) ;
@@ -539,28 +556,90 @@ export class Label extends LabelBase {
539
556
}
540
557
@needFormattedStringComputation
541
558
[ htmlProperty . setNative ] ( value : string ) {
542
- // if (!this.style.fontInternal) {
559
+ this . fontSizeRatio = 1 ;
560
+ this . needsAutoFontSize = this . autoFontSize ;
543
561
this . updateHTMLString ( ) ;
544
- // }
562
+ }
563
+ @needFormattedStringComputation
564
+ [ formattedTextProperty . setNative ] ( value : string ) {
565
+ this . fontSizeRatio = 1 ;
566
+ this . needsAutoFontSize = this . autoFontSize ;
567
+ super [ formattedTextProperty . setNative ] ( value ) ;
545
568
}
546
569
@needFormattedStringComputation
547
570
[ letterSpacingProperty . setNative ] ( value : number ) {
571
+ this . fontSizeRatio = 1 ;
572
+ this . needsAutoFontSize = this . autoFontSize ;
548
573
super [ letterSpacingProperty . setNative ] ( value ) ;
549
574
}
550
575
@needFormattedStringComputation
551
576
[ lineHeightProperty . setNative ] ( value : number ) {
577
+ this . fontSizeRatio = 1 ;
578
+ this . needsAutoFontSize = this . autoFontSize ;
552
579
super [ lineHeightProperty . setNative ] ( value ) ;
553
580
}
554
- // @needFormattedStringComputation
555
- // [textAlignmentProperty.setNative](value: number) {
556
- // super[textAlignmentProperty.setNative](value);
557
- // }
581
+ @needFormattedStringComputation
582
+ [ colorProperty . setNative ] ( value : number ) {
583
+ super [ colorProperty . setNative ] ( value ) ;
584
+ }
585
+ [ fontInternalProperty . setNative ] ( value : any ) {
586
+ const nativeView = this . nativeTextViewProtected ;
587
+ this . fontSizeRatio = 1 ;
588
+ this . needsAutoFontSize = this . autoFontSize ;
589
+ const newFont : UIFont = value instanceof Font ? value . getUIFont ( nativeView . font ) : value ;
590
+ if ( ! this . formattedText && ! this . html ) {
591
+ nativeView . font = newFont ;
592
+ } else if ( newFont ) {
593
+ if ( ! this . _canChangeText ) {
594
+ this . _needFormattedStringComputation = true ;
595
+ return ;
596
+ }
597
+ this . _setNativeText ( ) ;
598
+ }
599
+ }
600
+ _setSpannablesFontSizeWithRatio ( ratio ) {
601
+ const nativeView = this . nativeTextViewProtected ;
602
+ const toChange : NSMutableAttributedString =
603
+ nativeView . attributedText instanceof NSMutableAttributedString
604
+ ? nativeView . attributedText
605
+ : NSMutableAttributedString . alloc ( ) . initWithAttributedString ( nativeView . attributedText ) ;
606
+ let found = false ;
607
+ toChange . enumerateAttributeInRangeOptionsUsingBlock (
608
+ AttributeOriginalFontSize ,
609
+ { location : 0 , length : nativeView . attributedText . length } ,
610
+ 0 ,
611
+ ( value , range : NSRange , stop ) => {
612
+ if ( ! value ) {
613
+ return ;
614
+ }
615
+ toChange . enumerateAttributeInRangeOptionsUsingBlock (
616
+ NSFontAttributeName ,
617
+ range ,
618
+ 0 ,
619
+ ( value2 : UIFont , range : NSRange , stop ) => {
620
+ if ( value2 && value * ratio !== value2 . pointSize ) {
621
+ const newFont = value2 . fontWithSize ( Math . round ( value * ratio ) ) ;
622
+ if ( newFont ) {
623
+ found = true ;
624
+ toChange . removeAttributeRange ( NSFontAttributeName , range ) ;
625
+ toChange . addAttributeValueRange ( NSFontAttributeName , newFont , range ) ;
626
+ }
627
+ }
628
+ }
629
+ ) ;
630
+ }
631
+ ) ;
632
+ if ( found ) {
633
+ nativeView . attributedText = toChange ;
634
+ }
635
+ }
558
636
_setNativeText ( ) {
559
637
if ( this . html ) {
560
638
this . updateHTMLString ( ) ;
561
639
} else {
562
640
super . _setNativeText ( ) ;
563
641
}
642
+ this . _requestLayoutOnTextChanged ( ) ;
564
643
}
565
644
setTextDecorationAndTransform ( ) {
566
645
const style = this . style ;
@@ -830,8 +909,11 @@ export class Label extends LabelBase {
830
909
}
831
910
}
832
911
912
+ fontSizeRatio = 1 ;
913
+ needsAutoFontSize = false ;
833
914
textViewDidChange ( textView : UITextView , width ?, height ?) {
834
- if ( this . autoFontSize ) {
915
+ if ( this . autoFontSize && this . needsAutoFontSize ) {
916
+ this . needsAutoFontSize = false ;
835
917
if (
836
918
( ! textView . attributedText && ! textView . text ) ||
837
919
( width === undefined && height === undefined && CGSizeEqualToSize ( textView . bounds . size , CGSizeZero ) )
@@ -852,8 +934,18 @@ export class Label extends LabelBase {
852
934
const fontSize = this . style . fontSize || 17 ;
853
935
let expectFont : UIFont = ( this . style . fontInternal || Font . default ) . getUIFont ( UIFont . systemFontOfSize ( fontSize ) ) ;
854
936
//first reset the font size
855
- textView . font = expectFont ;
856
937
let expectSize ;
938
+
939
+ const stepSize = this . autoFontSizeStep || 1 ;
940
+
941
+ const updateFontSize = ( font ) => {
942
+ if ( this . formattedText || this . html ) {
943
+ this . _setSpannablesFontSizeWithRatio ( font . pointSize / fontSize ) ;
944
+ } else {
945
+ textView . font = font ;
946
+ }
947
+ } ;
948
+ updateFontSize ( expectFont ) ;
857
949
const size = ( ) => {
858
950
if ( nbLines === 1 ) {
859
951
expectSize = textView . sizeThatFits ( CGSizeMake ( Number . MAX_SAFE_INTEGER , fixedHeight ) ) ;
@@ -867,18 +959,16 @@ export class Label extends LabelBase {
867
959
( expectSize . height > fixedHeight || expectSize . width > fixedWidth ) &&
868
960
expectFont . pointSize > ( this . minFontSize || 12 )
869
961
) {
870
- const newFont = expectFont . fontWithSize ( expectFont . pointSize - 1 ) ;
871
- textView . font = newFont ;
872
- // TODO: find a better way i dont want to have
873
- // to recompute html each time!
874
- if ( this . html ) {
875
- this . updateHTMLString ( newFont . pointSize ) ;
876
- }
962
+ const newFont = expectFont . fontWithSize ( expectFont . pointSize - stepSize ) ;
963
+ updateFontSize ( newFont ) ;
877
964
size ( ) ;
878
965
if ( expectSize . height >= fixedHeight || expectSize . width >= fixedWidth ) {
879
966
expectFont = newFont ;
880
967
} else {
881
- textView . font = newFont ;
968
+ expectFont = newFont ;
969
+ if ( ! this . formattedText && ! this . html ) {
970
+ textView . font = newFont ;
971
+ }
882
972
break ;
883
973
}
884
974
}
@@ -887,28 +977,30 @@ export class Label extends LabelBase {
887
977
( expectSize . height < fixedHeight || expectSize . width < fixedWidth ) &&
888
978
expectFont . pointSize < ( this . maxFontSize || 200 )
889
979
) {
890
- const newFont = expectFont . fontWithSize ( expectFont . pointSize + 1 ) ;
891
- textView . font = newFont ;
892
- // TODO: find a better way i dont want to have
893
- // to recompute html each time!
894
- if ( this . html ) {
895
- this . updateHTMLString ( newFont . pointSize ) ;
896
- }
980
+ const newFont = expectFont . fontWithSize ( expectFont . pointSize + stepSize ) ;
981
+ updateFontSize ( newFont ) ;
982
+
897
983
size ( ) ;
898
984
899
985
if ( expectSize . height <= fixedHeight || expectSize . width <= fixedWidth ) {
900
986
expectFont = newFont ;
901
987
} else {
902
- textView . font = newFont ;
988
+ expectFont = newFont ;
989
+ if ( ! this . formattedText && ! this . html ) {
990
+ textView . font = newFont ;
991
+ }
903
992
break ;
904
993
}
905
994
}
906
995
}
996
+ this . fontSizeRatio = expectFont . pointSize / fontSize ;
907
997
this . updateTextContainerInset ( ) ;
908
998
}
909
999
}
910
1000
[ autoFontSizeProperty . setNative ] ( value : boolean ) {
911
- if ( value && ( this . text || this . html ) ) {
1001
+ if ( value && ( this . text || this . html || this . formattedText ) ) {
1002
+ this . fontSizeRatio = 1 ;
1003
+ this . needsAutoFontSize = true ;
912
1004
this . textViewDidChange ( this . nativeTextViewProtected ) ;
913
1005
} else {
914
1006
this [ fontInternalProperty . setNative ] ( this . style . fontInternal ) ;
0 commit comments