Cell specific Action like slide-in menu - iphone

I'm attempting to implement a slide-in menu like in the facebook app.
I have a NIB for a custom UITableViewCell, which includes a button.
The button has an IBAction associated with it, in which I animate in a subview of my NIB (the delete/edit menu).
My problem is that my animation only happens on one cell, and its not the cell where I pushed the button.
How would I call this animation to work on the cell where my button was tapped?
Here's my code so far. Any tips?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *PatientCellIdentifier = #"PatientCellIdentifier";
PatientListTableViewCell *cell = (PatientListTableViewCell *)[tableView dequeueReusableCellWithIdentifier:PatientCellIdentifier];
if (cell ==nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"PatientCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBG.png"]];
}
//NSUInteger row = [indexPath row];
//NSDictionary *rowData = [self.
[self configureCell:cell atIndexPath:indexPath];
return cell; }
-(IBAction)showMenu:(id)sender{
[self showMenuForCell:sender animated:YES];}
- (void)showMenuForCell:(UITableViewCell *)cell animated:(BOOL)animated {
//[super showMenu:view forCell:cell animated:animated];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
//Action here
[UIView commitAnimations];
}

Is this included in your code?
[self.contentView addSubview:SLIDINGVIEW];
We need to look at your animation block and the code that invokes your animation

I solved this problem Myself. I ended up using a custom Subclass of UITableViewCell outlined in 'Beginning iPhone Development' pp 205-208.
I put a button in the NIB for my cell, with one view for the normal view, and another for the menu. When the button was pushed. The main view slides out of the way.
All of these methods and buttons were included in the subClass.
Boom. done.

Related

How do I know which content view is touched?

I have two questions about content view.
1st question:
There are two content views in tableview cell. How do I know which one is touched?
2nd question:
I only want content view to appear in the first section of the tableview.
But, when I scroll up tableview, content view appears in the third section also.
How can I fix this problem?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIImageView *imgView, *imgView1;
if(cell == nil)
{
if (indexPath.section == 0) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = #"test";
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(100,0,20,62)];
[imgView setImage:[UIImage imageNamed:#"1.png"]];
imgView.tag = 10;
[cell.contentView addSubview:imgView];
[imgView release];
imgView1 = [[UIImageView alloc] initWithFrame:CGRectMake(200,0,20,62)];
[imgView1 setImage:[UIImage imageNamed:#"2.png"]];
imgView1.tag = 20;
[cell.contentView addSubview:imgView1];
[imgView1 release];
}
}
else
{
if (indexPath.section == 0) {
imgView = (id)[cell.contentView viewWithTag:10];
imgView1 = (id)[cell.contentView viewWithTag:20];
}
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// How do I know left content view is touched or right content view is touched?
}
1) You can add different recognizers to each view which will call different methods.
// create view
UIImageView *view = [UIImageView ...];
view.userInteractionEnabled = YES;
// create recognizer
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myViewTapped:)];
// add recognizer to your view
[view addGestureRecognizer:recognizer];
[recognizer release];
// now when user will tap on your view method - (IBAction)myViewTapped:(UIGestureRecognizer); will be called
2) As you are reusing cell, don't forget to nil or remove from content view unneedfull views (as they already been added in previous section and reused in third one).
UIView *view2remove = [cell viewWithTag:itsTag];
[view2remove removeFromSuperview];
The code you posted is missing a brace. You need an extra close brace before the else. Presumably your real code is not, or it would not compile.
In the else clause, assigning something to local variables won't do anything.
You also need to do something if indexPath.section != 0. If you do nothing, it is possible you will get the content of a cell that was built earlier. If you want the views not to appear, you would have to remove them. Something like:
for (UIView *subview in cell.contentView.subviews)
[subview removeFromSuperview];
But I think it will be easier if you just use a different cell identifier for section 1 and other sections. Then you will not get back cells that have been used for section 1 in section 3, and have to reconfigure them. Like:
NSString *CellIdentifier;
if (indexPath.section == 0)
CellIdentifier = #"Section1Cell";
else
CellIdentifier = #"OtherSectionCell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

