Skip to content

Instantly share code, notes, and snippets.

@jazzychad
Last active August 29, 2015 14:20
Show Gist options
  • Save jazzychad/b57fb7e0155ae1a7b300 to your computer and use it in GitHub Desktop.
Save jazzychad/b57fb7e0155ae1a7b300 to your computer and use it in GitHub Desktop.
ZZZTypewriterLabel
//
// ZZZTypewriterLabel.h
//
// Created by Chad Etzel on 4/30/15.
// Copyright (c) 2015 Chad Etzel, MIT License.
//
//
// The MIT License (MIT)
//
// Copyright (c) 2015 Chad Etzel
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
@protocol ZZZTypewriterLabelDelegate;
@interface ZZZTypewriterLabel : UILabel
@property (nonatomic, weak) id<ZZZTypewriterLabelDelegate> delegate;
@property (nonatomic) NSURL *typewriterSoundResourceURL; // e.g. [[NSBundle mainBundle] URLForResource:@"click" withExtension:@"wav"]
@property (nonatomic) BOOL typewriterSoundEnabled;
- (void)setTyperwriterText:(NSString *)text duration:(NSTimeInterval)duration;
- (void)setAttributedTypewriterText:(NSAttributedString *)attributedText duration:(NSTimeInterval)duration;
@end
@protocol ZZZTypewriterLabelDelegate <NSObject>
- (void)typewriterLabelDidFinishTyping:(ZZZTypewriterLabel *)label;
@optional
- (void)typewriterLabelDidTypeCharacter:(ZZZTypewriterLabel *)label;
@end
//
// ZZZTypewriterLabel.m
//
// Created by Chad Etzel on 4/30/15.
// Copyright (c) 2015 Chad Etzel, MIT License.
//
//
// The MIT License (MIT)
//
// Copyright (c) 2015 Chad Etzel
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "ZZZTypewriterLabel.h"
@implementation ZZZTypewriterLabel
{
NSTimer *_timer;
NSString *_typewriterText;
NSInteger _typewriterTextProgress;
NSAttributedString *_attributedTypewriterText;
NSInteger _attributedTypewritterTextProgress;
SystemSoundID _soundID;
}
#pragma mark - properties
- (void)setTypewriterSoundResourceURL:(NSURL *)typewriterSoundResourceURL
{
if (_typewriterSoundResourceURL != typewriterSoundResourceURL) {
AudioServicesDisposeSystemSoundID(_soundID);
_typewriterSoundResourceURL = typewriterSoundResourceURL;
if (!_typewriterSoundResourceURL) {
_soundID = 0;
} else {
AudioServicesCreateSystemSoundID((__bridge CFURLRef)_typewriterSoundResourceURL, &_soundID);
}
}
}
#pragma mark - public methods
- (void)setTyperwriterText:(NSString *)text duration:(NSTimeInterval)duration
{
[_timer invalidate];
[self setText:nil];
[self setAttributedText:nil];
_typewriterText = [text copy];
_typewriterTextProgress = 0;
NSTimeInterval timerInterval = duration / (text.length + 0.0);
_timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(__typewriterTextTimerFired:) userInfo:nil repeats:YES];
}
- (void)setAttributedTypewriterText:(NSAttributedString *)attributedText duration:(NSTimeInterval)duration
{
[_timer invalidate];
[self setText:nil];
[self setAttributedText:nil];
_attributedTypewriterText = [attributedText copy];
_attributedTypewritterTextProgress = 0;
NSTimeInterval timerInterval = duration / (attributedText.length + 0.0);
_timer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:@selector(__attributedTypewriterTextTimerFired:) userInfo:nil repeats:YES];
}
#pragma mark - private methods
- (void)__typewriterTextTimerFired:(NSTimer *)timer
{
self.text = [_typewriterText substringToIndex:_typewriterTextProgress];
_typewriterTextProgress++;
[self __playTypingSound];
if ([self.delegate respondsToSelector:@selector(typewriterLabelDidTypeCharacter:)]) {
[self.delegate typewriterLabelDidTypeCharacter:self];
}
if (_typewriterTextProgress > _typewriterText.length) {
[_timer invalidate];
_timer = nil;
[self.delegate typewriterLabelDidFinishTyping:self];
}
}
- (void)__attributedTypewriterTextTimerFired:(NSTimer *)timer
{
self.attributedText = [_attributedTypewriterText attributedSubstringFromRange:NSMakeRange(0, _attributedTypewritterTextProgress)];
_attributedTypewritterTextProgress++;
[self __playTypingSound];
if ([self.delegate respondsToSelector:@selector(typewriterLabelDidTypeCharacter:)]) {
[self.delegate typewriterLabelDidTypeCharacter:self];
}
if (_attributedTypewritterTextProgress > _attributedTypewriterText.length) {
[_timer invalidate];
_timer = nil;
[self.delegate typewriterLabelDidFinishTyping:self];
}
}
- (void)__playTypingSound
{
if (_soundID && _typewriterSoundEnabled) {
AudioServicesPlaySystemSound(_soundID);
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment