Wednesday, 23 April 2014

Text to Speech in iOS7

iOS7 makes Text to Speech really easy and that also in multiple languages.
iOS7 has added two new classes for Text to Speech functionality:
1. AVSpeechSynthesizer
2. AVSpeechUtterance

First Link AVFoundation and AudioToolbox Framework from Application Target -> Build Phases -> Link Binary With Libraries.

Import both frameworks in Header file (.h file)
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

add delegate <AVSpeechSynthesizerDelegate>.

In implementation file (.m file)
    AVSpeechSynthesizer *speechSynthesizer = [[AVSpeechSynthesizer alloc] init];
    AVSpeechUtterance *speechUtterance = [AVSpeechUtterance speechUtteranceWithString:@"Welcome to iOS App."];
    speechUtterance.rate = AVSpeechUtteranceMaximumSpeechRate / 4.0f;
    speechUtterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"]; // language
    [speechSynthesizer speakUtterance: speechUtterance];

By adding the above code you can add text to speech functionality to your iOS7 app.

Display HTML in NSAttributedString in iOS7

iOS7 has really added some best things like displaying HTML in NSAttributedString.
Suppose in a case you want to display some HTML in your UITextView from any website.
Just pass the HTML to NSAttributedString and set this attributed string to the UITextView and that's it, you are done.

In below snippet i have passed the html string from my blog site to NSAttributedString and this NSAttributedString is set to UITextView.
Now the html from my blog site will be displayed in the UITextView along with clickable links.

      NSString *strHtml = [NSString stringWithContentsOfURL:[NSURL   URLWithString:@"http://objectivecwithsuraj.blogspot.in/"] encoding:NSUTF8StringEncoding error:nil];
    
    NSAttributedString *attrStrWithHtml = [[NSAttributedString alloc] 
                   initWithData:[strHtml dataUsingEncoding:NSUTF8StringEncoding]
                   options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                                               NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
                   documentAttributes:nil error:nil];
    
    UITextView *textView = [[UITextView alloc] initWithFrame:self.view.frame];
    [textView setAttributedText: attrStrWithHtml];
    [textView setDataDetectorTypes:UIDataDetectorTypeLink];
    [textView setEditable:NO];
    [self.view addSubview:textView];

Wednesday, 9 April 2014

Calculating Height of UITextView in iOS7



Many times in application we need to calculate height of UITextView to make it grow and shrink according to the text contained within it.

Now many of you will say calculating height of UITextView is not a big deal.

Yes its true for iOS6 and below version. But not true from iOS7 and higher.

In iOS6 we can get height of a UITextView simply using the contentSize.

eg.

  [myTextView setText:@"here goes my text"];

  CGFloat heightOfTextView = myTextView.contentSize.height;


In iOS7 may be it's a bug or due to deprecation, contentSize does not provide you the accurate height of the UITextView.

So below is the code snippet i used in my application for getting the height of UITextView:

Just set text NSString to UITextView and call this method sending UITextView as parameter


  [myTextView setText:@"here goes my text"];

  [self measureHeightOfUITextView: myTextView];


- (CGFloat)measureHeightOfUITextView:@"here goes my text"];​(UITextView *)textView

{

    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)

    {

        // This is the code for iOS 7. contentSize no longer returns the correct value, so

        // we have to calculate it.

        CGRect frame = textView.bounds;

        // Take account of the padding added around the text.​

        UIEdgeInsets textContainerInsets = textView.textContainerInset;

        UIEdgeInsets contentInsets = textView.contentInset;

        CGFloat leftRightPadding = textContainerInsets.left + textContainerInsets.right + textView.textContainer.lineFragmentPadding * 2 + contentInsets.left + contentInsets.right;

        CGFloat topBottomPadding = textContainerInsets.top + textContainerInsets.bottom + contentInsets.top + contentInsets.bottom;

        frame.size.width -= leftRightPadding;

        frame.size.height -= topBottomPadding;

        NSString *textToMeasure = textView.text;

        if ([textToMeasure hasSuffix:@"\n"])

        {

            textToMeasure = [NSString stringWithFormat:@"%@-", textView.text];

        }       

        // NSString class method: boundingRectWithSize:options:attributes:context is

        // available only on ios7.0 sdk.

        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

        [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];

        NSDictionary *attributes = @{ NSFontAttributeName: textView.font, NSParagraphStyleAttributeName : paragraphStyle };

        CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT)

                                                  options:NSStringDrawingUsesLineFragmentOrigin

                                               attributes:attributes

                                                  context:nil];

        CGFloat measuredHeight = ceilf(CGRectGetHeight(size) + topBottomPadding);

        return measuredHeight;

    }

    else

    {

        return textView.contentSize.height;

    }

}



I got help from below links for above code snippet:
Link 1
Link 2