how display view when cells select in a tableview

i am new to iphone ,my question is in one view i placed a tableview and display some data on that view,i want to add another view(same view to all cell) when select cell(suppose select first cell view will display and newly add view is used to delet that cell information based on cell index)please tell me how to display view.
In the didSelectRowAtIndexPath method in your TableView class; that is where you deal with the selected row. Here is some code that pushes a webViewController onto the screen :
webViewController = [[WebViewController alloc] init];
WebViewController *wvc = [[WebViewController alloc] init];
NSMutableArray *temp = [eventsDict objectForKey:[datesArray objectAtIndex:[indexPath section]]];
EventObject *tempEvent = [temp objectAtIndex:[indexPath row]];
NSString *eventURL = [tempEvent eventLink];
[wvc setEventWebsite:eventURL];
[self setWebViewController:wvc];
[[self navigationController] pushViewController:webViewController animated:YES];
[wvc release];
[webViewController release];
Basically I have an array of Events, it gets the event you touched using [indexPath row], gets the URL within that Event object, passes it to the webViewController, then it pushes the webViewController onto the screen loading the appropriate link. Hope this helps
If you want to display the same view for all cells - simply create one UIView object and change frame in didSelectRowAtIndexPath delegate method. It will something like this -
At first declare infoView in your .h file UIView *infoView, next steps:
- (void)viewDidLoad {
infoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
infoView.hidden = YES;
[tableView addSubview:infoView];
[super viewDidLoad]; }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGPoint st = CGPointMake(tableView.frame.size.width/2, cell.frame.size.height*indexPath.row);
infoView.hidden = NO;
infoView.center = st;}
Don't forget to release infoView in dealloc method

Horizontal UIScrollView inside a UITableViewCell

