Club 15CC

iOS ~ 15CC Code

Task Code
iOS Draw a Shadow Under a UIView » Credits: 
self.layer.masksToBounds = NO;
self.layer.cornerRadius = 8; // optional
self.layer.shadowOffset = CGSizeMake(10, 10);
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 0.5;
iOS Vibrate / Buzz the iPhone Even When Not in Silent Mode » Seem like iPhone5+ might have changed the ability...
// Allocate system sound for buzz
SystemSoundID _soundID;
NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"silence" ofType:@"wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)([NSURL fileURLWithPath: soundPath]), &_soundID);

// later...
AudioServicesPlayAlertSound(_soundID);  // ...PlayAlertSound, not ...PlaySystemSound
iOS Clone a UILabel in iOS »
// Warning: Not necessarily complete, but a good start ;)

// Size & position
UILabel *clonedLbl = [[UILabel alloc] initWithFrame:sourceLbl.frame];

// Text
clonedLbl.text = sourceLbl.text;
if ([sourceLbl respondsToSelector:@selector(attributedText)]) { // iOS 6+
    clonedLbl.attributedText = sourceLbl.attributedText;
}

// Format
clonedLbl.font = sourceLbl.font;
clonedLbl.textColor = sourceLbl.textColor;
clonedLbl.textAlignment = sourceLbl.textAlignment;
clonedLbl.lineBreakMode = sourceLbl.lineBreakMode;

clonedLbl.adjustsFontSizeToFitWidth  = sourceLbl.adjustsFontSizeToFitWidth;
clonedLbl.adjustsLetterSpacingToFitWidth  = sourceLbl.adjustsLetterSpacingToFitWidth;
clonedLbl.baselineAdjustment  = sourceLbl.baselineAdjustment;
clonedLbl.minimumFontSize = sourceLbl.minimumFontSize;    // deprecated in iOS6
clonedLbl.minimumScaleFactor  = sourceLbl.minimumScaleFactor;
clonedLbl.numberOfLines = sourceLbl.numberOfLines;

clonedLbl.shadowColor = sourceLbl.shadowColor;
clonedLbl.shadowOffset = sourceLbl.shadowOffset;
clonedLbl.backgroundColor = sourceLbl.backgroundColor;
clonedLbl.highlighted = sourceLbl.highlighted;
clonedLbl.highlightedTextColor = sourceLbl.highlightedTextColor;

clonedLbl.enabled = sourceLbl.enabled;
clonedLbl.userInteractionEnabled = sourceLbl.userInteractionEnabled;
clonedLbl.preferredMaxLayoutWidth = sourceLbl.preferredMaxLayoutWidth;
iOS Get the Default Output Stream Format for an Audio Unit in iOS »
AudioComponentDescription inputDescription = {0};
inputDescription.componentType = kAudioUnitType_Output;
inputDescription.componentSubType = kAudioUnitSubType_RemoteIO;
inputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;

// Get component
AudioUnit inputUnit;
size_t s = sizeof(AudioStreamBasicDescription);
AudioComponent inputComponent = AudioComponentFindNext(NULL, &inputDescription);
AudioComponentInstanceNew(inputComponent, &inputUnit);

// Read the stream format
AudioStreamBasicDescription asbd;
AudioUnitGetProperty(inputUnit,
                     kAudioUnitProperty_StreamFormat,
                     kAudioUnitScope_Output,
                     0,
                     (void *)&asbd,
                     &s);

