ioscodesnippet
ioscodesnippet
iOS Code Snippet
19 posts
iOS Code Snippet has moved to a new homepage: http://ioscodesnippet.com
Don't wanna be here? Send us removal request.
ioscodesnippet · 12 years ago
Photo
Tumblr media
ioscodesnippet.com has been redesigned with new features!
New CocoaPods integration
Quick Installation section
Responsive design
Go and checkout the new ioscodesnippet.com now :)
1 note · View note
ioscodesnippet · 12 years ago
Link
Sometimes you're wondering what are stored in an NSCoder instance?
Here's a little utility exactly for this purpose, I called it UINibDecoderProxy. This is how you use it:
#import "UINibDecoderProxy.h" // Then override initWithCoder: - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:[[UINibDecoderProxy alloc] initWithTarget:aDecoder]]; return self; }
Now go to UINibDecoderProxy.m and set a break point at -[UINibDecoderProxy forwardInvocation:] and log the necessary information for you. Notice at the inline comment below:
Hopefully not too tricky.
1 note · View note
ioscodesnippet · 12 years ago
Text
Using custom drop shadows in UINavigationBar (fix for iOS 6.1)
This is an update to the Adding Drop Shadow on UINavigationBar which was written prior to iOS 6.0
Since iOS 6.0 Apple introduced the -[UINavigationBar shadowImage] property. We should probably leverage that, which are also UIAppearance selectors.
// Configure your images UIImage *background = [UIImage imageNamed:@"titlebar44"]; UIImage *shadow = [UIImage imageNamed:@"titlebar-bottom-highlight"]; // Using the appearance proxy // Note: setBackgroundImage:forBarMetrics has been documented to be // **compulsory** to enable the displaying of the custom shadow image. [[UINavigationBar appearance] setBackgroundImage:background forBarMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setShadowImage:shadow];
You probably went with similar code, but the custom shadow just didn't show up, right?
The problem occurs because of the implementation on UINavigationBar, the clipsToBounds property is needed to be set to NO, and this step has been missing from the documentation. (At least I didn't find it)
Most probably you'll need to set self.navigationController.navigationBar.clipsToBounds = NO in every UIViewController subclass you wrote, a more convenience way is to subclass UINavigationController and have it do the job for you. And I've created a snippet for you.
So now you can initialise your view controllers in code like this:
UIViewController *controller; // configure your view controller UINavigationController *navController = [[JTDropShadowFixNavigationViewController alloc] initWithRootViewController:controller];
Or if you use storyboard, simply change the subclass of your UINavigationController to JTDropShadowFixNavigationViewController.
Tumblr media
In fact there's an even simpler method you'll notice in the snippet.
This is a hack that adds a category method to always set clipsToBounds to NO for UINavigationBar. Enable it defining this constant somewhere in your code (recommended in .pch):
#define ENABLE_JTDROPSHADOW_GLOBAL_FIX 1
Let me know your thoughts!
0 notes
ioscodesnippet · 12 years ago
Text
Revisiting KVO+Block, the simplest version.
There have been a good number of attempts solving the "broken" Key Value Observing official API.
And we get solutions like custom notification centre replacement, extra target-action based observation, handly marcos, trampoline...?, mixin context for selector, wah, and one that can't even find the link to the repo, etc.
But come on, just because I need to subclass one 3rd party library that already implements the -[NSObject observeValueForKeyPath:ofObject:change:context:]... all I want is a tiny wrapper that allows me stay away from that method.
I don't want any overheads to the base NSObject due to custom category methods; I don't want solutions hacking around with associative objects, I just want a just enough solution for that particular hassle, please...
To remove observer earlier? Just nil the properly, you know ;P
1 note · View note
ioscodesnippet · 12 years ago
Text
Method Swizzling in Objective-C
There are many reasons for you to use method swizzling, even if it's considered [harmful][1] and [dangerous][2]. Despite it's flaws, this little technique can be so powerful and let you reveal secrets of iOS like [status bar is drawn by the current app][3], and replace methods in class you don't own like [customizing UINavigationBar background in old days][4] to achieve a higher level of UI customisation. So here's the base snippet: Example usage: @implementation NSParagraphStyle (JTParagraphStyleDebug) + (void)load { SwizzleInstanceMethod([self class], @selector(initWithCoder:), @selector(initWithCoderSwizzled:)); } // -[NSParagraphStyle initWithCoder:] is called when an NSAttributedString is specified in an UILabel in Interface Builder. - (id)initWithCoderSwizzled:(NSCoder *)aDecoder { self = [self initWithCoderSwizzled:(id)[[UINibDecoderProxy alloc] initWithTarget:aDecoder]]; return self; } @end Above code is extracted from [JTAttributedLabel][6] to use [UINibDecoderProxy][5] to diagnose NSAttributedString in Interface Builder. Enjoy and have a good use with it! [1]:http://zathras.de/angelweb/blog-method-swizzling-considered-harmful.htm [2]:http://stackoverflow.com/questions/5339276/what-are-the-dangers-of-method-swizzling-in-objective-c [3]:http://darkdust.net/writings/objective-c/method-swizzling [4]:http://www.andyshep.org/2011/04/12/uinavigationbar-and-method-swizzling.html [5]:https://gist.github.com/mystcolor/4466616 [6]:https://github.com/mystcolor/JTAttributedLabel
0 notes
ioscodesnippet · 13 years ago
Text
Quick hack to enable delete menu item in UITableView menuController
Tumblr media
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { NSLog(@"%@", NSStringFromSelector(action)); return YES; } - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { }
Watch carefully, there is a problem. So you found yourself returning YES for all of the actions including the delete: selector, and the delete item just doesn't show up.
To properly fix it, you should really subclass your UITableViewCell and implement your own delete: method.
But if you would like a really quick hack for all of your default tableViewCell, you can do it with category and implements the delete: method.
After the import of snippets:
// By only returning YES for delete menu item, we can get the results like the screenshot down below. - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { return action == @selector(delete:); }
Tumblr media
The category also helps you to route the delete: selector to your tableViewDelegate's tableView:performAction:forRowAtIndexPath:withSender: method, so you can handle it like all other actions.
Updated: 30 June 2012
The version you see above, I considered as a more elegant version for it's clever use of responder chain. Worth a look to the old naive version if you're digging down to the ground.
This is revised version from the old blog post.
1 note · View note
ioscodesnippet · 13 years ago
Text
Quickly switch supported UIInterfaceOrientation for your View Controllers
Tumblr media
In Xcode 4, you can simply point-and-click to specify supported orientation in your info.plist. But wait, it doesn't really make your app obey to that certain interface orientation.
You still have to implement the - [UIViewController shouldAutorotateToInterfaceOrientation:] and return a right value.
Your specified value is located in your app's info.plist, so here's the code to let you easily access that configuration.
Example usage
// In your ViewController.m subclass that you wish to just obey the specified supported orientations, // #import "UIApplicationAddition.h" - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return UIInterfaceOrientationIsSupportedOrientation(interfaceOrientation); }
Now you can just point-and-click to really change the supported orientations!
1 note · View note
ioscodesnippet · 13 years ago
Text
Adding Block support for UIControl's Target-Action mechanism
Tired of [Target-Action][2]? Welcome to the world of [blocks][1]. Sample usage: UIButton *button = ...; [button addEventHandler:^(id sender, UIEvent *event) { NSLog(@"touchedUp!"); } forControlEvent:UIControlEventTouchUpInside]; This is a very simple implementation of adding block support for UIControls. Download the snippet from [here][3], instantly saves you a few lines of code. If you are finding for a more complex block addition of everything, you maybe interested to have a look at [zwaldowski / BlocksKit][4]. [1]:http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html [2]:http://developer.apple.com/library/ios/#documentation/General/Conceptual/Devpedia-CocoaApp/TargetAction.html#//apple_ref/doc/uid/TP40009071-CH3-SW1 [3]:https://gist.github.com/2205564 [4]:https://github.com/zwaldowski/BlocksKit
5 notes · View notes
ioscodesnippet · 14 years ago
Text
Splitting an array to several components
Say you'd like to split an array into several arrays each with a specific number of components. // Say your originalArray is [@"A", @"B", @"C", @"D"] NSArray *originalArray = [NSArray arrayWithObjects:@"A", @"B", @"C", @"D", nil]; // And we now want the array to be split into two arrays with two per segment // like this [[@"A", @"B"], [@"C", @"D"]] NSArray *newArray = [NSArray splitArray:originalArray componentsPerSegment:1]; And here's the code snippet on how you can do it.
3 notes · View notes
ioscodesnippet · 14 years ago
Link
andymatuschak:
Panther introduced Key-Value Observing, a Cocoa implementation of the observer pattern. It’s very useful, but the API kind of sucks.
To get observation notices, you have to override a lengthy selector (observeValueForKeyPath:ofObject:change:context:), provide a static context pointer, and essentially implement a big switch statement on the key path.
That’s unwieldy, but I think it also makes for unmaintainable code: the callbacks end up thrown in the same method, and they’re separated from the observer registration.
KVO+Blocks is an NSObject category I wrote which provides addObserverForKeyPath:task:, where the latter parameter is a block.
So, before KVO+Blocks:
const static NSString *SomeValueObservationContext = @"org.andymatuschak.SomeValueObservationContext"; - (void)registerObservation { [observee addObserver:self forKeyPath:@"someValue" options:0 context:SomeValueObservationContext] } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == SomeValueObservationContext && [keyPath isEqualToString:@"someValue"]) { NSLog(@"someValue changed: %@", change); } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (void)dealloc { [observee removeObserver:self forKeyPath:@"someValue"]; [super dealloc]; }
And after:
- (void)registerObservation { [observee addObserverForKeyPath:@"someValue" task:^(id obj, NSDictionary *change) { NSLog(@"someValue changed: %@", change); }]; }
Note that you don’t even need to unregister your observer if you’re using GC; it’s handled for you when the observee is released. If you want to unregister early, or you’re using retain-counted code, there’s API for that too.
Blocks make life happy, ladies and gentlemen. More on this later.
Update: more notes and gotchas.
13 notes · View notes
ioscodesnippet · 14 years ago
Text
Force decompressing UIImage in background to achieve better performance
If you’ve ever experience in loading lots of image in your app from the web, and display in a list form of UIImages in a table view, you’d properly heard of doing lazy loading those images. There are several great loading and caching open source solutions you’d probably already heard of such as SDWebImage, EGOImageLoading, etc.
However, you are still experience slight UI delay when the image finished loading or caching out from the disk. The reason behind is UIKit does extra lazy initialization, and only do expensive decompressing at the time to display or draw. Here’s is code snippet meant to be load from a background thread that force an image to be decompressed into the right format, so that the system don’t have to do extra conversion on display.
So after an image has successfully loaded from the web or cached out, create an operation and decompress the image with 
[UIImage decodedImageWithImage:anImage];
And now you can achieve a smoother scrolling experience for your app. Checkout rs / SDWebImage library which already contains the optimization on github.
18 notes · View notes
ioscodesnippet · 14 years ago
Text
Adding drop shadow on UINavigationBar (before iOS 6)
We've an update on this technique for iOS 6.1, please see
Using custom drop shadows in UINavigationBar (fix for iOS 6.1)
Tumblr media
Somehow adding drop shadows on UINavigationBar using the CALayer property fails for me but I later find it out we just need a little trick there.
// The magic is to have -[UIView clipToBounds] set to NO self.navigationController.navigationBar.clipsToBounds = NO;
Base on the fact this is ioscodesnippet, I know I have to make a really simple UINavigationBar-JTDropShadow category to make our life more easier.
Usage:
- (void)viewDidLoad { [super viewDidLoad]; ... [self.navigationController.navigationBar dropShadowWithOffset:CGSizeMake(0, 3) radius:1 color:[UIColor darkGrayColor] opacity:1]; ... }
Make sure you've already imported QuartzCore.framework in your build settings.
While it is more generic by making it a UIView category, but I’ll leave it simple here to demonstrate the main purpose.
8 notes · View notes
ioscodesnippet · 14 years ago
Text
Crop an image in specific rect
You probably aware of the method CGImageCreateWithImageInRect that's already defined in the Foundation framework. It is absolute fine for developers familiar well with CoreGraphics and doesn’t mind manually taking care of the image orientations. We loved UIKit anyway.
Use this UIImage-JTImageCrop category instead.
Now you use this instead of the CoreGraphics method.
+ (UIImage *)imageWithImage:(UIImage *)image cropInRect:(CGRect)rect;
Last but not least, you’d somehow want to further abstract it with a proportional rect value. (Imagine you are defining a cropping area on the screen and want to crop a full sized image, you’d transform the visible area to the full sized photo). A handly method is also created for this purpose.
+ (UIImage *)imageWithImage:(UIImage *)image cropInRelativeRect:(CGRect)rect;
Enjoy the snippet!
13 notes · View notes
ioscodesnippet · 14 years ago
Text
Adding fadeout effect to any -[UIViews removeFromSuperview]
Typically you like to do something like below when you wanted to remove a view from its parent view.
[myView removeFromSuperview];
Sometimes it's not that please for a user to see an UI component disappearing suddenly. You'd then consider adding some transition effects, and here's a little code snippet in the UIView+JTRemoveAnimated category for how you can get a fade out effect on view removal. So from now on, you just needed to do this to fade out any UIViews
[myView removeFromSuperviewAnimated]
25 notes · View notes
ioscodesnippet · 14 years ago
Text
NSStringf. Simpler printf styled +[NSString stringWithFormat:]
If you thinks that +[NSString stringWithFormat:] is simply annoying.
If you missed the C style string formatter like printf() or NSLog().
[NSString stringWithFormat:@"Why should I type this long?"];
// // JTStringAddition.h // // Created by James Tang on 27/08/2011. // http://ioscodesnippet.tumblr.com/ // NSString *NSStringf(NSString *format, ...); // // JTStringAddition.m // // Created by James Tang on 27/08/2011. // http://ioscodesnippet.tumblr.com/ // #import "JTStringAddition.h" NSString *NSStringf(NSString *format, ...) { va_list ap; NSString *str; va_start(ap,format); str=[[NSString alloc] initWithFormat:format arguments:ap]; va_end(ap); return [str autorelease]; }
NSStringf(@"It's just so much easier. %@", @"Really.");
2 notes · View notes
ioscodesnippet · 14 years ago
Text
Rendering any UIViews into UIImage in one line
Looks like you'd like to make some snapshots of your application, or maybe capturing partial UI elements on the screen for caching or saving? You can achieve this in just one single line like this.
UIImage *viewSnapshot = [myView toImage];
Add this UIView+JTViewToImage category to your project, and you'll also needed to link <QuartzCore/QuartzCore.h> framework too.
In advance, if you want to make sure you've the exact size of the static image output, try this line instead.
UIImage *viewSnapshot = [myView toImageWithScale:1];
This will tell your app to ignore the screen scale and simply reference to the size of the view bounds.
Updated: 2013-10-14
With iOS 7 faster API, the screen capturing method is about 1.8x faster on my iPhone 5. Actual time elasped was down from 0.09s to 0.05 seconds. Clone the repository to test it in action.
43 notes · View notes
ioscodesnippet · 14 years ago
Text
Creating a placeholder UIImage dynamically with color
Ever needed a placeholder color for your lazy loaded table view cell image view? Typically can create a 1x1 pixel image in PhotoShop, add it to your project, then load it with UIImageNamed. Can't imagine how lots of effort and steps, and if the placeholder color are requested to be updated, you'd have to repeat the process all over again.
If you needed work with this kind of situations a lot, lets do it programmatically and DRY! Consider the following UIImage-JTColor category.
Usage:
#import "UIImage-JTColor.h" UIColor *color = [UIColor lightGrayColor]; // Or your whatever UIColor imageView.image = [UIImage imageWithColor:color];
Nothing magical but will saves you a lot of time.
27 notes · View notes