- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
... dance right here ...
[tableView reloadData];
}
Showing posts with label Objective-C. Show all posts
Showing posts with label Objective-C. Show all posts
iOS: Deselecting UITableViewCell with AutoLayout
on
Thursday, February 12, 2015
Keywords:
AutoLayout
,
Fix
,
iOS
,
Objective-C
,
UITableView
0
comments
You'll notice that when deselecting a customized UITableViewCell using tableView-deselectRowAtIndexPath:animated: method inside tableView-didSelectRowAtIndexPath: method is that its contentView gets misplaced. It's probably halfway up the cell. I really think there's a bug on this area for Apple to adress. In the meantime, to work around this bug, you only need to replace the tableView-deselectRowAtIndexPath:animated: method call with tableView-reloadData. Yes it is. And for as long you don't have such a complicated tableView and cell structure, worry not about the performance.
UICollectionView: Paging for Smaller Width Cells
on
Tuesday, February 25, 2014
Keywords:
Codes
,
iOS
,
Objective-C
2
comments
In the application I'm working on, there's a 320pt wide horizontal-only scrolling UICollectionView with varied content width depending on the number of items. The UICollectionViewCell subclass or itemView being used here has a width of 250pt enough to let the next itemView peak just a little bit. And I need to show one itemView at a time by snapping to the closest one.
// NOTE: This delegate method requires you to disable UICollectionView's `pagingEnabled` property.
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset {
CGPoint point = *targetContentOffset;
UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
// This assumes that the values of `layout.sectionInset.left` and
// `layout.sectionInset.right` are the same with `layout.minimumInteritemSpacing`.
// Remember that we're trying to snap to one item at a time. So one
// visible item comprises of its width plus the left margin.
CGFloat visibleWidth = layout.minimumInteritemSpacing + layout.itemSize.width;
// It's either we go forwards or backwards.
int indexOfItemToSnap = round(point.x / visibleWidth);
// The only exemption is the last item.
if (indexOfItemToSnap + 1 == [self.collectionView numberOfItemsInSection:0]) { // last item
*targetContentOffset = CGPointMake(self.collectionView.contentSize.width -
self.collectionView.bounds.size.width, 0);
} else {
*targetContentOffset = CGPointMake(indexOfItemToSnap * visibleWidth, 0);
}
}
iOS: Stopping a chain of Block-based animations
on
Sunday, February 10, 2013
Keywords:
Codes
,
iOS
,
Objective-C
0
comments
This can easily be done using one line of code and given you're using either [UIView animateWithDuration:animations:] or [UIView animateWithDuration:animations:completion], or both of them interchangeably.
But what if another variant of these methods is also in the mix? This method is [UIVIew animateWithDuration:delay:options:animations:completion].
What happens is that, whatever is in the completion block of this method, it still is executed right after calling [CALayer removeAllAnimations]. So the right thing to do here is always check for the value of the Boolean argument, finished. If it evaluates to True, then let the rest of the code continue. Otherwise, stop. Also, make sure to include UIViewAnimationOptionAllowUserInteraction in the options parameter.
[someView.layer removeAllAnimations]
But what if another variant of these methods is also in the mix? This method is [UIVIew animateWithDuration:delay:options:animations:completion].
What happens is that, whatever is in the completion block of this method, it still is executed right after calling [CALayer removeAllAnimations]. So the right thing to do here is always check for the value of the Boolean argument, finished. If it evaluates to True, then let the rest of the code continue. Otherwise, stop. Also, make sure to include UIViewAnimationOptionAllowUserInteraction in the options parameter.
iOS: Unrecognized selector sent to class...
Keywords:
iOS
,
Objective-C
,
Xcode
0
comments
There are several reasons why this could happen. One of this is when adding a static Objective-C Library into your project. While compiling the app may seem to work fine, the actual code using the library may encounter this exception. The simple solution to this is to add a linker flag -all_load to your project's Targets->YourProject->Build Settings->Linking->Other Linker Flags.
Read Apple's technical note about this issue here.
IMPORTANT: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -all_load or -force_load flags. -all_load forces the linker to load all object files from every archive it sees, even those without Objective-C code. -force_load is available in Xcode 3.2 and later. It allows finer grain control of archive loading. Each -force_load option must be followed by a path to an archive, and every object file in that archive will be loaded.
Effectively render a Drop Shadow on a UIView subclass
on
Friday, May 11, 2012
Keywords:
Codes
,
iOS
,
Notes
,
Objective-C
0
comments
Adding a drop shadow to your UIView subclass is as easy as the following code.
While the common use case of such trick is on rendering stationary views, and no doubt it works perfectly that way, placing them inside a scrollable view like UISrollView or UITableView yields a different feel - it lags a bit when scrolling. So the way to solve this issue and keep them scrolling smoothly is to make use of UIBezierPath. You create an instance of this based on the `bounds` of the receiving view. Then set it as the `shadowPath` of the view's layer object.
Now let's modify our base code to include the bezier path.
UIView *customView = [[UIView alloc] init]; ... customView.layer.shadowColor = [[UIColor lightGrayColor] CGColor]; customView.layer.shadowOffset = CGSizeMake(1, 1); customView.layer.shadowOpacity = 1.0; customView.layer.shadowRadius = 2.0; ...
While the common use case of such trick is on rendering stationary views, and no doubt it works perfectly that way, placing them inside a scrollable view like UISrollView or UITableView yields a different feel - it lags a bit when scrolling. So the way to solve this issue and keep them scrolling smoothly is to make use of UIBezierPath. You create an instance of this based on the `bounds` of the receiving view. Then set it as the `shadowPath` of the view's layer object.
UIBezierPath *path = [UIBezierPath bezierPathWithRect:customView.bounds]; customView.layer.shadowPath = [path CGPath];
Now let's modify our base code to include the bezier path.
UIView *customView = [[UIView alloc] init]; ... UIBezierPath *path = [UIBezierPath bezierPathWithRect:customView.bounds]; customView.layer.shadowPath = [path CGPath]; customView.layer.shadowColor = [[UIColor lightGrayColor] CGColor]; customView.layer.shadowOffset = CGSizeMake(1, 1); customView.layer.shadowOpacity = 1.0; customView.layer.shadowRadius = 2.0; ...
Facebook iOS: Use Access Token in PHP
on
Friday, September 30, 2011
Keywords:
Facebook
,
iOS
,
Objective-C
,
php
,
SDK
5
comments
Yes that's right. As of the time of this writing, it is possible to use the user granted access_token back in some server side scripting language like PHP. If you currently have a 255 varchar field size for access_tokens in your database, you may want to bump that up a bit.
The time I made the sample code ran and allowed me to log in (one that came bundled with the Facebook iOS SDK from GitHub), I began realizing that the token quite have different format than the one we usually see in web-based apps (e.g. FB iFrame app).
The usual token looks something like this:
..while in mobile:
The plan was, allow users to connect to our application using FB. Then once he approved it, we take a copy of the access_token and save it back to the server. Same access_token will be used once he logs in to his account using our web-based app.
Well, so far so good. Let me know if yours doesn't work.
Related posts:
The time I made the sample code ran and allowed me to log in (one that came bundled with the Facebook iOS SDK from GitHub), I began realizing that the token quite have different format than the one we usually see in web-based apps (e.g. FB iFrame app).
The usual token looks something like this:
213455681425|1.BGgrgnfWrdpG_X18.3600.1213252135.2-1334679|dHcDbxGbeYbLg3SRgw12fdf4gd60
..while in mobile:
v9ylvkttPnuFWUX4KVdjDPB0SRXkuKX7z281rqjHuG0.eyJpdiI6ImEwWXBDaEtncWpDTU5ibUNuQWdROWcifQ.Y-DwxRY2ZAFZiP7EVuR-HksXqmGw9LXP6umGrfz2XnjSLm0a508u7_jXq0_Kz5a2S8AUUulzUvIRVxTS51_i6VfSByOCbFBIKoBe0-n-Pa8NC29wbuVmGJLvq4W-ezhv0DzA3diiCIqCybt9ELDXoA
The plan was, allow users to connect to our application using FB. Then once he approved it, we take a copy of the access_token and save it back to the server. Same access_token will be used once he logs in to his account using our web-based app.
Well, so far so good. Let me know if yours doesn't work.
Related posts:
Facebook iOS SDK: Let users Connect & Login with FB
on
Thursday, September 29, 2011
Keywords:
Facebook
,
iOS
,
Objective-C
,
SDK
2
comments
Here's how to let your users connect and login to your iOS app using Facebook. The first thing you got to do is download the Facebook iOS SDK. If you have Git installed, you can also do this by pulling from GitHub.
git clone git://github.com/facebook/facebook-ios-sdk.git
Objective-C: Retain, Release, Autorelease
on
Tuesday, May 03, 2011
Keywords:
iOS
,
Notes
,
Objective-C
0
comments
The rules for -retain, -release, and -autorelease are simple. If you alloc, copy, or retain something, you also need to (eventually) release or autorelease it. If you don't do any of those three things, you don't need to do any memory management at all. Not only don't need to, if you try, it messes things up.
If you alloc something, it's just like you sent -retain to the object. So you release or autorelease it. If you do a copy or a mutableCopy, it's also the same as sending a retain. So you also release or autorelease it.
If you never sent a retain (or equivalent) method to an object, then by default it is autoreleased and will go away on its own. The following example doesn't need to be released explicitly since it has already been given an -autorelease message internally. (see NSArray Class Reference -> arrayWithObjects:)
Also, in my code I always try to release an object instead of autoreleasing it as much as possible.
The actual mechanism here is that when you call -autorelease, a pointer to the object is added to a list kept by an NSAutoreleasePool. When that pool is deallocated, every object in the list gets a -release method. Thus -autorelease is a delayed -release.
If you alloc something, it's just like you sent -retain to the object. So you release or autorelease it. If you do a copy or a mutableCopy, it's also the same as sending a retain. So you also release or autorelease it.
If you never sent a retain (or equivalent) method to an object, then by default it is autoreleased and will go away on its own. The following example doesn't need to be released explicitly since it has already been given an -autorelease message internally. (see NSArray Class Reference -> arrayWithObjects:)
NSArray * sampleList = [NSArray arrayWithObjects:@"One", @"Two", nil];
Also, in my code I always try to release an object instead of autoreleasing it as much as possible.
The actual mechanism here is that when you call -autorelease, a pointer to the object is added to a list kept by an NSAutoreleasePool. When that pool is deallocated, every object in the list gets a -release method. Thus -autorelease is a delayed -release.
Subclassing UIView with NIB file
Keywords:
Codes
,
iOS
,
Objective-C
,
UIView
0
comments
Here's how UIView subclassing is done (with NIB files). I felt the need of doing so for two reasons: reusability and maintainability.
Header class:
Implementation class:
Using the the new class is as simple as this:
Related posts:
Header class:
#import <UIKit/UIKit.h>
@interface MyCustomView: UIView
+ (MyCustomView *)createWithOwner:(id)owner;
@end
@interface MyCustomView: UIView
+ (MyCustomView *)createWithOwner:(id)owner;
@end
Implementation class:
#import "MyCustomView.h"
@implementation MyCustomView
+ (MyCustomView *)createWithOwner:(id)owner {
NSString *nibName = NSStringFromClass([self class]);
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName owner:owner options:nil];
MyCustomView *view = [nib objectAtIndex:0];
return view;
}
@end
@implementation MyCustomView
+ (MyCustomView *)createWithOwner:(id)owner {
NSString *nibName = NSStringFromClass([self class]);
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName owner:owner options:nil];
MyCustomView *view = [nib objectAtIndex:0];
return view;
}
@end
Using the the new class is as simple as this:
#import "MyCustomView.h" ... MyCustomView * customView = [MyCustomView createWithOwner:self]; [self.view addSubView: customView]; [customView release]; ...
Related posts:
Determine if UITableView is near bottom when scrolling
on
Tuesday, April 19, 2011
Keywords:
Codes
,
iOS
,
Objective-C
,
UITableViewController
1
comments
Here's my way of finding out if UITableView is near bottom when scrolling. And when it does, we fetch and load another batch of items.