// Inspect with debugger, etc...
iOS Get iPhone/iPad Screen Dimensions »
CGSize screenSize = UIScreen.mainScreen.applicationFrame.size;
iOS Present Your UIView Subview With a 3D Flip »
// Somewhere in your UIView...
self.layer.transform = CATransform3DMakeRotation(-90.0f*M_PI/180.f, 1.0, 1.0, 0.0); // start: hidden at 90deg
CATransform3D trans3D = CATransform3DMakeRotation(0.0f*M_PI/180.f, 1.0, 1.0, 0.0); // end: angle and rotation vector (axis)
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
transformAnimation.removedOnCompletion = NO;
transformAnimation.toValue = [NSValue valueWithCATransform3D:trans3D];
transformAnimation.fillMode = kCAFillModeForwards;
[self.layer addAnimation:transformAnimation forKey:@"transform"];
iOS Convert a Float to a Price in a Specific Locale with NSNumberFormatter »
float newPrice = 1234.56;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterCurrencyStyle;
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en-GB"];
myLabel.text = [formatter stringFromNumber:@(newPrice)];
iOS Play a Short Sound / Audio Clip on iOS – 2 Ways »
// Cocoa-style:  AVAudioPlayer
#import <AVFoundation/AVFoundation.h>
clickSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSBundle.mainBundle URLForResource:@"click" withExtension:@"mp3"] error:NULL];
clickSound.volume = 0.5;
[clickSound playAtTime:0];  // OR...
clickSound.currentTime = 0;
[clickSound play];

// Cocoa-style:  AVPlayer
#import <AVFoundation/AVFoundation.h>
clickSound = [AVPlayer playerWithURL:[NSBundle.mainBundle URLForResource:@"click" withExtension:@"mp3"]];
// Note, no volume on this :(
clickSound seekToTime:CMTimeMake(0,1)];   // rewind if play occurs repeatedly and loading is only on init
[clickSound play];

// Core Foundation style
#import <AudioToolbox/AudioToolbox.h>
AudioServicesCreateSystemSoundID(.... URL ...., &mySound);
AudioServicesPlaySystemSound(mySound);
AudioServicesDisposeSystemSoundID(mySound);
iOS Implement a Custom Back Button in your UINavigationController »
// Within your child VC which is about to be pushed
UIImage *btnImgOff = [UIImage imageNamed:@"back_button_off"];
UIImage *btnImgOn = [UIImage imageNamed:@"back_button_on"];    
UIButton *backBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, btnImgOff.size.width, btnImgOff.size.height)];
[backBtn setBackgroundImage:btnImgOff forState:UIControlStateNormal];
[backBtn setBackgroundImage:btnImgOn forState:UIControlStateHighlighted]; // optional
[backBtn addEventHandler:^(id sender) {
    [self.navigationController popViewControllerAnimated:YES];
} forControlEvents:UIControlEventTouchUpInside];

self.navigationItem.hidesBackButton = YES;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
iOS Rotate a UIView (2D) »
view.transform = CGAffineTransformMakeRotation(angleClockwise);
Objective-C Add Ivars & Properties to an Objective-C Category via Runtime »
/// An sort-of hack (not that bad really) for adding ivars and properies to Categories 

// .h file
@interface UIView (Marshmallows)
@property (nonatomic) CGFloat rotation;
@end

// .m file
#import <objc/runtime.h>

/// Key for objc_*AssociatedObject functions
static char _rotation;

@implementation UIView (Marshmallows)

- (CGFloat)rotation
{
    // Convert from object
    NSNumber *n = objc_getAssociatedObject(self, &_rotation);
    return n.floatValue;
}

- (void)setRotation:(CGFloat)rotation
{
    CGFloat delta = rotation - _rotation;
    self.transform = CGAffineTransformMakeRotation(delta);

    // Must convert to an object for this trick to work
    objc_setAssociatedObject(self, &_rotation, @(rotation), OBJC_ASSOCIATION_COPY);
}

