用户
 找回密码
 立即注册

发帖

UITextView中#话题#功能的简单实现

[复制链接]
  • TA的每日心情
    慵懒
    2025-11-24 10:46
  • 27

    主题

    6

    回帖

    669

    积分

    管理员

    积分
    669
    发表于 2015-8-9 00:00:00
    实现过程1
    今天来谈谈类似于新浪微博话题功能的简单实现,当文字是”#话题#”这种格式时,该文字字体得变颜色。个人觉得,这种问题的处理方式可以是,监听用户输入的信息,如果遇到有”#”号输入或删除时,再处理看是否需要改变字体颜色。于是我就按照这种思路写了一段改变颜色的代码,它就是是遍历textview.text,然后在将两个”#”号之间有文字的字体设置颜色,不会玩正则,所以这个方法比较蠢。O(∩_∩)O~
    1. /**6 c, O- E6 x/ H, a  i* Y
    2. *  设置textview字体属性! w, _0 c3 G3 Y9 R
    3. */: O) O/ G3 k1 l; Z6 l. t2 G3 t
    4. - (void)setTextViewAttributed {( D: ?3 Q$ L0 r3 O% \( i
    5.     NSMutableArray *indexArray = [NSMutableArray array];& O0 B5 K( y7 b. L% ]( m$ f/ J# P
    6.     for (NSInteger i = 0; i < self.topicTextView.text.length; i++) {" h' {' `2 k/ C7 J8 _
    7.         NSString *indexString = [self.topicTextView.text substringWithRange:NSMakeRange(i, 1)];/ s" Y$ c' A) ]; l' s7 w8 h
    8.         if ([indexString isEqualToString:topicString]) {. g2 n& M" a9 v  Y, ]
    9.             [indexArray addObject:@(i)];
      : q  O& L2 P* k7 `3 y$ t
    10.         }* D. ]3 t/ _0 ^. ~/ V2 f  b# h( s2 u
    11.     }1 F# V0 A6 x/ |0 ~" [6 O
    12.     // reset# ^5 @+ ?7 s+ @7 K- ~* s4 H$ [( }
    13.     NSMutableAttributedString *aText = [[NSMutableAttributedString alloc] initWithString:self.topicTextView.text];7 w4 C6 }' L5 D8 J- A
    14.     self.topicTextView.attributedText = aText;" c. D; _: a6 e* c6 k& x
    15.     self.topicTextView.font = [UIFont systemFontOfSize:16.0];/ f; o1 @+ G3 H6 G6 c
    16. # I. D; Y5 p0 p- B
    17.     // change
      . q! f0 o7 i( t7 {& X( Y
    18.     if (indexArray.count > 1) {) B9 `. Y1 U2 i; S& u, o$ J
    19.         NSMutableAttributedString *aText = [[NSMutableAttributedString alloc] initWithString:self.topicTextView.text];
      7 R' Y$ \$ \9 y4 R+ b
    20.         for (NSInteger i = 0; i < indexArray.count; i++) {
      ) g1 R6 X0 o% j2 T6 g: C* Q! R/ E  w5 R
    21.             NSInteger index1 = [indexArray integerValue];
      9 c8 S# [# b: ~% B$ X2 M
    22.             NSInteger index2 = 0;
      - D0 m  q- n8 x0 E* G
    23.             if ((i + 1) < indexArray.count) {
      2 O! U9 |1 I1 c; u
    24.                 index2 = [indexArray[i + 1] integerValue];0 {0 l. @" W9 b4 T- \3 P$ e
    25.             }
      5 C$ [* H( P; E8 Y) N4 S) z
    26.             if (index2 - index1 > 1) {
        L' g% S$ z' T( b( p" P
    27.                 // 多余中间有值才显示
      ) |& N6 ?8 c, F5 ]6 E5 Q6 Z! E9 F
    28.                 [aText setAttributes:@{ NSForegroundColorAttributeName: TopicColor } range:NSMakeRange(index1, index2 - index1 + 1)];1 q- u7 V6 V" ^7 g( e; u6 ?  U" o
    29.                 ++i;
        f0 H) [; I& ^! A1 q5 H
    30.             }
      6 E, q! H9 J& v1 q$ _
    31.         }& h$ D/ @" O; G/ h$ ?+ ^2 y
    32.         self.topicTextView.attributedText = aText;) }3 X5 S7 G8 _4 }1 M
    33.         self.topicTextView.font = [UIFont systemFontOfSize:16.0];
      : Q5 w- E% c$ g  s0 G. s
    34.     }2 e4 q/ H8 N/ ^2 T6 A; C+ A
    35. }
    复制代码
    实现过程2
    这个是我一厢情愿写的demo。因为现实并不是这样子的,客户端的话题只能从服务端获取,每个话题都是有标识的,因为不能让用户随心所欲的创建话题撒!所以呢,用户自己手动输入”#”号,然并卵。如果是这样子的话,那我只有三个问题要解决了:
    • 改变话题字符串颜色;
    • 光标不能移动到话题字符串中间,当用户光标移动至话题后面时,用户第一次点击键盘删除按钮,其实是选中这个话题的,再一次点击键盘删除按钮时,才会删除这个话题字符串;
    • 上传至服务器的时候,并不是上传#话题#,而是上传协议好的字符串,就是能让服务端能够识别这个话题;' G* x; }. n. Y
    在实现过程中,我以AttributedString的颜色值为基准,用几个正则为查找工具,结合UITextView的三个代理方法。
    1. /// Prior to replacing text, this method is called to give your delegate a chance to accept or reject the edits. If you do not implement this method, the return value defaults to YES.( O  S" [+ |2 w& P2 w" L
    2. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
      ; ]: S" R: K: o; y1 Y/ _& i: q" t) B

    3. . v; T  g$ \+ T
    4. /// The text view calls this method in response to user-initiated changes to the text. This method is not called in response to programmatically initiated changes. Implementation of this method is optional.9 m5 y3 I) v; x" O
    5. - (void)textViewDidChange:(UITextView *)textView;
      ! A2 ^; ?: x9 F5 M% g4 _
    6. % s: t! K2 _  c6 R! R5 ~$ F
    7. ///  Implementation of this method is optional. You can use the selectedRange property of the text view to get the new selection.
      0 z" w/ k) E: C/ S9 _$ k# w0 h# {  g
    8. - (void)textViewDidChangeSelection:(UITextView *)textView;
    复制代码
    这三个方法都不陌生吧,那么我的思路就简单了
    • shouldChangeTextInRange 代理方法中,第一,实现第一次选中,第二次删除功能;第二,实现插入话题后,需要改变其他字符串的初始颜色,得在这个方法里面做个标志。
    • textViewDidChange 代理方法中,实现 根据 shouldChangeTextInRange 方法中所得到的标志,设置字符串的初始颜色;
    • textViewDidChangeSelection 代理方法中,实现让光标不能移动到话题里面;1 x  ]4 u1 K8 S
    首先我定义了两个变量,插入了话题以后,继续在后面输入字符的话,字符颜色就跟话题颜色一样了。所以,我得用这两个变量来实现改变输入字符的初始颜色。
    1. /// 改变Range& L* }: A/ f" \* w; h
    2. @property (assign, nonatomic) NSRange changeRange;; Y# f: P1 D4 Z% x) I
    3. /// 是否改变4 a: v* W4 I4 o0 e+ M
    4. @property (assign, nonatomic) BOOL isChanged;
    复制代码
    哦,对了,我还得用一个变量来记录上次光标所在的位置,因为话题字符串是不让它输入的。
    1. /// 光标位置
      $ r7 V( {9 [# V) B
    2. @property (assign, nonatomic) NSInteger cursorLocation;
    复制代码
    用户从其他界面选择好话题以后,它得插入到textview中啊:
    1. NSString *insertText = [NSString stringWithFormat:@"#%@#", dict[KeyTopicName]];
      - x0 b4 T. u2 r
    2. [self.textView insertText:insertText];
      ( x' M; y& x: P& ~5 G
    3. NSMutableAttributedString *tmpAString = [[NSMutableAttributedString alloc] initWithAttributedString:self.textView.attributedText];. W8 s/ C+ x7 z1 O$ N, }
    4. [tmpAString setAttributes:@{ NSForegroundColorAttributeName: TopicColor, NSFontAttributeName: DefaultSizeFont } range:NSMakeRange(self.textView.selectedRange.location - insertText.length, insertText.length)];
      ) H# ^2 r% {9 B7 v: ?! Q
    5. self.textView.attributedText = tmpAString;
    复制代码
    然后我还得找到将用户所选择插入的话题位置啊。
    1. /**
      ( _; S* Q1 g+ i. F, v
    2. *  得到话题Range数组
      5 p2 ]4 c7 C  S! A. W+ a
    3. *# K9 k3 _9 m+ ?# F* x0 P
    4. *  @return return value description+ y1 q1 k: C: r$ e; f2 S, I
    5. */
      ( O3 O; J1 ]! k
    6. - (NSArray *)getTopicRangeArray:(NSAttributedString *)attributedString {
      * B, j9 @+ {1 B$ s/ S5 W6 I
    7.     NSAttributedString *traveAStr = attributedString ?: _textView.attributedText;6 y5 E; f: U- c* T8 q
    8.     __block NSMutableArray *rangeArray = [NSMutableArray array];
      , @) l8 _  h' i; P8 B
    9.     static NSRegularExpression *iExpression;0 w5 u2 S# l9 y( i
    10.     iExpression = iExpression ?: [NSRegularExpression regularExpressionWithPattern:@"#(.*?)#" options:0 error:NULL];
      ' G+ C1 r/ w1 v: J! _( _
    11.     [iExpression enumerateMatchesInString:traveAStr.string7 u& R7 K' T) ]  h) K( m( J
    12.                                   options:0' c! _+ o2 I3 W- c
    13.                                     range:NSMakeRange(0, traveAStr.string.length)- Z- Z. Y: L! K0 j
    14.                                usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {- p6 D7 z, `- j4 Z) b% F# x
    15.                                    NSRange resultRange = result.range;/ e" f$ e& r- F6 B/ M3 u1 |
    16.                                    NSDictionary *attributedDict = [traveAStr attributesAtIndex:resultRange.location effectiveRange:&resultRange];
      3 _8 R: X4 v" e+ z/ f% O: t, h- P
    17.                                    if ([attributedDict[NSForegroundColorAttributeName] isEqual:TopicColor]) {
      ) B3 F3 [0 S5 g9 P/ S- |7 D: Z
    18.                                        [rangeArray addObject:NSStringFromRange(result.range)];
      " a! y9 Q) f: e3 `# H; x% F
    19.                                    }# y" j( s1 ?, t* k7 M
    20.                                }];
      " d1 o8 l1 M$ V7 z
    21.     return rangeArray;
      9 h- @  f6 y" Z" y1 {- C
    22. }
    复制代码
    那么,三个UITextView delegate方法里的代码就可以这么玩了:
    1. #pragma mark - UITextView Delegate
      : k, Y  F4 C1 Q; Q$ ~
    2. - (void)textViewDidChangeSelection:(UITextView *)textView {$ f$ H3 t. q0 e) n3 \) m7 g2 T
    3.     NSArray *rangeArray = [self getTopicRangeArray:nil];
      5 P  I5 u8 a3 w4 K; m2 J, s
    4.     BOOL inRange = NO;7 T0 d7 D0 Q# y+ @
    5.     for (NSInteger i = 0; i < rangeArray.count; i++) {& {' o; \* Z; u2 W) b( W3 ~& [3 F
    6.         NSRange range = NSRangeFromString(rangeArray);
      0 M4 R6 w( f4 J+ v; f' `; e
    7.         if (textView.selectedRange.location > range.location && textView.selectedRange.location < range.location + range.length) {5 q; S; r* Z% B& `4 L2 d0 q0 q
    8.             inRange = YES;, r( }( M( ^& @  z( r& }4 K* `
    9.             break;0 d" w0 [3 r3 r% P6 [
    10.         }
      0 l" ?. Y3 `# A% e
    11.     }
      1 h5 G/ M7 ^; X; z( n' k, x2 z
    12.     if (inRange) {9 x! N/ Z8 @' L! r
    13.         textView.selectedRange = NSMakeRange(self.cursorLocation, textView.selectedRange.length);% M+ _; P8 x  n" L9 W  g( G+ q
    14.         return;
      # G3 Z5 u' q7 @* O
    15.     }# F' r' s! @! @2 q; g
    16.     self.cursorLocation = textView.selectedRange.location;  V8 E; x0 j2 d( f2 D9 d
    17. }
      . B' r* N) Y* o+ C- n% j

    18. . g) l2 ~/ E+ u3 }
    19. - (void)textViewDidChange:(UITextView *)textView {# B+ R) ?. ?2 c; g
    20.     if (_isChanged) {
      9 S% y6 L0 Q4 X: h5 u
    21.         NSMutableAttributedString *tmpAString = [[NSMutableAttributedString alloc] initWithAttributedString:self.textView.attributedText];1 P: |9 U' Z" B8 w$ X0 T
    22.         [tmpAString setAttributes:@{ NSForegroundColorAttributeName: [UIColor blackColor], NSFontAttributeName: DefaultSizeFont } range:_changeRange];) N, O; G9 y/ M
    23.         _textView.attributedText = tmpAString;
      / Q/ G) x) V$ x% v! V  R
    24.         _isChanged = NO;
      8 e# K0 L* i5 y6 o* |" V
    25.     }
      0 P& |( ^9 A& w" [" Q( F) W
    26. }
      9 ?* q5 {% X3 Y4 p: a$ u; b
    27. 2 @( F: _# z  ^6 ]
    28. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
      ' e* g1 v  ^6 c; J! Q; z
    29.     if ([text isEqualToString:@""]) { // 删除, a1 X# M5 G' f2 Y+ q
    30.         NSArray *rangeArray = [self getTopicRangeArray:nil];3 G! {) Q8 b5 y& z! L, w  v
    31.         for (NSInteger i = 0; i < rangeArray.count; i++) {
      - l; o- ^9 @4 n9 w5 }6 A
    32.             NSRange tmpRange = NSRangeFromString(rangeArray);" C- S) y# T6 t
    33.             if ((range.location + range.length) == (tmpRange.location + tmpRange.length)) {; ?* U" ]+ M5 q* q
    34.                 if ([NSStringFromRange(tmpRange) isEqualToString:NSStringFromRange(textView.selectedRange)]) {; Z! e1 x! V5 {7 G$ B; ?
    35.                     // 第二次点击删除按钮 删除/ V$ s' y9 f5 r) n3 r9 a- ^
    36.                     return YES;
      2 L: o6 T9 r0 b; g1 j, i: w5 t
    37.                 } else {; p3 h( |0 G  s& V. ]/ ~# e0 G& c
    38.                     // 第一次点击删除按钮 选中
      " ^: F4 a4 E. [/ m; W
    39.                     textView.selectedRange = tmpRange;5 f1 j" ], S" x
    40.                     return NO;
      " P5 v5 f& s! y; E% r! G
    41.                 }
      2 A+ G! V4 k- y3 y% s' Q( W, V0 [" d4 Y
    42.             }0 q) C, Q+ b3 r( \* H6 c0 G) {
    43.         }
      4 J* g. p( u& D6 a. a% }! R
    44.     } else { // 增加
      " r% j1 s4 K/ x% U
    45.         NSArray *rangeArray = [self getTopicRangeArray:nil];
      " a2 A! d# q1 O4 H" y" m
    46.         if ([rangeArray count]) {
      0 N4 N7 W7 ^2 b! P6 e
    47.             for (NSInteger i = 0; i < rangeArray.count; i++) {% r& q! q) i7 K; l- F5 w" J
    48.                 NSRange tmpRange = NSRangeFromString(rangeArray);9 ]- m/ h( \/ V: S1 u
    49.                 if ((range.location + range.length) == (tmpRange.location + tmpRange.length) || !range.location) {
      . ]! e, ?5 @  S6 w# J
    50.                     _changeRange = NSMakeRange(range.location, text.length);; O* A) S& l% [
    51.                     _isChanged = YES;
      0 I6 y4 f( U  n$ l* t# L. |; U- M' k
    52.                     return YES;
      $ N4 P8 Y$ s  g
    53.                 }/ l/ O0 b2 U* k
    54.             }
      2 ?7 {) {- `+ Y( c0 C2 U/ \4 z. z3 w
    55.         } else {- V8 \- Z0 K8 ]' a
    56.             // 话题在第一个删除后 重置text color
      0 Z& ~( t4 X9 t9 M# G
    57.             if (!range.location) {
      4 b5 G3 J5 `# d2 [
    58.                 _changeRange = NSMakeRange(range.location, text.length);
      + b' m3 @3 N  p. S7 n9 s; P; j6 w
    59.                 _isChanged = YES;1 F  \  Q0 c' b" r' }
    60.                 return YES;
      6 C& ]  S% O4 I  u) X# g9 V
    61.             }
        m1 c  |: L, h5 M+ O2 ~8 T% U* k* P
    62.         }5 r" e- M! p! a5 w7 a( G
    63.     }
      & x& q: ?% l' ~: Y) c
    64.     return YES;& `  {# Q" t. L$ S
    65. }
    复制代码
    好吧,通过以上方法,基本输入、删除操作功能是实现了。但是,上传貌似是个问题,因为我得上传跟服务端协议好的字符串格式啊;还有假如有一个聪明的用户,发现客户端和服务端的协议格式,他输入了那种格式的字符串,本着对服务端大哥的崇敬之心,我得将它转成”#话题#”格式啊。
    1. /**
        t2 F' S: o% N  P6 m
    2. *  获取上传时 textview text 字符串
      & D6 O2 a4 u" V# t; I. H/ Z
    3. */ V8 C9 j. e' B+ Q* M
    4. *  @return <#return value description#>
      / w" C! t8 Z8 i" \& g
    5. */* f# ^* ~5 }" }% _, x2 o. T+ L
    6. - (NSString *)getUploadString {( j. N4 K* D; J$ M5 Y! p
    7.     NSMutableString *lastTopic = [NSMutableString string];
      , T  u5 J" D8 g6 _& S9 u, N7 q
    8.     NSAttributedString *formatAString = [self formatAttributedString];
      % e7 s$ D4 l) Y, z) ]4 Y# z
    9.     NSArray *rangeArray = [self getTopicRangeArray:formatAString];& d* C4 c" I) }/ u  m
    10.     NSInteger lastLocation = 0;
      7 `9 F5 ?) {8 s/ l: G7 b8 q& R6 c
    11.     for (NSInteger i = 0; i < rangeArray.count; i++) {! \- p( u% V- g5 A
    12.         // 转成协议字符串代码8 a$ R6 Q. A: U/ U& S
    13.     }) k: L3 J$ @6 m- _# O2 ?
    14.     if (lastLocation < formatAString.string.length) {, k  o- J# x. o: s, x
    15.         [lastTopic appendString:[formatAString.string substringFromIndex:lastLocation]];
      / _& n) r/ k  X  E8 R! |) }
    16.     }# i. o& y- \( e( v
    17.     return lastTopic;7 v0 z" j5 q& V  S" N
    18. }9 V$ g( X( i( T+ h7 {6 N

    19. $ E, p% r3 W1 p9 N; k* |
    20. /**3 F: l; f. n+ d1 T$ [
    21. *  上传时候 将文本中不带topic color的 协议字符串 改成 "#话题#" 上传至服务器
      ( I, P) z) C% h/ s, r* @# D* L
    22. *
      ' m6 e! @5 Y/ u2 Q
    23. *  @return <#return value description#>  g6 N' b; \$ M: U* K8 E6 s) e
    24. */# Z" H4 G$ T2 X, T8 I7 f
    25. - (NSMutableAttributedString *)formatAttributedString {6 F  V, R+ P, A% B5 u% k
    26.     NSMutableAttributedString *tmpAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:_textView.attributedText];
      6 t7 j( l. K5 _
    27.     static NSRegularExpression *iExpression;
      . {0 F2 ?$ h+ J" X
    28.     iExpression = iExpression ?: [NSRegularExpression regularExpressionWithPattern:@"获取协议字符串正则" options:0 error:NULL];
      : c) |5 O# K5 F" Y  B6 m- \, D
    29.     // 临时遍历的 topic数组
      2 T1 U4 I( }3 v$ H. K5 u
    30.     NSMutableArray *topicArray = [NSMutableArray array];- Y1 Y( Y% A$ M+ x. |2 `: P3 p
    31.     [topicArray addObjectsFromArray:[iExpression matchesInString:tmpAttributedString.string options:0 range:NSMakeRange(0, tmpAttributedString.string.length)]];
      / |2 b# u9 [  p: h. w5 j/ S
    32.     while (topicArray.count) {( [8 q  v& a( h; o
    33.         NSTextCheckingResult *result = [topicArray firstObject];
      7 C- _* ?3 }! H( i4 U
    34.         NSString *searchStr = [tmpAttributedString.string substringWithRange:result.range];
      + r5 P3 {% Q) \, q
    35. 2 ?6 F8 [9 L! n# q
    36.                /**1 O3 D" z; f# d' j' |
    37.                * 替换代码5 i5 g. y( p, ?8 F# U; z
    38.                */
      + O0 m9 ?- c9 J. `/ x
    39. 4 I- K5 d  b6 y* S' @' \
    40.         [topicArray removeAllObjects];+ p5 u% Q% J: c2 \, B) W

    41. $ \6 ], O7 ^6 r9 \; W( a
    42.         [topicArray addObjectsFromArray:[iExpression matchesInString:tmpAttributedString.string options:0 range:NSMakeRange(0, tmpAttributedString.string.length)]];. U# h3 h/ {" Y& g3 u
    43.     }0 j7 w5 @) ^+ }# I0 q
    44.     return tmpAttributedString;6 q5 k+ S; U* v
    45. }
    复制代码
    实现总结
    文中,我只说了大致的实现方式以及核心功能代码,因为有的东西涉及到公司的。。。所以,都懂得哈!
    " l. o5 U. D6 j9 y& u在做这个功能过程中,我走了一些弯路。因为在上次博文中,我延时的发现AttributedString可以设置图片,所以我当时的想法是将”#话题#”这段文字转成image然后添加到textview的AttributedString中。 牛逼的代码都找好了. U; F+ {( q; C: ~1 L$ h
    1. /**9 t7 l' M+ t, B4 x4 K& F8 _+ a2 |
    2. *  Text to Image) e' @, l6 e  p; c
    3. *
      8 \  ]3 x8 X  x" p6 k
    4. *  @param text text description9 w' ^+ A0 J7 a8 N
    5. *) B, U  M) u3 i: `% ]3 h) y, k+ |
    6. *  @return return value description
      6 }" P2 g: @5 L( m
    7. */
      0 @- d% b4 d) ~# w
    8. - (UIImage *)imageFromText:(NSString *)text {9 k+ n! v" S1 |. K
    9.     NSMutableParagraphStyle *paragraph = [NSMutableParagraphStyle new];: y- }4 \% B* y6 J* }) r
    10.     paragraph.lineBreakMode = NSLineBreakByCharWrapping;) a% C. ]& H; P$ i' j* X
    11.     paragraph.alignment = NSTextAlignmentLeft;
      , ]2 @7 P1 N# D1 o
    12.     NSDictionary *attributeDict = @{NSFontAttributeName: [UIFont systemFontOfSize:14.0], NSForegroundColorAttributeName: [UIColor redColor], NSParagraphStyleAttributeName: paragraph};7 h* {9 o1 m4 `( D% x* P2 v- q0 V! X
    13.     CGSize textSize = [text sizeWithAttributes:attributeDict];
      4 f, M  G! M0 A, X, E( D  y
    14.     NSAttributedString *mutableString = [[NSAttributedString alloc] initWithString:text attributes:attributeDict];
      ' x) X/ R6 `% x8 D
    15.     UIGraphicsBeginImageContextWithOptions(textSize, NO, 0.0);& A# x6 M1 y1 {% ]
    16.     [mutableString drawInRect:CGRectMake(0.0, 0.0, textSize.width, textSize.height)];  N. l. u7 t. z2 ]
    17.     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();8 P; z, H7 ?* {9 K
    18.     UIGraphicsEndImageContext();
      + M( U' m- ~: _' y
    19.     return image;- w) j6 H" B6 @5 [
    20. }
    复制代码
    可是。。。后面因为实现新浪微博,第一次删除选中,第二次删除删除的效果,这个思路被抛弃了。其实,这个思路当时还有两个问题,我还没有解决:
    • textview的AttributedString添加图片后,后面输入的文字和图片中的文字,centerY不相等,有偏差。
    • 如果#话题#转为图片了,我得用什么方法去获取它在最终上传字符串中的位置,因为添加完成后,用户可以在任意位置删除、添加新的字符。
      5 m2 r  s/ V/ R0 }8 q- b( K0 E
    在解决这个问题后,我觉得潜意识挺重要的,因为当时这个功能要在三天之内完成嘛,到了第二天标准下班时间时我还没弄出来,晚上10点多下班后,还是没有进展。当时,就紧张了,因为我没有解决这个问题,那我就成为了问题了撒。穷则变嘛,后面机智的我果断决定用最熟悉的笨方法解决,下班后我就一直在思考这个用textview的代理方法该怎么搞,结果第三天早晨我醒的特别早,并且一醒来还在想那个问题,那睁开眼睛的情形宛如电视剧男主角失忆后第一次睁开眼,好帅的感觉,O(∩_∩)O哈哈~。洗完脸后,我深深的体会到了那句话:每天叫醒你的不只是闹钟,还有八阿哥!!!其实,就是把问题复杂化了!!!(⊙o⊙)…
    8 S0 m& a4 P, n7 T# I& J
    原文链接:http://joakimliu.github.io/2015/08/09/Simple-implementation-for-topic/
    " t( |+ C- y( F2 m' ]7 S% w/ C
    使用道具 举报 回复
    严禁恶意灌水!!!拒绝伸手党!!!
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    ض