Skip to content

Instantly share code, notes, and snippets.

@thornpig
thornpig / xibInAnotherXib.m
Last active April 7, 2016 18:14
Using xib in another xib
xib does not automatically unarchive embedded xib. So simply setting a subview's class in IB to another xib's class won't work.
Need to manually load the embedded xib in -initWithCoder:.
Note that the subview object just loaded needs to be manually added to the view hirerachy.
One trick is to have a wrapper view of the subview to be embedded in the prarent xib.
The wrapper view's layout can be easily setup in the parent xib.
Then in the code, simply add the subview object to the wrapper view in -awakeFromNib:
And it's very easy to setup the subview's constraints to take up the wrapper view.
In -initWithCoder: the IBOutlets have not been connected, so any IBOutlet property is nil in -initWithCoder:
@thornpig
thornpig / resizeTableViewFooter.m
Last active April 5, 2016 00:34
Resize tableView footer view
//update footer view's frame
-(void)updateFrame
{
CGSize newSize = [self systemLayoutSizeFittingSize: CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX)];
CGRect newFrame = self.frame;
newFrame.size = newSize;
self.frame = newFrame;
}
//when updating footer, need to call tableFooterView's setter in tableView to invoke resetting the tableview's contentView bounds
@thornpig
thornpig / gist:56f2337658af4a480075
Created March 12, 2016 01:20
If UIButton blinks on title change
[UIView setAnimationsEnabled: NO];
[button setTitle: @"New Title" forState:UIControlStateNormal];
[button layoutIfNeeded]; //why is this needed?
[UIView setAnimationsEnabled: YES];
@thornpig
thornpig / gist:27676620e2a2b3f89bb9
Last active June 12, 2016 20:39
initWithNibName: vs initWithCoder: for UIVIewController
[UIViewController initWithNibName:] is only used when the view controller is created directly in code instead of in storyboard.
The nib file with the nib name if actually for the view of the controller (in fact there is no option for view controller when creating new User Interface file in Xcode),
so unarchiving the nib file will call
[UIView initWithCoder:] instead of [UIViewController initWithCoder:].
The unarchiving will only be triggered when the view property
of the view controller is accessed for the first time, because [UIView initWithCoder:] is called by [UIViewController loadView].
On the other hand, when UIViewController is created in storyboard, either automatically by storyboard or manually by calling
[UIStoryboard instantiateViewControllerWithItentifier:],
[UIViewController initWithCoder:] will be called to unarchive the view controller object from the storyboard.
@thornpig
thornpig / gist:5eacf1a107256d195763
Created February 17, 2016 01:25
UIGestureRecognizer block touches to the touched view by default
For example, tap gesture is often added to root view to dismiss keyboard on tap on the screen.
If the root view contains a table view, the tap gesture will block tap on the cell,
so didselectrowatindexpath will never be called. To let the gesturerecognizer pass touches to the view, add
gestureRecognizer.cancelsTouchesInView = NO; //default value is YES.
@thornpig
thornpig / gist:21bff0fbb078e3a8e5ca
Created February 9, 2016 18:12
Find index of tapped character in UILabel
-(NSInteger)indexOfTappedCharacterWithTapGesture:(UITapGestureRecognizer *)tapGesture
{
CGPoint location = [tapGesture locationInView:self];
// init text storage
NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString: self.attributedText];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
// init text container
@thornpig
thornpig / gist:69d431f76eb1b0dfc063
Created February 8, 2016 19:05
Detect pressing backspace in textview
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if (text.length == 0 && range.length == 1)
{
//backspace is pressed
}
}
@thornpig
thornpig / gist:818fc7a814942148e53c
Created February 4, 2016 00:56
DIable/enable "relative to margin" when creating constraint with visual format language
Relative to margin
@"V:|-[subview]-|"
Relative to border
@"V:|-0-[subview]-0-|"
@thornpig
thornpig / gist:215990f2f3f4349f41f1
Created February 2, 2016 20:57
Force early layout with layoutIfNeeded if the some frame information is needed before the drawing cycle begins.
-(void)viewWillAppear:(BOOL)animated
{
//force the layout before the drawing cycle begins, so that when the tableview setup its cells the subviews of the cell
already have the frame information of the cell. For example, with this line, the text view inside the cell can use
the cell width to calculate depth to accormodate its text.
[self.view layoutIfNeeded];
[self.tableView reloadData];
}
@thornpig
thornpig / gist:8daeba3a42935718d8e7
Last active January 26, 2016 04:34
Make sure reused cell presents the right picture with GCD
id imageSource = cell.imageSource;
dispatch_async(queue, ^{
//block captures imageSource
UIImage *thumbNail = getImageFromSource(imageSource);
dispatch_sync(dispatch_get_main_queue(), ^{
//block captures cell
//if imageSource does not match cell.imageSource, it means the cell is resued before the background thread returns the image,
// and the image requested for the already invisible cell may be returned after the current cell obtains its image, in which case
// the returned image should not be used.
if ([imagaeSource isEqualToArray: cell.imageSource])