@end
iOS Get a String of a Number Rounded to a Decimal Place in Cocoa/iOS »
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
nf.maximumFractionDigits = 1;
aLabel.text = [nf stringFromNumber:@(sender.value)];
iOS AFConvert a Batch of Audio Files Replacing Originals in Shell »
# WAVE 16bit Stereo LEI...Careful!
ls | xargs -I {} afconvert -d LEI16@44100 -c 2 -f 'WAVE' {} -o {}
iOS Check Supported File Container (AudioFileTypeId) and Format (ASBD.mFormatID) Combinations in Core Audio »
void AUM_printAvailableStreamFormatsForId(AudioFileTypeID fileTypeID, UInt32 mFormatID)
{
    AudioFileTypeAndFormatID fileTypeAndFormat;
    fileTypeAndFormat.mFileType = fileTypeID;
    fileTypeAndFormat.mFormatID = mFormatID;
    UInt32 fileTypeIDChar = CFSwapInt32HostToBig(fileTypeID);
    UInt32 mFormatChar = CFSwapInt32HostToBig(mFormatID);

    OSStatus audioErr = noErr;
    UInt32 infoSize = 0;
    audioErr = AudioFileGetGlobalInfoSize(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat,
                                          sizeof (fileTypeAndFormat),
                                          &fileTypeAndFormat,
                                          &infoSize);
    if (audioErr != noErr) {
        UInt32 format4cc = CFSwapInt32HostToBig(audioErr);
        NSLog(@"-: fileTypeID: %4.4s, mFormatId: %4.4s, not supported (%4.4s)",
              //i,
              (char*)&fileTypeIDChar,
              (char*)&mFormatChar,
              (char*)&format4cc
              );

        return;
    }

    AudioStreamBasicDescription *asbds = malloc (infoSize);
    audioErr = AudioFileGetGlobalInfo(kAudioFileGlobalInfo_AvailableStreamDescriptionsForFormat,
                                      sizeof (fileTypeAndFormat),
                                      &fileTypeAndFormat,
                              	        &infoSize,
                                      asbds);
    if (audioErr != noErr) {
        UInt32 format4cc = CFSwapInt32HostToBig(audioErr);
        NSLog(@"-: fileTypeID: %4.4s, mFormatId: %4.4s, not supported (%4.4s)",
              //i,
              (char*)&fileTypeIDChar,
              (char*)&mFormatChar,
              (char*)&format4cc
              );

        return;
    }

    int asbdCount = infoSize / sizeof (AudioStreamBasicDescription);
    for (int i=0; i<asbdCount; i++) {
        UInt32 format4cc = CFSwapInt32HostToBig(asbds[i].mFormatID);

        NSLog(@"%d: fileTypeID: %4.4s, mFormatId: %4.4s, mFormatFlags: %ld, mBitsPerChannel: %ld",
              i,
              (char*)&fileTypeIDChar,
              (char*)&format4cc,
              asbds[i].mFormatFlags,
              asbds[i].mBitsPerChannel);
    }

    free (asbds);
}