I'm trying to create the exact same effect as in the AppStore app for viewing screenshots: inside a UITableView, I have custom subclasses of UITableViewCell's. One of them is designed to show previews of some product, say 4 images. I want them to show the same way as the AppStore presents screenshots of an app : inside a horizontal UIScrollView with its attached UIPageControl.
So I add my UIScrollView and my UIPageControl to my UITableViewCell, just like that :
#implementation phVolumePreviewCell
- (id)init {
if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kVolumePreviewCellIdentifier]) {
[self setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
[self setSelectionStyle:UITableViewCellSeparatorStyleNone];
previews = [[NSMutableArray alloc] initWithCapacity:4];
for (int i = 0; i < 4; i++) {
[previews addObject:#"dummy"];
}
scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
[scrollView setPagingEnabled:YES];
[scrollView setBackgroundColor:[UIColor grayColor]];
[scrollView setIndicatorStyle:UIScrollViewIndicatorStyleBlack];
[scrollView setShowsHorizontalScrollIndicator:YES];
[scrollView setBounces:YES];
[scrollView setScrollEnabled:YES];
[scrollView setDelegate:self];
[self.contentView addSubview:scrollView];
[scrollView release];
pageControl = [[UIPageControl alloc] initWithFrame:CGRectZero];
[pageControl setNumberOfPages:[previews count]];
[pageControl setBackgroundColor:[UIColor grayColor]];
[self.contentView addSubview:pageControl];
[pageControl release];
}
return self;
}
(note: I'm populating "previews" with dummy data here, just in order to have a [previews count] that works ; I want to view the scrollView's scroll indicator for test purposes only, I'll hide them later on).
My problem is that I can scroll the whole UITableView containing this phVolumePreviewCell (subclass of UITableViewCell), but I can't scroll the UIScrollView. How can I achieve this?
The only information I found is there: http://theexciter.com/articles/touches-and-uiscrollview-inside-a-uitableview.html
But it talks of old SDKs (namely 2.2) and I'm sure there is a more "recent" approach to doing this.
Some precisions :
I can scroll the UIScrollView with two fingers. That's not what I want, I want it to be able to scroll with one finger only.
When I scroll with two fingers, the TableView still intercepts the touches and scroll a little bit to the top or the bottom. I'd like the TableView to stick at its position when I touch the ScrollView.
I believe I have to work out how to intercept touches on my TableView, and if the touch is on the phVolumePreviewCell (custom UITableViewCell subclass), pass it to the cell instead of handling it on the TableView.
For the record, my TableView is created programmatically in a UITableViewController subclass:
#interface phVolumeController : UITableViewController <UITableViewDelegate> {
LocalLibrary *lib;
NSString *volumeID;
LLVolume *volume;
}
- (id)initWithLibrary:(LocalLibrary *)newLib andVolumeID:(NSString *)newVolumeID;
#end
 
#implementation phVolumeController
#pragma mark -
#pragma mark Initialization
- (id)initWithLibrary:(LocalLibrary *)newLib andVolumeID:(NSString *)newVolumeID {
if (self = [super initWithStyle:UITableViewStylePlain]) {
lib = [newLib retain];
volumeID = newVolumeID;
volume = [(LLVolume *)[LLVolume alloc] initFromLibrary:lib forID:volumeID];
[[self navigationItem] setTitle:[volume title]];
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVolumePreviewCellIdentifier];
if (cell == nil) {
cell = [[[phVolumePreviewCell alloc] init] autorelease];
}
[(phVolumePreviewCell *)cell setVolume:volume];
return (UITableViewCell *)cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return kVolumePreviewCellHeight;
}
Thanks for any help!
I have found a workaround.
Recreating from scratch a very simple UITableView (8 rows), and inserting a UIScrollView in just the second row, works perfectly. Nested scroll views (the TableView and the ScrollView) scroll independently as expected. All that was done in a single-file test project, in the AppDelegate.
So... first I thought "this might be a delegation problem", so I told the scrollView that its delegate was the TableView, not my custom TableViewCell subclass. To no avail.
Then instead of resorting to a custom, clean TableViewCell subclass that just adds the ScrollView and the PageControl, I resorted to creating a plain TableViewCell in the TableView's cellForRowAtIndexPath: method. Then, I create a UIScrollView right after initializing the TableViewCell, then add it to the TableViewCell, and shazam... it works!
Before:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVolumePreviewCellIdentifier];
if (cell == nil) {
cell = [[[phVolumePreviewCell alloc] init] autorelease];
}
[(phVolumePreviewCell *)cell setVolume:volume];
// That does the job of creating the cell's scrollView and pageControl
return (UITableViewCell *)cell
After:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kvcPreviewRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kvcPreviewRowIdentifier] autorelease];
previewScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, kvcPreviewScrollViewHeight)];
[previewScrollView setContentSize:CGSizeMake(1000, kvcPreviewScrollViewHeight)];
[[cell contentView] addSubview:previewScrollView];
previewPageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, kvcPreviewScrollViewHeight, tableView.frame.size.width, kvcPreviewPageControlHeight)];
[previewPageControl setNumberOfPages:4];
[[cell contentView] addSubview:previewPageControl];
}
return (UITableViewCell *)cell;
How the heck comes that when I create my scrollView from the TVCell subclass, it doesn't play nice ; but when I create the scrollView from the TableView right after creating a "classical" TVCell, it works?
I might have found a solution, but I'm still puzzled by the reason.

iPhone question: How can I add a button to a tableview cell?

