Consider a situation here, a 2nd layer view is pushed on top of the root view, where root view need a navigation bar and the view just pushed no need.
In root navigation viewController.m
1 2 3 4 5 6 7 8 9 10 11 12 13
- (void)viewWillAppear:(BOOL)animated { # show navigation bar when the root view is shown [self.navigationController setNavigationBarHidden:NO]; } - (IBAction)toNextView:(id)sender { # push a new view in YourViewController *controller = [[YourViewController alloc] init]; [self.navigationController pushViewController:controller animated:YES]; # hide the navigation bar [self.navigationController setNavigationBarHidden:YES]; }
#pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { // Un-focus the text field [textField resignFirstResponder]; returnYES; }
// set the delegate & dataSource to self, means have to implement in YourViewController tableView.delegate = self; tableView.dataSource = self;
[self.view addSubview:tableView]; }
... #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView { // the number of section(s) in the table return1; }
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section { // the number of row(s) in the table return1; }
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { staticNSString *cellIdentifier = @"Cell"; UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } // do some configuration like populate data to cell return cell; }
#pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Action that you want to perform when clicked on table cell }
// must be NSMutableURLRequest, NSURLRequest doesn't has setTimeoutInterval this method NSMutableURLRequest *request = [client requestWithMethod:@"GET" path:@"/foo" parameters:nil]; [request setTimeoutInterval:60];
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; self.searchBar.delegate = self; self.searchBar.placeholder = @"Search..."; // Loop through all subviews in UISearchBar for (UIView *searchBarSubview in [self.searchBar subviews]) { // Check if it is UITextField if ([searchBarSubview conformsToProtocol:@protocol(UITextInputTraits)]) { @try { // Change the title "Search" to "Done" [(UITextField *)searchBarSubview setReturnKeyType:UIReturnKeyDone]; // set the style of keyboard [(UITextField *)searchBarSubview setKeyboardAppearance:UIKeyboardAppearanceAlert]; // Enable the "Done" button eventhough no text in search bar [(UITextField *)searchBarSubview setEnablesReturnKeyAutomatically:NO]; } @catch (NSException * e) { // ignore exception } } } [self.view addSubview:self.searchBar];
// get the center coordinate CLLocationCoordinate2D centerCoor = [self.mapView centerCoordinate]; // get top left coordinate CLLocationCoordinate2D topLeftCoor = [self.mapView convertPoint:CGPointMake(0, 0) toCoordinateFromView:self.mapView];
// init locations based on coordinates CLLocation *centerLocation = [[CLLocation alloc] initWithLatitude:centerCoor.latitude longitude:centerCoor.longitude]; CLLocation *topLeftLocation = [[CLLocation alloc] initWithLatitude:topLeftCoor.latitude longitude:topLeftCoor.longitude];
// get the distance between 2 locations CLLocationDistance radius = [centerLocation distanceFromLocation:topLeftLocation];
if (radius > 0) { UIGraphicsBeginImageContext(size); // Add a clip before drawing anything, in the shape of an rounded rect [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius] addClip]; // Draw your image [img drawInRect:rect]; img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } return img; }
// options is the dataSource for the tableView for (int i = 0; i < [options count]; i++) { UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]; if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { // perform action here } }
Some time you might have some views is overlapping, when tapping a button, the 2 views will interchange, so you need to get the view’s index to do comparison.
Some time we just want to hide the keyboard when clicked on a button, but we might not know which textField is currently showing keyboard. The line below will just resign any responder.
- (UIImage *)imageFromText:(NSString *)text { // set the font type and size UIFont *font = [UIFont fontWithName:@"Helvetica" size:12]; CGSize size = [text sizeWithFont:font]; // check if UIGraphicsBeginImageContextWithOptions is available (iOS is 4.0+) if (UIGraphicsBeginImageContextWithOptions != NULL) UIGraphicsBeginImageContextWithOptions(size,NO,0.0); else // iOS is < 4.0 UIGraphicsBeginImageContext(size); // optional: add a shadow, to avoid clipping the shadow you should make the context size bigger // // CGContextRef ctx = UIGraphicsGetCurrentContext(); // CGContextSetShadowWithColor(ctx, CGSizeMake(1.0, 1.0), 5.0, [[UIColor grayColor] CGColor]); // set text color [[UIColor colorWithWhite:1 alpha:0.55] set]; // draw in context, you can use also drawInRect:withFont: [text drawAtPoint:CGPointMake(0.0, 0.0) withFont:font]; // transfer image UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
// change the font & text color [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:@"CustomFont-Bold" size:18], UITextAttributeFont, [UIColor whiteColor], UITextAttributeTextColor, // make the text FLAT [UIColor clearColor], UITextAttributeTextShadowColor, nil]]; ... }
Extract submatch from string using regular expression
Example here shows extract date from NSDate object
The format we want is YYYY-MM-DD
1 2 3
NSLog(@"date %@", date); // this will return (for example) // 2014-01-27 10:17:00 +0000
So we can extract out the part using regex
1 2 3 4 5 6 7 8 9 10 11 12 13
NSDate *date = ...;
// extract 4 integers followed by a dash followed by 2 integers followed by a dash followed by 2 integers again NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d{4}-\\d{2}-\\d{2})" options:NSRegularExpressionCaseInsensitive error:&error]; [regex enumerateMatchesInString:date.description options:0 range:NSMakeRange(0, date.description.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { // just get the substring by the range NSString *dateStr = [sender.date.description substringWithRange:[result rangeAtIndex:0]]; NSLog(@"Date only: %@", dateStr); // this will show // Date only: 2014-01-27 }];
Update
For this case, want to extract out the minutes & seconds
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
NSString *message = @"Your computer will be shutdown in 3 minutes 25 seconds";
// Only match for the minutes & seconds NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d+) minutes (\\d+) seconds" options:NSRegularExpressionCaseInsensitive error:&error]; [regex enumerateMatchesInString:date.description options:0 range:NSMakeRange(0, date.description.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
// `rangeAtIndex` 0 will be "3 minutes 25 seconds, so we don't take // `rangeAtIndex` 1 will be "3" // `rangeAtIndex` 2 will be "25" int minutes = [[message substringWithRange:[result rangeAtIndex:1]] intValue]; int seconds = [[message substringWithRange:[result rangeAtIndex:2]] intValue]; NSLog(@"%dm %ds", minutes, seconds); // 3m 25s }];
It always matches the main match then only followed by submatch
double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ //code to be executed on the main queue after delay NSLog(@"Action here delayed 2 seconds."); });
self.navigationController.navigationBar.shadowImage = [UIImage new]; // remove the inner shadow
// for iOS 7, remove the background image if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) { [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationController.navigationBar.translucent = YES; self.navigationController.view.backgroundColor = [UIColor clearColor]; } else { // for iOS 6, set the image filled with color that same as the view's background color // see https://github.com/jslim89/js-learning-journey/tree/master/programming/objective-c#create-rectangle-uiimage-programmatically [self.navigationController.navigationBar setBackgroundImage:[MyClass imageWithColor:[UIColor yellowColor] inSize:CGSizeMake(320, 44) withCornerRadius:0] forBarMetrics:UIBarMetricsDefault]; }
// normal font NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:@"Helvetica" size:20], NSFontAttributeName, [UIColor whiteColor], NSForegroundColorAttributeName, nil]; // bold font NSDictionary *boldAttrs = [NSDictionary dictionaryWithObjectsAndKeys: [UIFont fontWithName:@"Helvetica-Bold" size:20], NSFontAttributeName, nil];
NSString *text = @"The quick brown fox jumps over the lazy dog";
NSRange range = NSMakeRange(4, 15); // bold the text "quick brown fox" // init with regular attributes NSMutableAttributedString *textAttr = [[NSMutableAttributedString alloc] initWithString:text attributes:attrs]; [textAttr setAttributes:boldAttrs range:range]; // set specific attributes for range of text [myLabel setAttributedText:textAttr];
- (void)viewDidLoad { ... // add to the tableView instead of tableViewCell UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(tableViewPressed:)]; [self.tableView addGestureRecognizer:longPress]; }
- (void)tableViewPressed:(UILongPressGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateBegan) { // only take action in this state CGPoint point = [sender locationInView:self.tableView]; // get the point (x, y) NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point]; // look for correct indexPath // in case you have section header CGFloat headerHeight = [self tableView:self.tableView heightForHeaderInSection:indexPath.section]; // first row should be at the offset y which between (height of header view) and rowHeight + header for header view if ((point.y < headerHeight || point.y > (self.tableView.rowHeight + headerHeight)) && indexPath.row == 0) return;
NSString *content = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; // Create the attributed string (text + attributes) NSMutableAttributedString *textAttrs = [[NSMutableAttributedString alloc] initWithString:content attributes:attrs];
// only apply for iOS 6 if ([[UIDevice currentDevice].systemVersion floatValue] < 7) { // go through the subview for (UIView *subview inself.searchBar.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) { // add a view filled with flat color to the background view UIView *flatView = [[UIView alloc] initWithFrame:subview.bounds]; flatView.backgroundColor = [UIColor greenColor]; [subview addSubview:flatView]; break; } } }
// set the initial position UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 320, 240, 100)]; ...
[UIView animateWithDuration:1.0// 1 second delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{ // move the image to top imageView.center = CGPointMake(imageView.center.x, 100); } completion:nil];
Fade in UIButton
1 2 3 4 5 6 7 8 9 10 11
UIButton *fooButton = [UIButton buttonWithType:UIButtonTypeCustom]; fooButton.frame = ...; fooButton.alpha = 0; // set to transparent first
[UIView animateWithDuration:0.5// 0.5 second delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{ fooButton.alpha = 1.0; // slowly fade in } completion:nil];
// when tapped on facebook button - (IBAction)facebookTouched:(UIButton *)sender { // We will request the user's public profile and the user's birthday // These are the permissions we need: NSArray *permissionsNeeded = @[@"publish_actions", @"email"]; // don't cache the token FBSession *mySession = [[FBSession alloc] initWithAppID:nil permissions:permissionsNeeded urlSchemeSuffix:nil tokenCacheStrategy:[FBSessionTokenCachingStrategy nullCacheInstance]]; [mySession openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Facebook Error" message:@"You must allow Facebook permissions" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
if (error) { // user not allow "email" [alert show]; } else { // i don't know what is this for, if without this line, this block will be executed 2 times and get error if (status == 258) return; [FBSession setActiveSession:session]; // Request the permissions the user currently has [FBRequestConnection startWithGraphPath:@"/me/permissions" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) { if (!error) { // These are the current permissions the user has: NSDictionary *currentPermissions = [(NSArray *)[result data] objectAtIndex:0]; // We will store here the missing permissions that we will have to request NSMutableArray *requestPermissions = [[NSMutableArray alloc] initWithArray:@[]]; // Check if all the permissions we need are present in the user's current permissions // If they are not present add them to the permissions to be requested for (NSString *permission in permissionsNeeded){ if (![currentPermissions objectForKey:permission]){ [requestPermissions addObject:permission]; } } // If we have more permissions to request if ([requestPermissions count] > 0) { // user haven't allow publish_actions [alert show]; } else { fbToken = session.accessTokenData.accessToken; } } else { // An error occurred, we need to handle the error // See: https://developers.facebook.com/docs/ios/errors NSLog(@"error %@", error.description); } }]; } }]; }
Get profile picture
1 2 3 4 5 6 7 8 9 10
// set image & user name [FBSession setActiveSession:self.session]; [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *FBuser, NSError *error) { if (error) { NSLog(@"error %@", error.description); } else { self.usernameLabel.text = [FBuser name]; [self.avatarImageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?height=100&type=normal&width=100", [FBuser username]]]]; } }];
... - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. [FBSDKAppEvents activateApp]; }