【问题标题】:How to repaint a UITextView for iPhone 3.x after updating data programmatically以编程方式更新数据后如何为 iPhone 3.x 重新绘制 UITextView
【发布时间】:2011-04-13 10:35:32
【问题描述】:

在我的应用程序中,我以编程方式更新了 textView。实际上,我遍历 SQLITE3 DB 中的数据集并显示给定时间的特定文本。然后我想显示下一个数据集记录中的文本等等。我一直在浏览各种论坛和苹果文档,但找不到像重绘、刷新、updateTextView 等命令之类的东西。 我正在处理长字符串,为什么我认为 UITextView 将是最好的显示方式。但是,如果另一个 UI 类,如 UITextField 或 UILabel 会更好、更容易地实现我正在寻找的东西,我也会使用它。没问题。

【问题讨论】:

    标签: iphone refresh uitextview repaint


    【解决方案1】:

    [myTextView setNeedsDisplay]; 有效吗?这是告诉 iOS UIView 它需要查看重绘自身的传统方式。 UIView documentation 包含一些很好的信息。

    【讨论】:

      【解决方案2】:

      你的问题到底是什么?

      您是在问如何在UITextView 中设置文本?只需使用它的text 属性:

      someTextView.text = @"Some Text";
      

      您是在问使用UILabel 还是UITextField 是否“更好”?这是一个主观的问题。这取决于您的应用程序是如何设计的,以及最适合呈现文本信息的方式。 (在 UIWebView 中显示格式化的 HTML 是另一种选择。)

      一旦你设置了这些内置类的文本,它就会知道自己更新/重绘。您无需设置文本,然后手动触发重绘或“重绘”。

      【讨论】:

      • 抱歉,我的问题好像不太清楚。 samkass 明白了这一点,因为我在 UITextView 上尝试了 setNeedsDisplay 方法。我需要这样做,因为我正在循环读取所有记录,其中包含要迭代显示的文本块,这里的代码 sn-p: while(sqlite3_step(selectstmt) == SQLITE_ROW) { self.myText1 = [NSString stringWithUTF8String: (char *)sqlite3_column_text(selectstmt, 0)]; self.myTextView1.text = self.question; [self.myTextView1 setNeedsDisplay]; }
      • 顺便说一句:setNeedsDisplay 不起作用,无法回答 samkass 问题。仅显示第一条记录和最后一条记录。即使我将 setNeedsDisplay 消息发送到 UITextView,它也不会更新循环内的显示。
      • 就像我说的,一旦你有了self.myTextView1.text = self.question;myTextView1 已经被标记为需要更新它的显示,所以[self.myTextView1 setNeedsDisplay]; 什么都不做。我想您要问的是“当我在循环中设置UITextFieldtext 属性时,为什么不更新显示?”答案是“UI 在单线程上运行,所以在你完成循环之前,它根本没有机会更新 UI”
      • 好的,理解并且实际上完全有道理。在这种情况下将返回并检查另一种解决方案。我实际上在考虑是否可以使用选择器解决这个问题,因为我还需要应用程序等待一段时间才能在 UITextView 中显示下一个文本。不管怎么说,还是要谢谢你。干杯,勒内
      【解决方案3】:

      好的,我现在得到了解决方案。与往常一样,只要您知道如何操作,它就非常简单:-) 看来,我最初的问题描述不是很清楚,这里再次描述功能: 我需要我的应用程序在 UITextView 中显示我的 SQLITE3 数据库中的文本,并使用数据库中下一条记录中的文本每 2 秒更新一次该文本。所以我最初的想法是在 Select 循环中进行。带着毛茸茸的暗示,它的视图不会被更新,在完成循环之前,因为它在一个线程中运行,我开始寻找另一个解决方案,并提出了以下基于选择器的解决方案,效果非常好。

      用户界面中任何对象的这种程序化和迭代更新的解决方案就是这样的方法

      - (IBAction)displayTextFromArray:(UIButton *)sender{
      timer = [NSTimer scheduledTimerWithTimeInterval:(2.0) target:self selector:@selector(displayText) userInfo:nil repeats:YES];    
      

      }

      在我的例子中,这个方法在用户触摸 UIButton 时被调用。要使计划停止,需要向计时器实例发送以下消息:

              [timer invalidate];
      

      当然,我必须稍微更改我的代码以使用计划的计时器运行,但从迭代的角度来看,上面的代码是触发和停止计划程序所需的一切。希望这对其他有类似问题的人也有帮助。

      干杯,勒内

      【讨论】:

        【解决方案4】:

        您可以通过设置文本颜色来强制UITextField 重新绘制其文本:

        textField.textColor = [UIColor colorWithWhite:0.0 alpha:1.0];
        

        颜色不需要不同,它只需要是一个新的UIColor 实例。上面的代码会做到这一点。如果您已覆盖 drawTextInRect: 并希望在不更改文本本身的情况下更改文本的外观,则强制重绘会很有用。

        出于性能原因,如果文本未更改,则调用 [textField setNeedsDisplay] 将不会重新绘制(或调用 drawTextInRect:)。

        【讨论】:

          【解决方案5】:

          我自己在更新多行 UITextView 时苦苦挣扎,我从"Phil Calvin" 的回答中找到了解决方案

          就我而言,我使用了textView.textColor = [UIColor blackColor];

          所以,这里有一些可以帮助您完成任务的上下文...

          - (void)textViewDidChange:(UITextView *)textView
          {  
             // ... lots of code to calculate the correct autolayout constraints & content size
             [textView setContentSize:CGSizeMake(textFitSize.width, newTextContentHeight)];
          
             [textView.superview setNeedsUpdateConstraints];
          
             [UIView animateWithDuration:0.3
                               animations:^
                               {
                                   // first apply the AutoLayout to resize the UITextView
                                   [textView layoutIfNeeded];
                                   [textView.superview layoutIfNeeded];
                               }
                               completion:^(BOOL finished)
                               {
                                   // then update the text by resetting the text colour 
                                   dispatch_async(dispatch_get_main_queue(), ^{
          
                                       [textView.textColor = [UIColor blackColor];
                                       [UIView animateWithDuration:0.3
                                            animations:^(void) {                                   
                                               // do not loose the keyboard
                                               [textView becomeFirstResponder];
                                            }
                                            completion:^(BOOL finished) {
                                               // move the cursor to the bottom of the text view
                                               textView.contentOffset = CGPointMake(0., textView.contentSize.height);
                                        }];
                                   });
                }];
          }           
          

          【讨论】:

            猜你喜欢
            • 2018-03-02
            • 1970-01-01
            • 1970-01-01
            • 2012-05-24
            • 2011-05-22
            • 1970-01-01
            • 2014-05-18
            • 2019-02-18
            • 1970-01-01
            相关资源
            最近更新 更多