This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[UIView setAnimationsEnabled: NO]; | |
[button setTitle: @"New Title" forState:UIControlStateNormal]; | |
[button layoutIfNeeded]; //why is this needed? | |
[UIView setAnimationsEnabled: YES]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-(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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text | |
{ | |
if (text.length == 0 && range.length == 1) | |
{ | |
//backspace is pressed | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Relative to margin | |
@"V:|-[subview]-|" | |
Relative to border | |
@"V:|-0-[subview]-0-|" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-(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]; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]) |