I have the following code that encloses a UITableView within a UITableCell, so basically it's a table within a table. This works fine in iOS6 and below, but in iOS7 I can't scroll the secondary view or press into it.
Basically it shows fine as per the code below, but all touches are sent to the main table, not to the table inside the cell.
Previously it would allow both to scroll.
Here is the code that loads the second table. tableViewCellWithTableView class is just a tablecell class and contains the didselectrowatindex path etc for the second table.
[[NSBundle mainBundle] loadNibNamed:#"TableViewCell" owner:self options:nil];
tableViewCellWithTableView.data = myData;
tableViewCellWithTableView.backgroundColor = [UIColor clearColor];
[tableViewCellWithTableView setBackgroundView: nil];
tableViewCellWithTableView.tableViewInsideCell.allowsSelection = YES;
tableViewCellWithTableView.tableViewInsideCell.separatorStyle = UITableViewCellSeparatorStyleNone;
tableViewCellWithTableView.tableViewInsideCell.separatorColor=[UIColor clearColor];
[cell.contentView addSubview:tableViewCellWithTableView];
[cell setNeedsDisplay];
Related
I am trying to set a UIView (loaded from a xib file) as the background of a tableview. But when running the app on a device it is just showing a black screen and there are no errors. This is how i do it,
zoneListEmptyView = [[[NSBundle mainBundle] loadNibNamed:#"TableViewEmptyState" owner:self options:nil] lastObject];
zoneListEmptyView.bounds = self.view.bounds;
And in numberOfSectionsInTableView: i check if data to be displayed is empty and if yes, i do,
[self.tableView setBackgroundView:zoneListEmptyView];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
I checked other similar questions in stack overflow and tried to recreate the xib and class files, but no help. I am displaying tableview empty states in another application using the same approach and it works fine,but not here. Please help
I've created an empty view .xib file to be displayed when the application is unable to download certain data from the internet.
The problem I'm facing is that when I set the empty view as my tableView's backgroundView, the empty view does not fit precisely into the screen.
I'm not sure why this is happening.
-(void) updateUI
{
if ([self.categories count]) {
self.tableView.backgroundView = nil;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
}else{
NSArray* nibs = [[NSBundle mainBundle] loadNibNamed:#"EmptyView" owner:self options:nil];
UIView* emptyView = [nibs objectAtIndex:0];
[emptyView sizeToFit];
self.tableView.backgroundView = emptyView;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
}
I tried [emptyView sizeToFit] which didn't work. I also tried setting the frame of the empty view but I had no luck with that either. I'm fairly new to iOS development so I might have missed something really basic.
Clarification:
I did set Autolayout constraints on both labels in the Empty View:
The 'No categories available' is set to be in the centre of the view.
The instructions are set to appear a standard distance below.
You can use Auto Layout to set some constrains to the view, make sure that will fill the whole screen.
This tutorial of Auto Layout may help.
http://www.appcoda.com/introduction-auto-layout
I am trying to create a label in each of my customCells. In cellForRowIndexPath, I have:
EDIT:
static NSString *checkInTableIdendifier = #"ChatCell";
cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:checkInTableIdendifier];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ChatTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSAttributedString *title;
title = [[NSAttributedString alloc] initWithString:[self.savedMsgs objectAtIndex:indexPath.row] attributes:#{ NSFontAttributeName : [UIFont fontWithName:#"Noteworthy-Bold" size:12], NSUnderlineStyleAttributeName : #1 , NSStrokeColorAttributeName : [UIColor blackColor]}]; //1
UILabel *label;
label = [[UILabel alloc] initWithFrame:CGRectMake( (self.view.bounds.size.width - title.size.width) / 2.0f, 40.0f, title.size.width, title.size.height)]; //2
label.attributedText = title; //3
[cell addSubview:label]; //4
The label will all end up in the same point overlapping each other because of line 2. How can I represent the origin of the label generated according to each respective cell?
The method you are using to generate cells, 'dequeueReusableCellWithIdentifier' can return a cell that has already been used before. When you add your labels etc after getting the cell, you are adding labels on top of labels that are already there.
The easiest way to handle cell reuse is to create a UITableViewCell subclass and an associated xib. After this ViewController is created and the tableView is accessible (viewDidLoad, usually) register the nib for the cell to the tableView. Then when you dequeue the cell, you need only to set the text values on the labels that are already there.
An aside, UITableView had a newer better method for dequeuing cells that takes an index path and always returns a cell so you don't need to nil check it. I would switch to that if you don't need to support iOS 6.
You should use the cell's bounds, not self.view's to position the label. Be careful as the frame might change after the cell has been created, so it's recommended to use auto layout to ensure the label is always positioned when you want it to be in respect to the cell.
Also, remember that the cell get reused in which case you might end up adding the label multiple times.
To mitigate both issues, subclass the cell and design it in the accompanying xib.
I am trying to use the CollapseClick table control. This all works, but I can't seem to add a button event to the view that is shown when the table cell is expanded.
Looking through the code, it is UITableView, which created UITableViewCells and adds UIViews dynamically. I think the UIView is added here:
+ (CollapseClickCell *)newCollapseClickCellWithTitle:(NSString *)title index:(int)index content:(UIView *)content {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"CollapseClickCell" owner:nil options:nil];
CollapseClickCell *cell = [[CollapseClickCell alloc] initWithFrame:CGRectMake(0, 0, 320, kCCHeaderHeight)];
cell = [views objectAtIndex:0];
// Initialization Here
cell.TitleLabel.text = title;
cell.index = index;
cell.TitleButton.tag = index;
cell.ContentView.frame = CGRectMake(cell.ContentView.frame.origin.x, cell.ContentView.frame.origin.y, cell.ContentView.frame.size.width, content.frame.size.height);
[cell.ContentView addSubview:content];
return cell;
}
The button displays, but if I try and hook up any events I cannot capture them.
It's probably quite simple. I have put the app here: http://www.havoc-media.com/TravelApp.zip
Upon looking at your code, you have a few overlooks, when it comes to using views.
The most important thing to know about views are that in order to have click events register on subviews the parent view cannot be smaller. The silly thing here is that even though you can visually see a view you inject into your ContentView, the Content view's width is set to zero, which means that all the views inside the ContentView may show, but will not respond to click events and the click events will default to the parentview of the ContentView, thus making your buttons unusable and unresponsive.
To address this in your openCollapseClickCellAtIndex you need to add the code:
cell.ContentView.frame = CGRectMake(cell.ContentView.frame.origin.x, cell.ContentView.frame.origin.y, 320, cell.ContentView.frame.size.height);
Your second issue is your CollapseClickCell xib you created is not communicating back to the view controller. Which means the view you created in the view controller and injected in the CollapseClickCell xib of which you want to report back to the view controller....isn't.
There is a way to address this but in my opinion I would create another custom xib-A to inject into your CollapseClickCell, and have the xib-A handle your button click events instead of test1View. Create a xib called "testView" linked to a test class and put this code in
-(UIView *)viewForCollapseClickContentViewAtIndex:(int)index
{
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"testView" owner:nil options:nil];
UIView *content = [views objectAtIndex:0];
switch (index) {
case 0:
return content; /*test1View;*/
break;
Once these two issues are addressed, your code will work. I can include the additions I made to your code to make it work if you would like to see it?
First of all, this code is not correct:
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"CollapseClickCell" owner:nil options:nil];
CollapseClickCell *cell = [[CollapseClickCell alloc] initWithFrame:CGRectMake(0, 0, 320, kCCHeaderHeight)];
cell = [views objectAtIndex:0];
You are first creating a cell via [collapseClickCell alloc]. But after that you assign the first object of the array created with loadNibNamed:owner:options:nil to the same variable. You either load the cell from the nib or you create it programatically. Simply put, you should just use:
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"CollapseClickCell" owner:nil options:nil];
CollapseClickCell *cell = [views objectAtIndex:0];
Be aware that the rect you were providing to the initWithFrame: method was not being used at all
Adding buttons to a cell is not the most appropriate thing (the whole cell should be the button). But if you absolutely need to, try assigning a uibutton as the accessory view of the cell. Take a look at http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableViewCell/accessoryView
Something similar to:
UITableViewCell *cell = (obtain your cell)
UIButton *button= [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(x,y,width,height);
cell.accessoryView = button;
I've created a custom UITableViewCell class, and used the layoutSubviews method to add a custom label. Like this:
- (void)layoutSubviews
{
[super layoutSubviews];
if (statusLabel == nil)
{
statusLabel = [[UILabel alloc]initWithFrame:CGRectMake(430.0, 10.0, 100.0, 20.0)];
[statusLabel setTextAlignment:UITextAlignmentRight];
[statusLabel setText:#"Status, set in code"];
statusLabel.tag = 1;
[self.contentView addSubview:statusLabel];
}
}
As you can see, I have set the initial text of the label to "Status, set in code".
In the table view controller I set the text for this custom label in the cellForRowAtIndexPath method, like so:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int index = [indexPath row];
NSString *introducerString =[introducers objectAtIndex:index];
NSArray *parts = [introducerString componentsSeparatedByString:#","];
static NSString *MyIdentifier = #"Requester";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[DanceCardCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:MyIdentifier] autorelease];
}
UIImage *image = [UIImage imageNamed:#"1.jpg"];
[cell.imageView setImage:image];
cell.textLabel.text = [parts objectAtIndex:1];
cell.detailTextLabel.text = #"Some text";
UILabel *statusLabel = (UILabel *)[cell viewWithTag:1];
statusLabel.text = #"Did it!";
return cell;
}
I'm using one table view to display two lists, depending on which of two buttons is pressed. When a button is pressed the appropriate table view controller is attached to the table view, and the reloadData method is called to trigger display of the new data. The new data does display, but the custom label text, which should read "Did it!" reads "Status, set in code ...", until I switch lists again twice.
How can I get the new text for the custom label to update straight away? I have checked the official documentation and cannot find any reference to refreshing a cell's display after updating its custom content.
Here is a screen shot to demonstrate what happens: http://www.dsbsystems.co.uk/images/xcode1.png
You're initializing the cell and immediately attempting to find the statusLabel with tag 1 inside it. layoutSubviews hasn't had the opportunity to be called yet, and so the label hasn't been created and added. (I suggest overriding the designated initializer method on your table view cell and creating the label there.)
Because of this, when you try to pull out statusLabel, it becomes nil because there's no such view, and messaging (calling a method on) nil simply does nothing (actually, it returns nil). You will need to watch out for this going forward if you're used to things blowing up with e.g. null reference exceptions.
When the cell is requested again, a new cell isn't needed because it's available from the reuse queue, and the label will be found correctly.