2
votes

I have a template quiz application that has been on the app store in various guises for a while now, in general it receives good reviews and had no bug reports.

Recently I've had two bug reports, people using iPads with iOS 8.1.2 or 8.1.3, saying that now and again the UITextView that I use to show the questions is blank.

I've not been able to replicate this bug, but I would be grateful if someone could shed some light on it.

The objects questions and userAnswer are not nil so it is definitely a UITextView issue.

The Controller is here:

@interface ReviewController ()
@property (strong, nonatomic) IBOutlet UITextView *output;

@end

@implementation ReviewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setReviewText];
   // Do any additional setup after loading the view.
}

-(void)setReviewText{

    NSArray* questions = [[NSArray alloc] init];
    questions = [_manager getAllQuestions];
    NSMutableArray* userAnswer = [[NSMutableArray alloc] init];
    userAnswer = [self answersAttributed];

    if(questions == nil)
        _output.text = @"Questions Error";

    if (userAnswer == nil)
    {
        _output.text = @"Error";
    }

    NSMutableAttributedString *mutableAttString = [[NSMutableAttributedString alloc] init];

    int i = 0;
    NSAttributedString *linebreak =[[NSAttributedString alloc] initWithString:@"\n"];
    for (Question* q in questions)
    {
        if (i == [userAnswer count])
            break;

        NSAttributedString *qtext =[[NSAttributedString alloc] initWithString:q.questionText];
        NSAttributedString *ctext =[[NSAttributedString alloc] initWithString:@"Correct Answer:\n"];

        NSAttributedString *atext =[[NSAttributedString alloc] initWithString:q.answerText];
        NSAttributedString *ytext =[[NSAttributedString alloc] initWithString:@"Your Answer:\n"];
        NSAttributedString *utext =[[NSAttributedString alloc] initWithAttributedString:userAnswer[i]];
        [mutableAttString appendAttributedString:qtext];
        [mutableAttString appendAttributedString:linebreak];
        [mutableAttString appendAttributedString:ctext];
        [mutableAttString appendAttributedString:atext];
        [mutableAttString appendAttributedString:linebreak];
        [mutableAttString appendAttributedString:ytext];
        [mutableAttString appendAttributedString:utext];
        [mutableAttString appendAttributedString:linebreak];
        [mutableAttString appendAttributedString:linebreak];
        i++;
    }
    NSAttributedString* outText = [[NSAttributedString alloc] init];
    outText = [mutableAttString mutableCopy];
    _output.attributedText = outText;
    [_output setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]];
}


-(NSMutableArray*)answersAttributed
{
    NSMutableArray* ansAtt = [[NSMutableArray alloc] init];
    NSArray* questions = [[NSArray alloc] init];
    questions = [_manager getAllQuestions];

    NSArray* userAnswers = [[NSArray alloc] init];
    userAnswers = [_manager getAllUserAnswers];


    if ([questions count] != [userAnswers count])
    {
        return ansAtt;
    }


    int i = 0;
    for (NSString* userAnswer in userAnswers )
    {
        if([[questions[i] answerText] isEqualToString:userAnswer] )
        {
            NSDictionary *attributes = @{NSBackgroundColorAttributeName:[UIColor greenColor]};
            NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:userAnswer attributes:attributes];
            [ansAtt addObject:attrString];
        }
        else
        {
            NSDictionary *attributes = @{NSBackgroundColorAttributeName:[UIColor redColor]};
            NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:userAnswer attributes:attributes];
            [ansAtt addObject:attrString];

        }
        i++;
    }

    return ansAtt;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"review2results"])
    {
        // Get reference to the destination view controller
        ReviewController *vc = [segue destinationViewController];

        // Pass any objects to the view controller here, like...
        [vc setManager:_manager];
    }
}
2
Are you using AutoLayout? It might be related to rotation - say if you rotate the device while the question is loading?brandonscript
I am using AutoLayout, but I have the app configured to only work in portrait mode. One person said that about 50% of the time the UITextView didn't appear, it seems unlikely that they were rotating every time, but I'll ask. Thanks for the suggestion.James
Yeah, that doesn't sound likely does it!brandonscript

2 Answers

0
votes

With autolayout, if you don't have enough constraints to fully specify size and position, then sometimes you'll see and and sometimes you won't. The unspecified constraints can have random values, like 0 height or off screen position.

Check to make sure the constraints are fully specified.

0
votes

In my case textview marked as Non-Editable and Non-Selectable in Storyboard have the same strange behavior on iOS 8.1 (no problems in iOS 9+).

- (void)viewDidLoad {
    [super viewDidLoad];
    textview.attributedText = [[NSAttributedString alloc] initWithString:@"non-nil"]];
    value = textview.attributedText;
    //^ value is nil !!!
}

Fixed with this:

- (void)viewDidLoad {
    [super viewDidLoad];
    textview.editable = YES;
    textview.attributedText = [[NSAttributedString alloc] initWithString:@"non-nil"]];
    textview.editable = NO;
    value = textview.attributedText;
    //^ value is @"non-nil" now !!!
}