Question

In my app I update a textView programmatically. I actually loop through a dataset from a SQLITE3 DB and show a specific text for a given time. Then I would like to show the text from the next dataset record and so forth. I have been browsing through all kind of forums and the apple doc as well, but could not find anything like a repaint, refresh, updateTextView or so command. I am dealing with long strings, why I thought the UITextView would be the best way to display. However, if another UI Class, like the UITextField or UILabel would be better and easier to achieve what I am looking for, I would also use that. No problem.

Was it helpful?

Solution

What exactly is your question?

Are you asking how to set text in a UITextView? Just use its text property:

someTextView.text = @"Some Text";

Are you asking if it's "better" to use a UILabel or UITextField? That's a subjective question. It depends on how your app is designed and what makes the most sense for presenting textual information. (Presenting formatted HTML in a UIWebView is another option.)

Once you set the text of any of these built-in classes, it will know to update/redraw itself. You don't need to set text and then trigger the redrawing or "repainting" manually.

OTHER TIPS

You can force a UITextField to repaint its text by setting its text color:

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

The color doesn't need to be different, it simply needs to be a new UIColor instance. The above code will do this. Forcing a repaint can be useful if you have overridden drawTextInRect: and want to change the appearance of the text without changing the text itself.

For performance reasons, calling [textField setNeedsDisplay] will not repaint (or call drawTextInRect:) if the text has not changed.

I was struggling with updating multiline UITextView myself, and I found a solution from the answer of "Phil Calvin"

In my case I used textView.textColor = [UIColor blackColor];

So, here's some more context that may help you in your task...

- (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);
                              }];
                         });
      }];
}           

Does [myTextView setNeedsDisplay]; work? That is the traditional way to tell an iOS UIView that it needs to see about redrawing itself. The UIView documentation contains some good information on that.

Ok I got the solution now. As always, it is pretty simple as soon as you know how :-) As it seems, that I was not very clear on my initial problem description, here the feature description again: I needed my app to display text from my SQLITE3 database in a UITextView and update that text every 2 seconds with the text from the next record in the DB. So my initial thought was to do it within the Select loop. With the hint of shaggy, that it the view will not be updated, before finishing the loop as it is running in a single thread, I started to look for another solution and came up with the following selector based solution, which works fantastic.

The solution to such a programatic and iterative update of any object in the user interface is a method like this

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

}

This method in my case is invoked when the user touches a UIButton. To make the schedule stop, it is required to send the following message to the timer instance:

        [timer invalidate];

Of course I had to change my code a bit to run with the scheduled timer, but from an iteration perspective, the above code is everything you need to trigger and stop a scheduler. Hope that this helps others with a similar issue too.

Cheers, René

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top