Little background, the table view is filled by a fetchedResultsController which fills the table view with Strings. Now I'm trying to add a button next to each String in each tableview cell. So far, I've been trying to create a button in my configureCell:atIndexPath method and then add that button as a subview to the table cell's content view, but for some reason the buttons do not show up. Below is the relevant code. If anyone wants more code posted, just ask and I'll put up whatever you want. Any help is greatly appreciated.
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
// get object that has the string that will be put in the table cell
Task *task = [fetchedResultsController objectAtIndexPath:indexPath];
//make button
UIButton *button = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
[button setTitle:#"Check" forState:UIControlStateNormal];
[button setTitle:#"Checked" forState:UIControlStateHighlighted];
//set the table cell text equal to the object's property
cell.textLabel.text = [task taskName];
//addbutton as a subview
[cell.contentView addSubview:button];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
Three comments:
You'll probably need to set the frame of your UIButton. Otherwise it doesn't know how big it's supposed to be and where it's supposed to be placed. It's possible that it comes with a default frame, but I haven't investigated that.
You're leaking your buttons. You don't need to retain after calling [UIButton buttonWithType:...];
You have the possibility of adding multiple buttons to the same cell. If you're reusing a cell, then you should first invoke removeFromSuperview each subview of cell.contentView .

How to get Transparent Accessory View in UITableViewCell? (w/ Screenshot)

I use a custom UITableViewCell from a nib. The accessory view is a Detail Disclosure Indicator . The problem is that the background color of the UITableViewCell behind the accessory view is not getting rendered (see image / source below). Any clues? Also, here are some things that I tried but did NOT work:
Things that DID NOT work:
- Setting the backgroundColor of the accessory view to clearColor
- Setting the contentView.opaque of the cell to FALSE
- Setting the contentView.opaque of the Table View to FALSE
- Setting a non-default accessory view for the cell
alt text http://www.chicknchoke.com/so/IMG_8028.png
-(void)showTablePrep
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 480, 320, 416) style:UITableViewStylePlain];
myTableView.dataSource = self;
myTableView.delegate = self;
myTableView.delaysContentTouches = FALSE;
myTableView.opaque = FALSE;
myTableView.rowHeight = 60;
[UIView beginAnimations:#"SlideUp" context:nil];
[UIView setAnimationDuration:0.3f];
[myTableView setCenter:CGPointMake(myTableView.center.x, myTableView.center.y-436)];
[self.view addSubview:myTableView];
[self.view bringSubviewToFront:myTableView];
[UIView commitAnimations];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FriendsCell* cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCellID"];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"FriendsCellView" owner:self options:nil];
cell = (FriendsCell*)[nib objectAtIndex:0];
if(indexPath.row % 2 == 0){
cell.contentView.backgroundColor = [UIColor grayColor];
}else{
cell.contentView.backgroundColor = [UIColor lightGrayColor];
}
cell.accessoryView.backgroundColor = [UIColor clearColor];
cell.contentView.opaque = FALSE;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if(f
riendsCounter > indexPath.row){
cell.titleLabel.text = #"Label";
cell.descLabel.text = #"Description goes here";
}else{
cell.titleLabel.text = #"";
cell.descLabel.text = #"";
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
return cell;
}
You're drawing the background color for your cell incorrectly. A UITableViewCell will be arranged so that the contentView and accessoryView sit side-by-side. (This is done so that the contentView can clip its content so it doesn't overlap with the accessory view) The problem is not that the accessory view is opaque, it's that the gray background is simply not drawn behind the accessory view.
The correct way of customizing the background drawn behind a UITableViewCell is to customize its backgroundView. I haven't tried this, but since you're only changing the color, you might be able to simply set the backgroundColor color on the backgroundView to your desired color.
I found the answer by having a look at the subviews of my custom table view cell.
It seems like the accessory view has a button sitting over it. By finding this button in the subviews and changing its color, i was able to update the background color behind the accessory button.
<UIButton: 0x3b4d690; frame = (277 0; 43 75); opaque = NO; layer = <CALayer: 0x3b3e0b0>>
for (UIView *aSubView in self.subviews) {
if ([aSubView isMemberOfClass:[UIButton class]]) {
aSubView.backgroundColor = [UIColor greenColor];
}
}
Unfortunately I was only able to reach this button within the
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
method of my custom table view cell class. I've used this successfully within my app to display a different highlight color when the user selects a cell. This should point you in the right direction.
I resolve this problem on iOS7 but adding
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
in
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and you modify your background and other bakcgrounds here :
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// Add your Colour.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithHexColor:HIGHLIGHT_COLOR]];
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// Reset Colour.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor colorWithHexColor:UNHIGHLIGHT_COLOR]];
}