int main (void)
{
    NSLog(@"********* CAF ***********");
    AUM_printAvailableStreamFormatsForId(kAudioFileCAFType, kAudioFormatAppleIMA4);
    AUM_printAvailableStreamFormatsForId(kAudioFileCAFType, kAudioFormatAC3);
    AUM_printAvailableStreamFormatsForId(kAudioFileCAFType, kAudioFormatMPEG4AAC);
    AUM_printAvailableStreamFormatsForId(kAudioFileCAFType, kAudioFormatAppleLossless);

    NSLog(@"********* AIFF ***********");
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFFType, kAudioFormatLinearPCM);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFFType, kAudioFormatAppleIMA4);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFFType, kAudioFormatAC3);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFFType, kAudioFormatMPEG4AAC);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFFType, kAudioFormatAppleLossless);

    NSLog(@"********* M4A ***********");
    AUM_printAvailableStreamFormatsForId(kAudioFileM4AType, kAudioFormatAppleIMA4);
    AUM_printAvailableStreamFormatsForId(kAudioFileM4AType, kAudioFormatAC3);
    AUM_printAvailableStreamFormatsForId(kAudioFileM4AType, kAudioFormatMPEG4AAC);
    AUM_printAvailableStreamFormatsForId(kAudioFileM4AType, kAudioFormatAppleLossless);

    NSLog(@"********* AAC_ADTS ***********");
    AUM_printAvailableStreamFormatsForId(kAudioFileAAC_ADTSType, kAudioFormatLinearPCM);
    AUM_printAvailableStreamFormatsForId(kAudioFileAAC_ADTSType, kAudioFormatAppleIMA4);
    AUM_printAvailableStreamFormatsForId(kAudioFileAAC_ADTSType, kAudioFormatAC3);
    AUM_printAvailableStreamFormatsForId(kAudioFileAAC_ADTSType, kAudioFormatMPEG4AAC);
    AUM_printAvailableStreamFormatsForId(kAudioFileAAC_ADTSType, kAudioFormatAppleLossless);

    NSLog(@"********* AIFC ***********");
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFCType, kAudioFormatLinearPCM);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFCType, kAudioFormatAppleIMA4);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFCType, kAudioFormatAC3);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFCType, kAudioFormatMPEG4AAC);
    AUM_printAvailableStreamFormatsForId(kAudioFileAIFCType, kAudioFormatAppleLossless);
}
iOS Manually Load a ViewController With a Custom NIB at App Launch in iOS »
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // For those times when you decide to revert back from the Storyboard...
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    self.mainViewController = [MyCustomViewController alloc] inintWithNibName:@"MyCustomViewNib" bundle:nil];

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}
iOS Instantiate an Audio Unit Without an AUGraph in iOS »
    AudioComponentDescription desc = self._audioComponentDescription;
    AudioComponent comp = AudioComponentFindNext(NULL, &desc);
    _(AudioComponentInstanceNew(comp,
                                &_audioUnitRef),
      kAUMAudioUnitException,
      @"Error creating new instance (no graph)");

    _(AudioUnitInitialize(_audioUnitRef),
      kAUMAudioUnitException,
      @"Error initialising new unit instance (no graph)");
Objective-C Block-based NSNotifications with ‘self’ without creating a circular reference (retain cycle) under ARC »
- (void)setupNotification {

    // Prevents a circular reference. Otherwise dealloc will never be called
    __weak SWAnalytics *weakSelf = self;

    [[NSNotificationCenter defaultCenter]
     addObserverForName:UIApplicationDidEnterBackgroundNotification
     object:nil
     queue:[NSOperationQueue mainQueue]
     usingBlock:^(NSNotification *n) {

        [weakSelf doSomething];

     }];
}

- dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
iOS NSDate Comparisons and Maths »
// dateA < dateB
if ([dateA compare:dateB] == NSOrderedAscending) { ... }

// dateA > dateB
if ([dateA compare:dateB] == NSOrderedDescending) { ... }

// dateA == dateB
if ([dateA compare:dateB] == NSOrderedSame) { ... }

// dateA <= dateB
if ([dateA compare:dateB] != NSOrderedDescending) { ... }

// dateA >= dateB
if ([dateA compare:dateB] != NSOrderedAscending) { ... }

// dateA is before NOW
if ([dateA compare:[NSDate date]] == NSOrderedAscending) { ... }

// Time lapsed (positive) since dateA in the past and NOW.
NSTimeInterval timeLapsed = -1 * [dateA timeIntervalSinceNow];
iOS Remove a subview from a UIView »
UIView *v = [self.subviews objectAtIndex:1];
[v removeFromSuperview];
iOS Crossfade Multiple UIViews with Block-based Animations » Don't get too smart with completions. UIView...
// Nothing to do if it's already the active one
if (activeIndex == theIdx)
    return;    

// Hide immediately all lagging animations and
// fade out the visible one if any
for (int i=0; i
iOS Temporarily remove an implicit animation on a CALayer object » `action` is empty initially which uses the UIKit...
// Turn off the implicit animation for the touchHint layer
NSMutableDictionary *actions = [NSMutableDictionary dictionaryWithDictionary:touchHint.actions];
[actions setObject:[NSNull null] forKey:@"position"];
touchHint.actions = actions;

// Restore the implicit animation
NSMutableDictionary *actions = [NSMutableDictionary dictionaryWithDictionary:touchHint.actions];
[actions removeObjectForKey:@"position"];
touchHint.actions = actions;